blob: 32a9a0e56682d865113ddb814fe6d52bf2af819c [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 Rodgman7ff79652023-11-03 12:04:52 +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 Peskine1b6c09a2023-01-11 14:52:35 +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;
61 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010062 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070063
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010064 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070065 R_n = R_128;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066 } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070067 R_n = R_64;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010068 } else {
69 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070070 }
71
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010072 for (i = (int) blocksize - 1; i >= 0; i--) {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000073 output[i] = input[i] << 1 | overflow;
74 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000075 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000076
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000077 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
78 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +010079
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000080 /* MSVC has a warning about unary minus on unsigned, but this is
81 * well-defined and precisely what we want to do here */
82#if defined(_MSC_VER)
83#pragma warning( push )
84#pragma warning( disable : 4146 )
85#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010086 mask = -(input[0] >> 7);
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000087#if defined(_MSC_VER)
88#pragma warning( pop )
89#endif
90
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010091 output[blocksize - 1] ^= R_n & mask;
Simon Butcher327398a2016-10-05 14:09:11 +010092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000094}
95
96/*
97 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +010098 *
99 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000100 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100101static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
102 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000103{
Janos Follath24eed8d2019-11-22 13:21:35 +0000104 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100105 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700106 size_t olen, block_size;
107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100108 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700109
Simon Butcher327398a2016-10-05 14:09:11 +0100110 block_size = ctx->cipher_info->block_size;
111
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000112 /* Calculate Ek(0) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100113 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700114 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100115 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000116
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000117 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000118 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000119 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100120 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700121 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100122 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100125 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 }
Simon Butcher327398a2016-10-05 14:09:11 +0100127
128exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100131 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000132}
Ron Eldor621080d2017-12-21 10:57:43 +0200133#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000134
Ron Eldor621080d2017-12-21 10:57:43 +0200135#if !defined(MBEDTLS_CMAC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100136static void cmac_xor_block(unsigned char *output, const unsigned char *input1,
137 const unsigned char *input2,
138 const size_t block_size)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000139{
Hanno Becker61937d42017-04-26 15:01:23 +0100140 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100142 for (idx = 0; idx < block_size; idx++) {
143 output[idx] = input1[idx] ^ input2[idx];
144 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000145}
146
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000147/*
148 * Create padded last block from (partial) last block.
149 *
150 * We can't use the padding option from the cipher layer, as it only works for
151 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
152 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153static void cmac_pad(unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
154 size_t padded_block_len,
155 const unsigned char *last_block,
156 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000157{
158 size_t j;
159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160 for (j = 0; j < padded_block_len; j++) {
161 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000162 padded_block[j] = last_block[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000164 padded_block[j] = 0x80;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100165 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000166 padded_block[j] = 0x00;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000168 }
169}
170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100171int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
172 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000173{
Simon Butcher327398a2016-10-05 14:09:11 +0100174 mbedtls_cipher_type_t type;
175 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100176 int retval;
177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
179 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
180 }
Simon Butcher327398a2016-10-05 14:09:11 +0100181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
183 MBEDTLS_ENCRYPT)) != 0) {
184 return retval;
185 }
Simon Butcher327398a2016-10-05 14:09:11 +0100186
Simon Butcher327398a2016-10-05 14:09:11 +0100187 type = ctx->cipher_info->type;
188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100189 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100190 case MBEDTLS_CIPHER_AES_128_ECB:
191 case MBEDTLS_CIPHER_AES_192_ECB:
192 case MBEDTLS_CIPHER_AES_256_ECB:
193 case MBEDTLS_CIPHER_DES_EDE3_ECB:
194 break;
195 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100197 }
198
199 /* Allocated and initialise in the cipher context memory for the CMAC
200 * context */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100201 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
202 if (cmac_ctx == NULL) {
203 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
204 }
Simon Butcher327398a2016-10-05 14:09:11 +0100205
206 ctx->cmac_ctx = cmac_ctx;
207
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100208 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100209
210 return 0;
211}
212
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100213int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
214 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100215{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100216 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700217 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000218 int ret = 0;
219 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700220
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100221 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
222 ctx->cmac_ctx == NULL) {
223 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
224 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700225
Simon Butcher327398a2016-10-05 14:09:11 +0100226 cmac_ctx = ctx->cmac_ctx;
227 block_size = ctx->cipher_info->block_size;
228 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000229
Simon Butcher6b0774a2016-10-10 21:37:42 +0100230 /* Is there data still to process from the last call, that's greater in
231 * size than a block? */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232 if (cmac_ctx->unprocessed_len > 0 &&
233 ilen > block_size - cmac_ctx->unprocessed_len) {
234 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
235 input,
236 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100237
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 cmac_xor_block(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100240 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
241 &olen)) != 0) {
242 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100243 }
244
Simon Butcher6b0774a2016-10-10 21:37:42 +0100245 input += block_size - cmac_ctx->unprocessed_len;
246 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100247 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700248 }
249
Simon Butcher327398a2016-10-05 14:09:11 +0100250 /* n is the number of blocks including any final partial block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100251 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100252
Simon B3249cb72016-11-03 01:11:37 +0000253 /* Iterate across the input data in block sized chunks, excluding any
254 * final partial or complete block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100255 for (j = 1; j < n; j++) {
256 cmac_xor_block(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100257
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100258 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
259 &olen)) != 0) {
260 goto exit;
261 }
Simon Butcher327398a2016-10-05 14:09:11 +0100262
263 ilen -= block_size;
264 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700265 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000266
Simon Butcher327398a2016-10-05 14:09:11 +0100267 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 if (ilen > 0) {
269 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
270 input,
271 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100272 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100273 }
274
275exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100276 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100277}
278
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100279int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
280 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100281{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100283 unsigned char *state, *last_block;
284 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
285 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
286 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Janos Follath24eed8d2019-11-22 13:21:35 +0000287 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100288 size_t olen, block_size;
289
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100290 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
291 output == NULL) {
292 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
293 }
Simon Butcher327398a2016-10-05 14:09:11 +0100294
295 cmac_ctx = ctx->cmac_ctx;
296 block_size = ctx->cipher_info->block_size;
297 state = cmac_ctx->state;
298
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100299 mbedtls_platform_zeroize(K1, sizeof(K1));
300 mbedtls_platform_zeroize(K2, sizeof(K2));
301 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100302
Simon Butcher69283e52016-10-06 12:49:58 +0100303 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000304
305 /* Calculate last block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306 if (cmac_ctx->unprocessed_len < block_size) {
307 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
308 cmac_xor_block(M_last, M_last, K2, block_size);
309 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000310 /* Last block is complete block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 cmac_xor_block(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000312 }
313
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000314
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315 cmac_xor_block(state, M_last, state, block_size);
316 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
317 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100318 goto exit;
319 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100322
323exit:
324 /* Wipe the generated keys on the stack, and any other transients to avoid
325 * side channel leakage */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100326 mbedtls_platform_zeroize(K1, sizeof(K1));
327 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100328
329 cmac_ctx->unprocessed_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100330 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
331 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100332
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 mbedtls_platform_zeroize(state, MBEDTLS_CIPHER_BLKSIZE_MAX);
334 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000335}
336
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100339 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000340
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100341 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
342 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
343 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700344
Simon Butcher327398a2016-10-05 14:09:11 +0100345 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000346
Simon Butcher327398a2016-10-05 14:09:11 +0100347 /* Reset the internal state */
348 cmac_ctx->unprocessed_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
350 sizeof(cmac_ctx->unprocessed_block));
351 mbedtls_platform_zeroize(cmac_ctx->state,
352 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000353
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000355}
356
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100357int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
358 const unsigned char *key, size_t keylen,
359 const unsigned char *input, size_t ilen,
360 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100361{
362 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000363 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100364
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100365 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
366 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
367 }
Simon Butcher327398a2016-10-05 14:09:11 +0100368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100370
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100371 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100372 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 }
Simon Butcher327398a2016-10-05 14:09:11 +0100374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100375 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
376 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100377 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 }
Simon Butcher327398a2016-10-05 14:09:11 +0100379
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100380 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
381 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100382 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383 }
Simon Butcher327398a2016-10-05 14:09:11 +0100384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100386
387exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100391}
Simon Butcher327398a2016-10-05 14:09:11 +0100392
Simon Butcher69283e52016-10-06 12:49:58 +0100393#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000394/*
Simon Butcher69283e52016-10-06 12:49:58 +0100395 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000396 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
398 const unsigned char *input, size_t in_len,
399 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000400{
Janos Follath24eed8d2019-11-22 13:21:35 +0000401 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100402 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100403 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
404 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
405
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100406 if (key == NULL || input == NULL || output == NULL) {
407 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
408 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000409
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100410 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
411 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100412 /* Failing at this point must be due to a build issue */
413 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
414 goto exit;
415 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700416
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000418 /* Use key as is */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
420 } else {
421 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
424 key_length, int_key);
425 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700426 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100427 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000428 }
429
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100430 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
431 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000432
Simon Butcher327398a2016-10-05 14:09:11 +0100433exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700435
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100436 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000437}
Brian Murrayb439d452016-05-19 16:02:42 -0700438#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000439
Steven Cooreman63342772017-04-04 11:47:16 +0200440#endif /* !MBEDTLS_CMAC_ALT */
441
Simon Butcher69283e52016-10-06 12:49:58 +0100442#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000443/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000444 * CMAC test data for SP800-38B
445 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
446 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700447 *
448 * AES-CMAC-PRF-128 test data from RFC 4615
449 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000450 */
451
Brian Murray0f6af732016-05-19 15:59:23 -0700452#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000453#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100454
Brian Murray0f6af732016-05-19 15:59:23 -0700455#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
456/* All CMAC test inputs are truncated from the same 64 byte buffer. */
457static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000458 /* PT */
459 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
460 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
461 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
462 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
463 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
464 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
465 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
466 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000467};
Simon Butcher69283e52016-10-06 12:49:58 +0100468#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700469
Simon Butcher69283e52016-10-06 12:49:58 +0100470#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700471/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700472static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000473 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700474 0,
475 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000476 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700477 64
478};
479
Janos Follathcd13bd22016-12-13 11:51:04 +0000480/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700481static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000482 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
483 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700484};
Simon Butcher69283e52016-10-06 12:49:58 +0100485static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700486 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000487 /* K1 */
488 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
489 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700490 },
491 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000492 /* K2 */
493 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
494 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700495 }
496};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
498{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000499 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000500 /* Example #1 */
501 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
502 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000503 },
504 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000505 /* Example #2 */
506 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
507 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000508 },
509 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000510 /* Example #3 */
511 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
512 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000513 },
514 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000515 /* Example #4 */
516 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
517 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000518 }
519};
520
Janos Follathcd13bd22016-12-13 11:51:04 +0000521/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700522static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000523 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
524 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
525 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000526};
Simon Butcher69283e52016-10-06 12:49:58 +0100527static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700528 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000529 /* K1 */
530 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
531 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700532 },
533 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000534 /* K2 */
535 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
536 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700537 }
538};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100539static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
540{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700541 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000542 /* Example #1 */
543 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
544 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700545 },
546 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000547 /* Example #2 */
548 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
549 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700550 },
551 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000552 /* Example #3 */
553 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
554 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700555 },
556 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000557 /* Example #4 */
558 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
559 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700560 }
561};
562
Janos Follathcd13bd22016-12-13 11:51:04 +0000563/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700564static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000565 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
566 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
567 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
568 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700569};
Simon Butcher69283e52016-10-06 12:49:58 +0100570static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700571 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000572 /* K1 */
573 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
574 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700575 },
576 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000577 /* K2 */
578 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
579 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700580 }
581};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100582static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
583{
Brian Murray0f6af732016-05-19 15:59:23 -0700584 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000585 /* Example #1 */
586 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
587 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700588 },
589 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000590 /* Example #2 */
591 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
592 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700593 },
594 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000595 /* Example #3 */
596 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
597 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700598 },
599 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000600 /* Example #4 */
601 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
602 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700603 }
604};
605#endif /* MBEDTLS_AES_C */
606
Simon Butcher69283e52016-10-06 12:49:58 +0100607#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700608/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700609static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700610 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000611 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700612 20,
613 32
614};
615
Janos Follathcd13bd22016-12-13 11:51:04 +0000616/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700617static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000618 /* Key1 */
619 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
620 /* Key2 */
621 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
622 /* Key3 */
623 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700624};
625static const unsigned char des3_2key_subkeys[2][8] = {
626 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000627 /* K1 */
628 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700629 },
630 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000631 /* K2 */
632 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700633 }
634};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100635static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
636 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700637 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000638 /* Sample #1 */
639 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700640 },
641 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000642 /* Sample #2 */
643 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700644 },
645 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000646 /* Sample #3 */
647 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700648 },
649 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000650 /* Sample #4 */
651 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700652 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100653 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700654
Janos Follathcd13bd22016-12-13 11:51:04 +0000655/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700656static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000657 /* Key1 */
658 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
659 /* Key2 */
660 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
661 /* Key3 */
662 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700663};
664static const unsigned char des3_3key_subkeys[2][8] = {
665 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000666 /* K1 */
667 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700668 },
669 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000670 /* K2 */
671 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700672 }
673};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100674static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
675 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700676 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000677 /* Sample #1 */
678 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700679 },
680 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000681 /* Sample #2 */
682 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700683 },
684 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000685 /* Sample #3 */
686 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700687 },
688 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000689 /* Sample #4 */
690 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700691 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100692 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700693
Brian Murray0f6af732016-05-19 15:59:23 -0700694#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700695
Simon Butcher69283e52016-10-06 12:49:58 +0100696#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700697/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000698static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000699 /* Key */
700 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
701 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000702 0xed, 0xcb
703};
704
705/* Sizes in bytes */
706static const size_t PRFKlen[NB_PRF_TESTS] = {
707 18,
708 16,
709 10
710};
711
Janos Follathcd13bd22016-12-13 11:51:04 +0000712/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000713static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000714 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
715 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000716 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000717};
718
719static const unsigned char PRFT[NB_PRF_TESTS][16] = {
720 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000721 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
722 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000723 },
724 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000725 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
726 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000727 },
728 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000729 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
730 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000731 }
732};
Brian Murray0f6af732016-05-19 15:59:23 -0700733#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000734
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100735static int cmac_test_subkeys(int verbose,
736 const char *testname,
737 const unsigned char *key,
738 int keybits,
739 const unsigned char *subkeys,
740 mbedtls_cipher_type_t cipher_type,
741 int block_size,
742 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100743{
Brian Murray2fab5c92016-12-15 18:51:13 -0800744 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100745 mbedtls_cipher_context_t ctx;
746 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100747 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
748 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100749
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100750 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
751 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100752 /* Failing at this point must be due to a build issue */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100753 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100754 }
755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756 for (i = 0; i < num_tests; i++) {
757 if (verbose != 0) {
758 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
759 }
Simon Butcher327398a2016-10-05 14:09:11 +0100760
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100761 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100762
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100763 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
764 if (verbose != 0) {
765 mbedtls_printf("test execution failed\n");
766 }
Simon Butcher327398a2016-10-05 14:09:11 +0100767
Janos Follathd4443582016-10-12 10:00:42 +0100768 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100769 }
770
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100771 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
772 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100773 /* When CMAC is implemented by an alternative implementation, or
774 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100775 * AES-192 may be unavailable. This should not cause the selftest
776 * function to fail. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100777 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
778 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
779 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
780 if (verbose != 0) {
781 mbedtls_printf("skipped\n");
782 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100783 goto next_test;
784 }
785
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100786 if (verbose != 0) {
787 mbedtls_printf("test execution failed\n");
788 }
Simon Butcher327398a2016-10-05 14:09:11 +0100789
Janos Follathd4443582016-10-12 10:00:42 +0100790 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100791 }
792
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100793 ret = cmac_generate_subkeys(&ctx, K1, K2);
794 if (ret != 0) {
795 if (verbose != 0) {
796 mbedtls_printf("failed\n");
797 }
Janos Follathd4443582016-10-12 10:00:42 +0100798
799 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100800 }
801
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100802 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
803 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
804 if (verbose != 0) {
805 mbedtls_printf("failed\n");
806 }
Janos Follathd4443582016-10-12 10:00:42 +0100807
808 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100809 }
810
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100811 if (verbose != 0) {
812 mbedtls_printf("passed\n");
813 }
Janos Follathd4443582016-10-12 10:00:42 +0100814
Steven Cooreman830d5af2021-01-08 18:01:46 +0100815next_test:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100816 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100817 }
818
Gilles Peskinedf761d52018-03-01 22:18:14 +0100819 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100820 goto exit;
821
822cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100823 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100824
Janos Follathd4443582016-10-12 10:00:42 +0100825exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100826 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100827}
828
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100829static int cmac_test_wth_cipher(int verbose,
830 const char *testname,
831 const unsigned char *key,
832 int keybits,
833 const unsigned char *messages,
834 const unsigned int message_lengths[4],
835 const unsigned char *expected_result,
836 mbedtls_cipher_type_t cipher_type,
837 int block_size,
838 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700839{
Simon Butcher327398a2016-10-05 14:09:11 +0100840 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800841 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100842 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700843
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100844 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
845 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100846 /* Failing at this point must be due to a build issue */
847 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700848 goto exit;
849 }
850
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100851 for (i = 0; i < num_tests; i++) {
852 if (verbose != 0) {
853 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
854 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700855
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100856 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
857 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100858 /* When CMAC is implemented by an alternative implementation, or
859 * the underlying primitive itself is implemented alternatively,
Steven Cooreman146e7fc2021-02-15 13:42:35 +0100860 * AES-192 and/or 3DES may be unavailable. This should not cause
861 * the selftest function to fail. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100862 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
863 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
864 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
865 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
866 if (verbose != 0) {
867 mbedtls_printf("skipped\n");
868 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100869 continue;
870 }
871
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100872 if (verbose != 0) {
873 mbedtls_printf("failed\n");
874 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700875 goto exit;
876 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700877
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100878 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
879 if (verbose != 0) {
880 mbedtls_printf("failed\n");
881 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700882 goto exit;
883 }
884
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100885 if (verbose != 0) {
886 mbedtls_printf("passed\n");
887 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700888 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100889 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100890
Simon Butcher69283e52016-10-06 12:49:58 +0100891exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700893}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000894
Simon Butcher69283e52016-10-06 12:49:58 +0100895#if defined(MBEDTLS_AES_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100896static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700897{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000898 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000899 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100900 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100902 for (i = 0; i < NB_PRF_TESTS; i++) {
903 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
904 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
905 if (ret != 0 ||
906 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100907
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100908 if (verbose != 0) {
909 mbedtls_printf("failed\n");
910 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700911
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100912 return ret;
913 } else if (verbose != 0) {
914 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700915 }
916 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100917 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700918}
919#endif /* MBEDTLS_AES_C */
920
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100921int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700922{
Janos Follath24eed8d2019-11-22 13:21:35 +0000923 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100924
Simon Butcher69283e52016-10-06 12:49:58 +0100925#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100926 /* AES-128 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100927 if ((ret = cmac_test_subkeys(verbose,
928 "AES 128",
929 aes_128_key,
930 128,
931 (const unsigned char *) aes_128_subkeys,
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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100938 if ((ret = cmac_test_wth_cipher(verbose,
939 "AES 128",
940 aes_128_key,
941 128,
942 test_message,
943 aes_message_lengths,
944 (const unsigned char *) aes_128_expected_result,
945 MBEDTLS_CIPHER_AES_128_ECB,
946 MBEDTLS_AES_BLOCK_SIZE,
947 NB_CMAC_TESTS_PER_KEY)) != 0) {
948 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100949 }
950
951 /* AES-192 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100952 if ((ret = cmac_test_subkeys(verbose,
953 "AES 192",
954 aes_192_key,
955 192,
956 (const unsigned char *) aes_192_subkeys,
957 MBEDTLS_CIPHER_AES_192_ECB,
958 MBEDTLS_AES_BLOCK_SIZE,
959 NB_CMAC_TESTS_PER_KEY)) != 0) {
960 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700961 }
Brian Murray0f6af732016-05-19 15:59:23 -0700962
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100963 if ((ret = cmac_test_wth_cipher(verbose,
964 "AES 192",
965 aes_192_key,
966 192,
967 test_message,
968 aes_message_lengths,
969 (const unsigned char *) aes_192_expected_result,
970 MBEDTLS_CIPHER_AES_192_ECB,
971 MBEDTLS_AES_BLOCK_SIZE,
972 NB_CMAC_TESTS_PER_KEY)) != 0) {
973 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100974 }
975
976 /* AES-256 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 }
Brian Murray0f6af732016-05-19 15:59:23 -07001000#endif /* MBEDTLS_AES_C */
1001
Simon Butcher69283e52016-10-06 12:49:58 +01001002#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001003 /* 3DES 2 key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001004 if ((ret = cmac_test_subkeys(verbose,
1005 "3DES 2 key",
1006 des3_2key_key,
1007 192,
1008 (const unsigned char *) des3_2key_subkeys,
1009 MBEDTLS_CIPHER_DES_EDE3_ECB,
1010 MBEDTLS_DES3_BLOCK_SIZE,
1011 NB_CMAC_TESTS_PER_KEY)) != 0) {
1012 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001013 }
1014
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001015 if ((ret = cmac_test_wth_cipher(verbose,
1016 "3DES 2 key",
1017 des3_2key_key,
1018 192,
1019 test_message,
1020 des3_message_lengths,
1021 (const unsigned char *) des3_2key_expected_result,
1022 MBEDTLS_CIPHER_DES_EDE3_ECB,
1023 MBEDTLS_DES3_BLOCK_SIZE,
1024 NB_CMAC_TESTS_PER_KEY)) != 0) {
1025 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001026 }
Brian Murray0f6af732016-05-19 15:59:23 -07001027
Simon Butcher327398a2016-10-05 14:09:11 +01001028 /* 3DES 3 key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001029 if ((ret = cmac_test_subkeys(verbose,
1030 "3DES 3 key",
1031 des3_3key_key,
1032 192,
1033 (const unsigned char *) des3_3key_subkeys,
1034 MBEDTLS_CIPHER_DES_EDE3_ECB,
1035 MBEDTLS_DES3_BLOCK_SIZE,
1036 NB_CMAC_TESTS_PER_KEY)) != 0) {
1037 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001038 }
1039
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001040 if ((ret = cmac_test_wth_cipher(verbose,
1041 "3DES 3 key",
1042 des3_3key_key,
1043 192,
1044 test_message,
1045 des3_message_lengths,
1046 (const unsigned char *) des3_3key_expected_result,
1047 MBEDTLS_CIPHER_DES_EDE3_ECB,
1048 MBEDTLS_DES3_BLOCK_SIZE,
1049 NB_CMAC_TESTS_PER_KEY)) != 0) {
1050 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001051 }
Brian Murray0f6af732016-05-19 15:59:23 -07001052#endif /* MBEDTLS_DES_C */
1053
Simon Butcher69283e52016-10-06 12:49:58 +01001054#if defined(MBEDTLS_AES_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001055 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1056 return ret;
1057 }
Brian Murray0f6af732016-05-19 15:59:23 -07001058#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001059
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001060 if (verbose != 0) {
1061 mbedtls_printf("\n");
1062 }
Brian Murray0f6af732016-05-19 15:59:23 -07001063
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001064 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001065}
1066
Brian Murray0f6af732016-05-19 15:59:23 -07001067#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001068
1069#endif /* MBEDTLS_CMAC_C */