blob: 5e517c4b1b25d8617c6c9c1203ae7548c978aa4a [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
Robert Cragie3d23b1d2015-12-15 07:38:11 +000041/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070042 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000043 *
Brian Murray72b69e32016-09-13 14:21:01 -070044 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000045 *
Simon Butcher327398a2016-10-05 14:09:11 +010046 * If MSB(p) = 0, then p = (p << 1)
47 * If MSB(p) = 1, then p = (p << 1) ^ R_n
48 * with R_64 = 0x1B and R_128 = 0x87
49 *
50 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080051 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000052 */
Gilles Peskine449bd832023-01-11 14:50:10 +010053static int cmac_multiply_by_u(unsigned char *output,
54 const unsigned char *input,
55 size_t blocksize)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000056{
Brian Murrayb0c3c432016-05-18 14:29:51 -070057 const unsigned char R_128 = 0x87;
Dave Rodgman64172bc2024-01-29 12:29:14 +000058 unsigned char R_n;
Dave Rodgman7f86d352024-03-05 15:35:59 +000059 uint32_t overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010060 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070061
Gilles Peskine449bd832023-01-11 14:50:10 +010062 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070063 R_n = R_128;
Dave Rodgman5ba2b2b2024-03-06 11:38:49 +000064 }
65#if defined(MBEDTLS_DES_C)
66 else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
67 const unsigned char R_64 = 0x1B;
Brian Murrayb0c3c432016-05-18 14:29:51 -070068 R_n = R_64;
Dave Rodgman5ba2b2b2024-03-06 11:38:49 +000069 }
70#endif
71 else {
Gilles Peskine449bd832023-01-11 14:50:10 +010072 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070073 }
74
Dave Rodgman7f86d352024-03-05 15:35:59 +000075 for (i = (int) blocksize - 4; i >= 0; i -= 4) {
76 uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
77 uint32_t new_overflow = i32 >> 31;
78 i32 = (i32 << 1) | overflow;
79 MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
80 overflow = new_overflow;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000081 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000082
Dave Rodgman64172bc2024-01-29 12:29:14 +000083 R_n = (unsigned char) mbedtls_ct_uint_if_else_0(mbedtls_ct_bool(input[0] >> 7), R_n);
84 output[blocksize - 1] ^= R_n;
Simon Butcher327398a2016-10-05 14:09:11 +010085
Gilles Peskine449bd832023-01-11 14:50:10 +010086 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000087}
88
89/*
90 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +010091 *
92 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +000093 */
Gilles Peskine449bd832023-01-11 14:50:10 +010094static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
95 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000096{
Janos Follath24eed8d2019-11-22 13:21:35 +000097 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9e930e22023-06-14 17:52:54 +020098 unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murrayb0c3c432016-05-18 14:29:51 -070099 size_t olen, block_size;
100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700102
Dave Rodgman85a88132023-06-24 11:41:50 +0100103 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100104
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000105 /* Calculate Ek(0) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700107 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000109
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000110 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000111 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000112 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700114 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100118 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 }
Simon Butcher327398a2016-10-05 14:09:11 +0100120
121exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000125}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000126
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000127/*
128 * Create padded last block from (partial) last block.
129 *
130 * We can't use the padding option from the cipher layer, as it only works for
131 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
132 */
Gilles Peskine9e930e22023-06-14 17:52:54 +0200133static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 size_t padded_block_len,
135 const unsigned char *last_block,
136 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000137{
138 size_t j;
139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 for (j = 0; j < padded_block_len; j++) {
141 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000142 padded_block[j] = last_block[j];
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000144 padded_block[j] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000146 padded_block[j] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000148 }
149}
150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
152 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000153{
Simon Butcher327398a2016-10-05 14:09:11 +0100154 mbedtls_cipher_type_t type;
155 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100156 int retval;
157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
159 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
160 }
Simon Butcher327398a2016-10-05 14:09:11 +0100161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
163 MBEDTLS_ENCRYPT)) != 0) {
164 return retval;
165 }
Simon Butcher327398a2016-10-05 14:09:11 +0100166
Dave Rodgman2e8f6aa2023-06-24 17:32:18 +0100167 type = mbedtls_cipher_info_get_type(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100170 case MBEDTLS_CIPHER_AES_128_ECB:
171 case MBEDTLS_CIPHER_AES_192_ECB:
172 case MBEDTLS_CIPHER_AES_256_ECB:
173 case MBEDTLS_CIPHER_DES_EDE3_ECB:
174 break;
175 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100177 }
178
179 /* Allocated and initialise in the cipher context memory for the CMAC
180 * context */
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
182 if (cmac_ctx == NULL) {
183 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
184 }
Simon Butcher327398a2016-10-05 14:09:11 +0100185
186 ctx->cmac_ctx = cmac_ctx;
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100189
190 return 0;
191}
192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
194 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100195{
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700197 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000198 int ret = 0;
199 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
202 ctx->cmac_ctx == NULL) {
203 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
204 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700205
Simon Butcher327398a2016-10-05 14:09:11 +0100206 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100207 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100208 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000209
Dave Rodgman4faa34d2024-03-12 16:34:43 +0000210 /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
211 * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
212 MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE);
213
Simon Butcher6b0774a2016-10-10 21:37:42 +0100214 /* Is there data still to process from the last call, that's greater in
215 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 if (cmac_ctx->unprocessed_len > 0 &&
217 ilen > block_size - cmac_ctx->unprocessed_len) {
218 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
219 input,
220 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100221
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100222 mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
225 &olen)) != 0) {
226 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100227 }
228
Simon Butcher6b0774a2016-10-10 21:37:42 +0100229 input += block_size - cmac_ctx->unprocessed_len;
230 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100231 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700232 }
233
Simon Butcher327398a2016-10-05 14:09:11 +0100234 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100236
Simon B3249cb72016-11-03 01:11:37 +0000237 /* Iterate across the input data in block sized chunks, excluding any
238 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 for (j = 1; j < n; j++) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100240 mbedtls_xor_no_simd(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
243 &olen)) != 0) {
244 goto exit;
245 }
Simon Butcher327398a2016-10-05 14:09:11 +0100246
247 ilen -= block_size;
248 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700249 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000250
Simon Butcher327398a2016-10-05 14:09:11 +0100251 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 if (ilen > 0) {
253 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
254 input,
255 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100256 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100257 }
258
259exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100261}
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
264 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100265{
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100267 unsigned char *state, *last_block;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200268 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
269 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
270 unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Janos Follath24eed8d2019-11-22 13:21:35 +0000271 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100272 size_t olen, block_size;
273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
275 output == NULL) {
276 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
277 }
Simon Butcher327398a2016-10-05 14:09:11 +0100278
279 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100280 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Dave Rodgman4faa34d2024-03-12 16:34:43 +0000281 MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning
Simon Butcher327398a2016-10-05 14:09:11 +0100282 state = cmac_ctx->state;
283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 mbedtls_platform_zeroize(K1, sizeof(K1));
285 mbedtls_platform_zeroize(K2, sizeof(K2));
286 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100287
Simon Butcher69283e52016-10-06 12:49:58 +0100288 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000289
290 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if (cmac_ctx->unprocessed_len < block_size) {
292 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
293 mbedtls_xor(M_last, M_last, K2, block_size);
294 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000295 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000297 }
298
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 mbedtls_xor(state, M_last, state, block_size);
301 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
302 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100303 goto exit;
304 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100307
308exit:
309 /* Wipe the generated keys on the stack, and any other transients to avoid
310 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 mbedtls_platform_zeroize(K1, sizeof(K1));
312 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100313
314 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
316 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100317
Gilles Peskine9e930e22023-06-14 17:52:54 +0200318 mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000320}
321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000323{
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
327 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
328 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700329
Simon Butcher327398a2016-10-05 14:09:11 +0100330 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000331
Simon Butcher327398a2016-10-05 14:09:11 +0100332 /* Reset the internal state */
333 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
335 sizeof(cmac_ctx->unprocessed_block));
336 mbedtls_platform_zeroize(cmac_ctx->state,
337 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000340}
341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
343 const unsigned char *key, size_t keylen,
344 const unsigned char *input, size_t ilen,
345 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100346{
347 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000348 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
351 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
352 }
Simon Butcher327398a2016-10-05 14:09:11 +0100353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100357 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 }
Simon Butcher327398a2016-10-05 14:09:11 +0100359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
361 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100362 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 }
Simon Butcher327398a2016-10-05 14:09:11 +0100364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
366 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100367 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 }
Simon Butcher327398a2016-10-05 14:09:11 +0100369
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100371
372exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100376}
Simon Butcher327398a2016-10-05 14:09:11 +0100377
Simon Butcher69283e52016-10-06 12:49:58 +0100378#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000379/*
Simon Butcher69283e52016-10-06 12:49:58 +0100380 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000381 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
383 const unsigned char *input, size_t in_len,
384 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000385{
Janos Follath24eed8d2019-11-22 13:21:35 +0000386 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100387 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100388 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
389 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 if (key == NULL || input == NULL || output == NULL) {
392 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
393 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
396 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100397 /* Failing at this point must be due to a build issue */
398 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
399 goto exit;
400 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000403 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
405 } else {
406 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
409 key_length, int_key);
410 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700411 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000413 }
414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
416 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000417
Simon Butcher327398a2016-10-05 14:09:11 +0100418exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000422}
Brian Murrayb439d452016-05-19 16:02:42 -0700423#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000424
Simon Butcher69283e52016-10-06 12:49:58 +0100425#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000426/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000427 * CMAC test data for SP800-38B
428 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
429 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700430 *
431 * AES-CMAC-PRF-128 test data from RFC 4615
432 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000433 */
434
Brian Murray0f6af732016-05-19 15:59:23 -0700435#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000436#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100437
Brian Murray0f6af732016-05-19 15:59:23 -0700438#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
439/* All CMAC test inputs are truncated from the same 64 byte buffer. */
440static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000441 /* PT */
442 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
443 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
444 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
445 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
446 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
447 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
448 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
449 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000450};
Simon Butcher69283e52016-10-06 12:49:58 +0100451#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700452
Simon Butcher69283e52016-10-06 12:49:58 +0100453#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700454/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700455static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000456 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700457 0,
458 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000459 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700460 64
461};
462
Janos Follathcd13bd22016-12-13 11:51:04 +0000463/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700464static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000465 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
466 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700467};
Simon Butcher69283e52016-10-06 12:49:58 +0100468static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700469 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000470 /* K1 */
471 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
472 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700473 },
474 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000475 /* K2 */
476 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
477 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700478 }
479};
Gilles Peskine449bd832023-01-11 14:50:10 +0100480static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
481{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000482 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000483 /* Example #1 */
484 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
485 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000486 },
487 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000488 /* Example #2 */
489 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
490 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000491 },
492 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000493 /* Example #3 */
494 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
495 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000496 },
497 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000498 /* Example #4 */
499 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
500 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501 }
502};
503
Janos Follathcd13bd22016-12-13 11:51:04 +0000504/* CMAC-AES192 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800505#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700506static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000507 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
508 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
509 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000510};
Simon Butcher69283e52016-10-06 12:49:58 +0100511static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700512 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000513 /* K1 */
514 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
515 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700516 },
517 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000518 /* K2 */
519 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
520 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700521 }
522};
Gilles Peskine449bd832023-01-11 14:50:10 +0100523static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
524{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700525 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000526 /* Example #1 */
527 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
528 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700529 },
530 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000531 /* Example #2 */
532 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
533 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700534 },
535 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000536 /* Example #3 */
537 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
538 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700539 },
540 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000541 /* Example #4 */
542 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
543 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700544 }
545};
Yanray Wangdd56add2023-05-11 13:53:46 +0800546#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700547
Janos Follathcd13bd22016-12-13 11:51:04 +0000548/* CMAC-AES256 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800549#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700550static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000551 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
552 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
553 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
554 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700555};
Simon Butcher69283e52016-10-06 12:49:58 +0100556static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700557 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000558 /* K1 */
559 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
560 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700561 },
562 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000563 /* K2 */
564 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
565 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700566 }
567};
Gilles Peskine449bd832023-01-11 14:50:10 +0100568static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
569{
Brian Murray0f6af732016-05-19 15:59:23 -0700570 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000571 /* Example #1 */
572 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
573 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700574 },
575 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000576 /* Example #2 */
577 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
578 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700579 },
580 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000581 /* Example #3 */
582 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
583 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700584 },
585 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000586 /* Example #4 */
587 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
588 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700589 }
590};
Yanray Wangdd56add2023-05-11 13:53:46 +0800591#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700592#endif /* MBEDTLS_AES_C */
593
Simon Butcher69283e52016-10-06 12:49:58 +0100594#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700595/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700596static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700597 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000598 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700599 20,
600 32
601};
602
Janos Follathcd13bd22016-12-13 11:51:04 +0000603/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700604static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000605 /* Key1 */
606 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
607 /* Key2 */
608 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
609 /* Key3 */
610 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700611};
612static const unsigned char des3_2key_subkeys[2][8] = {
613 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000614 /* K1 */
615 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700616 },
617 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000618 /* K2 */
619 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700620 }
621};
Gilles Peskine449bd832023-01-11 14:50:10 +0100622static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
623 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700624 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000625 /* Sample #1 */
626 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700627 },
628 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000629 /* Sample #2 */
630 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700631 },
632 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000633 /* Sample #3 */
634 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700635 },
636 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000637 /* Sample #4 */
638 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700639 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700641
Janos Follathcd13bd22016-12-13 11:51:04 +0000642/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700643static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000644 /* Key1 */
645 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
646 /* Key2 */
647 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
648 /* Key3 */
649 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700650};
651static const unsigned char des3_3key_subkeys[2][8] = {
652 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000653 /* K1 */
654 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700655 },
656 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000657 /* K2 */
658 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700659 }
660};
Gilles Peskine449bd832023-01-11 14:50:10 +0100661static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
662 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700663 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000664 /* Sample #1 */
665 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700666 },
667 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000668 /* Sample #2 */
669 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700670 },
671 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000672 /* Sample #3 */
673 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700674 },
675 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000676 /* Sample #4 */
677 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700678 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700680
Brian Murray0f6af732016-05-19 15:59:23 -0700681#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700682
Simon Butcher69283e52016-10-06 12:49:58 +0100683#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700684/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000685static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* Key */
687 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
688 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000689 0xed, 0xcb
690};
691
692/* Sizes in bytes */
693static const size_t PRFKlen[NB_PRF_TESTS] = {
694 18,
695 16,
696 10
697};
698
Janos Follathcd13bd22016-12-13 11:51:04 +0000699/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000700static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000701 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
702 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000703 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000704};
705
706static const unsigned char PRFT[NB_PRF_TESTS][16] = {
707 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000708 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
709 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000710 },
711 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000712 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
713 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000714 },
715 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000716 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
717 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000718 }
719};
Brian Murray0f6af732016-05-19 15:59:23 -0700720#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722static int cmac_test_subkeys(int verbose,
723 const char *testname,
724 const unsigned char *key,
725 int keybits,
726 const unsigned char *subkeys,
727 mbedtls_cipher_type_t cipher_type,
728 int block_size,
729 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100730{
Brian Murray2fab5c92016-12-15 18:51:13 -0800731 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100732 mbedtls_cipher_context_t ctx;
733 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200734 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
735 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
738 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100739 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100741 }
742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 for (i = 0; i < num_tests; i++) {
744 if (verbose != 0) {
745 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
746 }
Simon Butcher327398a2016-10-05 14:09:11 +0100747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
751 if (verbose != 0) {
752 mbedtls_printf("test execution failed\n");
753 }
Simon Butcher327398a2016-10-05 14:09:11 +0100754
Janos Follathd4443582016-10-12 10:00:42 +0100755 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100756 }
757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
759 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100760 /* When CMAC is implemented by an alternative implementation, or
761 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100762 * AES-192 may be unavailable. This should not cause the selftest
763 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
765 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
766 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
767 if (verbose != 0) {
768 mbedtls_printf("skipped\n");
769 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100770 goto next_test;
771 }
772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if (verbose != 0) {
774 mbedtls_printf("test execution failed\n");
775 }
Simon Butcher327398a2016-10-05 14:09:11 +0100776
Janos Follathd4443582016-10-12 10:00:42 +0100777 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100778 }
779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 ret = cmac_generate_subkeys(&ctx, K1, K2);
781 if (ret != 0) {
782 if (verbose != 0) {
783 mbedtls_printf("failed\n");
784 }
Janos Follathd4443582016-10-12 10:00:42 +0100785
786 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100787 }
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
790 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
791 if (verbose != 0) {
792 mbedtls_printf("failed\n");
793 }
Janos Follathd4443582016-10-12 10:00:42 +0100794
795 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100796 }
797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 if (verbose != 0) {
799 mbedtls_printf("passed\n");
800 }
Janos Follathd4443582016-10-12 10:00:42 +0100801
Steven Cooreman830d5af2021-01-08 18:01:46 +0100802next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100804 }
805
Gilles Peskinedf761d52018-03-01 22:18:14 +0100806 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100807 goto exit;
808
809cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100811
Janos Follathd4443582016-10-12 10:00:42 +0100812exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100814}
815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816static int cmac_test_wth_cipher(int verbose,
817 const char *testname,
818 const unsigned char *key,
819 int keybits,
820 const unsigned char *messages,
821 const unsigned int message_lengths[4],
822 const unsigned char *expected_result,
823 mbedtls_cipher_type_t cipher_type,
824 int block_size,
825 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700826{
Simon Butcher327398a2016-10-05 14:09:11 +0100827 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800828 int i, ret = 0;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200829 unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murray57863ad2016-05-19 16:38:36 -0700830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
832 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100833 /* Failing at this point must be due to a build issue */
834 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700835 goto exit;
836 }
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 for (i = 0; i < num_tests; i++) {
839 if (verbose != 0) {
840 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
841 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700842
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
844 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100845 /* When CMAC is implemented by an alternative implementation, or
846 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100847 * AES-192 and/or 3DES may be unavailable. This should not cause
848 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
850 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
851 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
852 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
853 if (verbose != 0) {
854 mbedtls_printf("skipped\n");
855 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100856 continue;
857 }
858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 if (verbose != 0) {
860 mbedtls_printf("failed\n");
861 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700862 goto exit;
863 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
866 if (verbose != 0) {
867 mbedtls_printf("failed\n");
868 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700869 goto exit;
870 }
871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 if (verbose != 0) {
873 mbedtls_printf("passed\n");
874 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700875 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100876 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100877
Simon Butcher69283e52016-10-06 12:49:58 +0100878exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700880}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000881
Simon Butcher69283e52016-10-06 12:49:58 +0100882#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100883static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700884{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000885 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000886 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100887 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 for (i = 0; i < NB_PRF_TESTS; i++) {
890 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
891 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
892 if (ret != 0 ||
893 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100894
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 if (verbose != 0) {
896 mbedtls_printf("failed\n");
897 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 return ret;
900 } else if (verbose != 0) {
901 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700902 }
903 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700905}
906#endif /* MBEDTLS_AES_C */
907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700909{
Janos Follath24eed8d2019-11-22 13:21:35 +0000910 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100911
Simon Butcher69283e52016-10-06 12:49:58 +0100912#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100913 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if ((ret = cmac_test_subkeys(verbose,
915 "AES 128",
916 aes_128_key,
917 128,
918 (const unsigned char *) aes_128_subkeys,
919 MBEDTLS_CIPHER_AES_128_ECB,
920 MBEDTLS_AES_BLOCK_SIZE,
921 NB_CMAC_TESTS_PER_KEY)) != 0) {
922 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100923 }
924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 if ((ret = cmac_test_wth_cipher(verbose,
926 "AES 128",
927 aes_128_key,
928 128,
929 test_message,
930 aes_message_lengths,
931 (const unsigned char *) aes_128_expected_result,
932 MBEDTLS_CIPHER_AES_128_ECB,
933 MBEDTLS_AES_BLOCK_SIZE,
934 NB_CMAC_TESTS_PER_KEY)) != 0) {
935 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100936 }
937
938 /* AES-192 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800939#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 if ((ret = cmac_test_subkeys(verbose,
941 "AES 192",
942 aes_192_key,
943 192,
944 (const unsigned char *) aes_192_subkeys,
945 MBEDTLS_CIPHER_AES_192_ECB,
946 MBEDTLS_AES_BLOCK_SIZE,
947 NB_CMAC_TESTS_PER_KEY)) != 0) {
948 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700949 }
Brian Murray0f6af732016-05-19 15:59:23 -0700950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 if ((ret = cmac_test_wth_cipher(verbose,
952 "AES 192",
953 aes_192_key,
954 192,
955 test_message,
956 aes_message_lengths,
957 (const unsigned char *) aes_192_expected_result,
958 MBEDTLS_CIPHER_AES_192_ECB,
959 MBEDTLS_AES_BLOCK_SIZE,
960 NB_CMAC_TESTS_PER_KEY)) != 0) {
961 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100962 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800963#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Simon Butcher327398a2016-10-05 14:09:11 +0100964
965 /* AES-256 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800966#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 if ((ret = cmac_test_subkeys(verbose,
968 "AES 256",
969 aes_256_key,
970 256,
971 (const unsigned char *) aes_256_subkeys,
972 MBEDTLS_CIPHER_AES_256_ECB,
973 MBEDTLS_AES_BLOCK_SIZE,
974 NB_CMAC_TESTS_PER_KEY)) != 0) {
975 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700976 }
Brian Murray0f6af732016-05-19 15:59:23 -0700977
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 if ((ret = cmac_test_wth_cipher(verbose,
979 "AES 256",
980 aes_256_key,
981 256,
982 test_message,
983 aes_message_lengths,
984 (const unsigned char *) aes_256_expected_result,
985 MBEDTLS_CIPHER_AES_256_ECB,
986 MBEDTLS_AES_BLOCK_SIZE,
987 NB_CMAC_TESTS_PER_KEY)) != 0) {
988 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700989 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800990#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700991#endif /* MBEDTLS_AES_C */
992
Simon Butcher69283e52016-10-06 12:49:58 +0100993#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100994 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 if ((ret = cmac_test_subkeys(verbose,
996 "3DES 2 key",
997 des3_2key_key,
998 192,
999 (const unsigned char *) des3_2key_subkeys,
1000 MBEDTLS_CIPHER_DES_EDE3_ECB,
1001 MBEDTLS_DES3_BLOCK_SIZE,
1002 NB_CMAC_TESTS_PER_KEY)) != 0) {
1003 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001004 }
1005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 if ((ret = cmac_test_wth_cipher(verbose,
1007 "3DES 2 key",
1008 des3_2key_key,
1009 192,
1010 test_message,
1011 des3_message_lengths,
1012 (const unsigned char *) des3_2key_expected_result,
1013 MBEDTLS_CIPHER_DES_EDE3_ECB,
1014 MBEDTLS_DES3_BLOCK_SIZE,
1015 NB_CMAC_TESTS_PER_KEY)) != 0) {
1016 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001017 }
Brian Murray0f6af732016-05-19 15:59:23 -07001018
Simon Butcher327398a2016-10-05 14:09:11 +01001019 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 if ((ret = cmac_test_subkeys(verbose,
1021 "3DES 3 key",
1022 des3_3key_key,
1023 192,
1024 (const unsigned char *) des3_3key_subkeys,
1025 MBEDTLS_CIPHER_DES_EDE3_ECB,
1026 MBEDTLS_DES3_BLOCK_SIZE,
1027 NB_CMAC_TESTS_PER_KEY)) != 0) {
1028 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001029 }
1030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 if ((ret = cmac_test_wth_cipher(verbose,
1032 "3DES 3 key",
1033 des3_3key_key,
1034 192,
1035 test_message,
1036 des3_message_lengths,
1037 (const unsigned char *) des3_3key_expected_result,
1038 MBEDTLS_CIPHER_DES_EDE3_ECB,
1039 MBEDTLS_DES3_BLOCK_SIZE,
1040 NB_CMAC_TESTS_PER_KEY)) != 0) {
1041 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001042 }
Brian Murray0f6af732016-05-19 15:59:23 -07001043#endif /* MBEDTLS_DES_C */
1044
Simon Butcher69283e52016-10-06 12:49:58 +01001045#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1047 return ret;
1048 }
Brian Murray0f6af732016-05-19 15:59:23 -07001049#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 if (verbose != 0) {
1052 mbedtls_printf("\n");
1053 }
Brian Murray0f6af732016-05-19 15:59:23 -07001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001056}
1057
Brian Murray0f6af732016-05-19 15:59:23 -07001058#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001059
1060#endif /* MBEDTLS_CMAC_C */