blob: 0c07de6f2fcf9011ed82f0d2d75ef7ac3674a490 [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
Robert Cragie3d23b1d2015-12-15 07:38:11 +00007 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000020 */
21
22/*
Brian Murray53e23b62016-09-13 14:00:15 -070023 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010024 *
25 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
26 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000027 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010028 *
29 * - RFC 4493 - The AES-CMAC Algorithm
30 * https://tools.ietf.org/html/rfc4493
31 *
32 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
33 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
34 * Algorithm for the Internet Key Exchange Protocol (IKE)
35 * https://tools.ietf.org/html/rfc4615
36 *
37 * Additional test vectors: ISO/IEC 9797-1
38 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000039 */
40
Gilles Peskinedb09ef62020-06-03 01:43:33 +020041#include "common.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000042
43#if defined(MBEDTLS_CMAC_C)
44
45#include "mbedtls/cmac.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050046#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000047#include "mbedtls/error.h"
Steven Cooreman655b0122021-01-11 14:34:51 +010048#include "mbedtls/platform.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000049
50#include <string.h>
51
Ron Eldor621080d2017-12-21 10:57:43 +020052#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020053
Robert Cragie3d23b1d2015-12-15 07:38:11 +000054/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070055 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000056 *
Brian Murray72b69e32016-09-13 14:21:01 -070057 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000058 *
Simon Butcher327398a2016-10-05 14:09:11 +010059 * If MSB(p) = 0, then p = (p << 1)
60 * If MSB(p) = 1, then p = (p << 1) ^ R_n
61 * with R_64 = 0x1B and R_128 = 0x87
62 *
63 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080064 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000065 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066static int cmac_multiply_by_u(unsigned char *output,
67 const unsigned char *input,
68 size_t blocksize)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000069{
Brian Murrayb0c3c432016-05-18 14:29:51 -070070 const unsigned char R_128 = 0x87;
71 const unsigned char R_64 = 0x1B;
72 unsigned char R_n, mask;
73 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010074 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070075
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010076 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070077 R_n = R_128;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010078 } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070079 R_n = R_64;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010080 } else {
81 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070082 }
83
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010084 for (i = (int) blocksize - 1; i >= 0; i--) {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000085 output[i] = input[i] << 1 | overflow;
86 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000087 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000088
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000089 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
90 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +010091
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000092 /* MSVC has a warning about unary minus on unsigned, but this is
93 * well-defined and precisely what we want to do here */
94#if defined(_MSC_VER)
95#pragma warning( push )
96#pragma warning( disable : 4146 )
97#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098 mask = -(input[0] >> 7);
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000099#if defined(_MSC_VER)
100#pragma warning( pop )
101#endif
102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 output[blocksize - 1] ^= R_n & mask;
Simon Butcher327398a2016-10-05 14:09:11 +0100104
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100105 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000106}
107
108/*
109 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100110 *
111 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000112 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100113static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
114 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000115{
Janos Follath24eed8d2019-11-22 13:21:35 +0000116 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100117 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700118 size_t olen, block_size;
119
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100120 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700121
Simon Butcher327398a2016-10-05 14:09:11 +0100122 block_size = ctx->cipher_info->block_size;
123
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000124 /* Calculate Ek(0) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700126 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100127 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000128
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000129 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000130 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000131 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100132 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700133 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000135
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100136 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100137 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100138 }
Simon Butcher327398a2016-10-05 14:09:11 +0100139
140exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100142
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000144}
Ron Eldor621080d2017-12-21 10:57:43 +0200145#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000146
Ron Eldor621080d2017-12-21 10:57:43 +0200147#if !defined(MBEDTLS_CMAC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100148static void cmac_xor_block(unsigned char *output, const unsigned char *input1,
149 const unsigned char *input2,
150 const size_t block_size)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000151{
Hanno Becker61937d42017-04-26 15:01:23 +0100152 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100154 for (idx = 0; idx < block_size; idx++) {
155 output[idx] = input1[idx] ^ input2[idx];
156 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000157}
158
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000159/*
160 * Create padded last block from (partial) last block.
161 *
162 * We can't use the padding option from the cipher layer, as it only works for
163 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
164 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100165static void cmac_pad(unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
166 size_t padded_block_len,
167 const unsigned char *last_block,
168 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000169{
170 size_t j;
171
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100172 for (j = 0; j < padded_block_len; j++) {
173 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000174 padded_block[j] = last_block[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100175 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000176 padded_block[j] = 0x80;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100177 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000178 padded_block[j] = 0x00;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000180 }
181}
182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100183int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
184 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000185{
Simon Butcher327398a2016-10-05 14:09:11 +0100186 mbedtls_cipher_type_t type;
187 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100188 int retval;
189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100190 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
191 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
192 }
Simon Butcher327398a2016-10-05 14:09:11 +0100193
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100194 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
195 MBEDTLS_ENCRYPT)) != 0) {
196 return retval;
197 }
Simon Butcher327398a2016-10-05 14:09:11 +0100198
Simon Butcher327398a2016-10-05 14:09:11 +0100199 type = ctx->cipher_info->type;
200
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100201 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100202 case MBEDTLS_CIPHER_AES_128_ECB:
203 case MBEDTLS_CIPHER_AES_192_ECB:
204 case MBEDTLS_CIPHER_AES_256_ECB:
205 case MBEDTLS_CIPHER_DES_EDE3_ECB:
206 break;
207 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100208 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100209 }
210
211 /* Allocated and initialise in the cipher context memory for the CMAC
212 * context */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100213 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
214 if (cmac_ctx == NULL) {
215 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
216 }
Simon Butcher327398a2016-10-05 14:09:11 +0100217
218 ctx->cmac_ctx = cmac_ctx;
219
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100220 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100221
222 return 0;
223}
224
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
226 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100227{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100228 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700229 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000230 int ret = 0;
231 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700232
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100233 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
234 ctx->cmac_ctx == NULL) {
235 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
236 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700237
Simon Butcher327398a2016-10-05 14:09:11 +0100238 cmac_ctx = ctx->cmac_ctx;
239 block_size = ctx->cipher_info->block_size;
240 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000241
Simon Butcher6b0774a2016-10-10 21:37:42 +0100242 /* Is there data still to process from the last call, that's greater in
243 * size than a block? */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100244 if (cmac_ctx->unprocessed_len > 0 &&
245 ilen > block_size - cmac_ctx->unprocessed_len) {
246 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
247 input,
248 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250 cmac_xor_block(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100251
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100252 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
253 &olen)) != 0) {
254 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100255 }
256
Simon Butcher6b0774a2016-10-10 21:37:42 +0100257 input += block_size - cmac_ctx->unprocessed_len;
258 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100259 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700260 }
261
Simon Butcher327398a2016-10-05 14:09:11 +0100262 /* n is the number of blocks including any final partial block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100263 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100264
Simon B3249cb72016-11-03 01:11:37 +0000265 /* Iterate across the input data in block sized chunks, excluding any
266 * final partial or complete block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267 for (j = 1; j < n; j++) {
268 cmac_xor_block(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
271 &olen)) != 0) {
272 goto exit;
273 }
Simon Butcher327398a2016-10-05 14:09:11 +0100274
275 ilen -= block_size;
276 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700277 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000278
Simon Butcher327398a2016-10-05 14:09:11 +0100279 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280 if (ilen > 0) {
281 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
282 input,
283 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100284 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100285 }
286
287exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100289}
290
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100291int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
292 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100293{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100294 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100295 unsigned char *state, *last_block;
296 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
297 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
298 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Janos Follath24eed8d2019-11-22 13:21:35 +0000299 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100300 size_t olen, block_size;
301
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100302 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
303 output == NULL) {
304 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
305 }
Simon Butcher327398a2016-10-05 14:09:11 +0100306
307 cmac_ctx = ctx->cmac_ctx;
308 block_size = ctx->cipher_info->block_size;
309 state = cmac_ctx->state;
310
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 mbedtls_platform_zeroize(K1, sizeof(K1));
312 mbedtls_platform_zeroize(K2, sizeof(K2));
313 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100314
Simon Butcher69283e52016-10-06 12:49:58 +0100315 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000316
317 /* Calculate last block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 if (cmac_ctx->unprocessed_len < block_size) {
319 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
320 cmac_xor_block(M_last, M_last, K2, block_size);
321 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000322 /* Last block is complete block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100323 cmac_xor_block(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000324 }
325
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000326
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327 cmac_xor_block(state, M_last, state, block_size);
328 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
329 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100330 goto exit;
331 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000332
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100334
335exit:
336 /* Wipe the generated keys on the stack, and any other transients to avoid
337 * side channel leakage */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 mbedtls_platform_zeroize(K1, sizeof(K1));
339 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100340
341 cmac_ctx->unprocessed_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
343 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 mbedtls_platform_zeroize(state, MBEDTLS_CIPHER_BLKSIZE_MAX);
346 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000347}
348
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000350{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100351 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000352
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100353 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
354 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
355 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700356
Simon Butcher327398a2016-10-05 14:09:11 +0100357 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000358
Simon Butcher327398a2016-10-05 14:09:11 +0100359 /* Reset the internal state */
360 cmac_ctx->unprocessed_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100361 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
362 sizeof(cmac_ctx->unprocessed_block));
363 mbedtls_platform_zeroize(cmac_ctx->state,
364 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000367}
368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
370 const unsigned char *key, size_t keylen,
371 const unsigned char *input, size_t ilen,
372 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100373{
374 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000375 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100376
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
378 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
379 }
Simon Butcher327398a2016-10-05 14:09:11 +0100380
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100384 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 }
Simon Butcher327398a2016-10-05 14:09:11 +0100386
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
388 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100389 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 }
Simon Butcher327398a2016-10-05 14:09:11 +0100391
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100392 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
393 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100394 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 }
Simon Butcher327398a2016-10-05 14:09:11 +0100396
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100398
399exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100403}
Simon Butcher327398a2016-10-05 14:09:11 +0100404
Simon Butcher69283e52016-10-06 12:49:58 +0100405#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000406/*
Simon Butcher69283e52016-10-06 12:49:58 +0100407 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000408 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
410 const unsigned char *input, size_t in_len,
411 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000412{
Janos Follath24eed8d2019-11-22 13:21:35 +0000413 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100414 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100415 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
416 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 if (key == NULL || input == NULL || output == NULL) {
419 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
420 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
423 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100424 /* Failing at this point must be due to a build issue */
425 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
426 goto exit;
427 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700428
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000430 /* Use key as is */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
432 } else {
433 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000434
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
436 key_length, int_key);
437 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700438 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100439 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000440 }
441
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
443 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000444
Simon Butcher327398a2016-10-05 14:09:11 +0100445exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100446 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700447
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100448 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000449}
Brian Murrayb439d452016-05-19 16:02:42 -0700450#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000451
Steven Cooreman63342772017-04-04 11:47:16 +0200452#endif /* !MBEDTLS_CMAC_ALT */
453
Simon Butcher69283e52016-10-06 12:49:58 +0100454#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000455/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000456 * CMAC test data for SP800-38B
457 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
458 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700459 *
460 * AES-CMAC-PRF-128 test data from RFC 4615
461 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000462 */
463
Brian Murray0f6af732016-05-19 15:59:23 -0700464#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000465#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100466
Brian Murray0f6af732016-05-19 15:59:23 -0700467#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
468/* All CMAC test inputs are truncated from the same 64 byte buffer. */
469static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000470 /* PT */
471 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
472 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
473 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
474 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
475 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
476 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
477 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
478 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000479};
Simon Butcher69283e52016-10-06 12:49:58 +0100480#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700481
Simon Butcher69283e52016-10-06 12:49:58 +0100482#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700483/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700484static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000485 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700486 0,
487 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000488 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700489 64
490};
491
Janos Follathcd13bd22016-12-13 11:51:04 +0000492/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700493static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000494 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
495 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700496};
Simon Butcher69283e52016-10-06 12:49:58 +0100497static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700498 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000499 /* K1 */
500 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
501 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700502 },
503 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000504 /* K2 */
505 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
506 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700507 }
508};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
510{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000511 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000512 /* Example #1 */
513 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
514 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000515 },
516 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000517 /* Example #2 */
518 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
519 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000520 },
521 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000522 /* Example #3 */
523 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
524 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000525 },
526 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000527 /* Example #4 */
528 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
529 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000530 }
531};
532
Janos Follathcd13bd22016-12-13 11:51:04 +0000533/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700534static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000535 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
536 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
537 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000538};
Simon Butcher69283e52016-10-06 12:49:58 +0100539static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700540 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000541 /* K1 */
542 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
543 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700544 },
545 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000546 /* K2 */
547 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
548 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700549 }
550};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100551static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
552{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700553 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000554 /* Example #1 */
555 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
556 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700557 },
558 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000559 /* Example #2 */
560 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
561 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700562 },
563 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000564 /* Example #3 */
565 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
566 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700567 },
568 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000569 /* Example #4 */
570 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
571 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700572 }
573};
574
Janos Follathcd13bd22016-12-13 11:51:04 +0000575/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700576static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000577 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
578 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
579 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
580 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700581};
Simon Butcher69283e52016-10-06 12:49:58 +0100582static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700583 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000584 /* K1 */
585 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
586 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700587 },
588 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000589 /* K2 */
590 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
591 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700592 }
593};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
595{
Brian Murray0f6af732016-05-19 15:59:23 -0700596 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000597 /* Example #1 */
598 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
599 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700600 },
601 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000602 /* Example #2 */
603 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
604 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700605 },
606 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000607 /* Example #3 */
608 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
609 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700610 },
611 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000612 /* Example #4 */
613 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
614 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700615 }
616};
617#endif /* MBEDTLS_AES_C */
618
Simon Butcher69283e52016-10-06 12:49:58 +0100619#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700620/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700621static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700622 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000623 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700624 20,
625 32
626};
627
Janos Follathcd13bd22016-12-13 11:51:04 +0000628/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700629static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000630 /* Key1 */
631 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
632 /* Key2 */
633 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
634 /* Key3 */
635 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700636};
637static const unsigned char des3_2key_subkeys[2][8] = {
638 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000639 /* K1 */
640 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700641 },
642 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000643 /* K2 */
644 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700645 }
646};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
648 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700649 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000650 /* Sample #1 */
651 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700652 },
653 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000654 /* Sample #2 */
655 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700656 },
657 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000658 /* Sample #3 */
659 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700660 },
661 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000662 /* Sample #4 */
663 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700664 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700666
Janos Follathcd13bd22016-12-13 11:51:04 +0000667/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700668static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000669 /* Key1 */
670 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
671 /* Key2 */
672 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
673 /* Key3 */
674 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700675};
676static const unsigned char des3_3key_subkeys[2][8] = {
677 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000678 /* K1 */
679 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700680 },
681 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000682 /* K2 */
683 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700684 }
685};
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100686static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
687 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700688 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000689 /* Sample #1 */
690 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700691 },
692 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000693 /* Sample #2 */
694 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700695 },
696 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000697 /* Sample #3 */
698 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700699 },
700 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000701 /* Sample #4 */
702 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700703 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100704 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700705
Brian Murray0f6af732016-05-19 15:59:23 -0700706#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700707
Simon Butcher69283e52016-10-06 12:49:58 +0100708#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700709/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000710static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000711 /* Key */
712 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
713 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000714 0xed, 0xcb
715};
716
717/* Sizes in bytes */
718static const size_t PRFKlen[NB_PRF_TESTS] = {
719 18,
720 16,
721 10
722};
723
Janos Follathcd13bd22016-12-13 11:51:04 +0000724/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000725static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000726 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
727 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000728 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000729};
730
731static const unsigned char PRFT[NB_PRF_TESTS][16] = {
732 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000733 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
734 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000735 },
736 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000737 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
738 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000739 },
740 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000741 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
742 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000743 }
744};
Brian Murray0f6af732016-05-19 15:59:23 -0700745#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000746
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100747static int cmac_test_subkeys(int verbose,
748 const char *testname,
749 const unsigned char *key,
750 int keybits,
751 const unsigned char *subkeys,
752 mbedtls_cipher_type_t cipher_type,
753 int block_size,
754 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100755{
Brian Murray2fab5c92016-12-15 18:51:13 -0800756 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100757 mbedtls_cipher_context_t ctx;
758 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100759 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
760 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100761
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
763 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100764 /* Failing at this point must be due to a build issue */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100766 }
767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768 for (i = 0; i < num_tests; i++) {
769 if (verbose != 0) {
770 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
771 }
Simon Butcher327398a2016-10-05 14:09:11 +0100772
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100773 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100774
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100775 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
776 if (verbose != 0) {
777 mbedtls_printf("test execution failed\n");
778 }
Simon Butcher327398a2016-10-05 14:09:11 +0100779
Janos Follathd4443582016-10-12 10:00:42 +0100780 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100781 }
782
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100783 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
784 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100785 /* When CMAC is implemented by an alternative implementation, or
786 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100787 * AES-192 may be unavailable. This should not cause the selftest
788 * function to fail. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100789 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
790 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
791 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
792 if (verbose != 0) {
793 mbedtls_printf("skipped\n");
794 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100795 goto next_test;
796 }
797
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 if (verbose != 0) {
799 mbedtls_printf("test execution failed\n");
800 }
Simon Butcher327398a2016-10-05 14:09:11 +0100801
Janos Follathd4443582016-10-12 10:00:42 +0100802 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100803 }
804
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100805 ret = cmac_generate_subkeys(&ctx, K1, K2);
806 if (ret != 0) {
807 if (verbose != 0) {
808 mbedtls_printf("failed\n");
809 }
Janos Follathd4443582016-10-12 10:00:42 +0100810
811 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100812 }
813
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100814 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
815 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
816 if (verbose != 0) {
817 mbedtls_printf("failed\n");
818 }
Janos Follathd4443582016-10-12 10:00:42 +0100819
820 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100821 }
822
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100823 if (verbose != 0) {
824 mbedtls_printf("passed\n");
825 }
Janos Follathd4443582016-10-12 10:00:42 +0100826
Steven Cooreman830d5af2021-01-08 18:01:46 +0100827next_test:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100828 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100829 }
830
Gilles Peskinedf761d52018-03-01 22:18:14 +0100831 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100832 goto exit;
833
834cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100835 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100836
Janos Follathd4443582016-10-12 10:00:42 +0100837exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100839}
840
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100841static int cmac_test_wth_cipher(int verbose,
842 const char *testname,
843 const unsigned char *key,
844 int keybits,
845 const unsigned char *messages,
846 const unsigned int message_lengths[4],
847 const unsigned char *expected_result,
848 mbedtls_cipher_type_t cipher_type,
849 int block_size,
850 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700851{
Simon Butcher327398a2016-10-05 14:09:11 +0100852 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800853 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100854 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700855
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100856 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
857 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100858 /* Failing at this point must be due to a build issue */
859 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700860 goto exit;
861 }
862
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100863 for (i = 0; i < num_tests; i++) {
864 if (verbose != 0) {
865 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
866 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700867
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100868 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
869 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100870 /* When CMAC is implemented by an alternative implementation, or
871 * the underlying primitive itself is implemented alternatively,
Steven Cooreman146e7fc2021-02-15 13:42:35 +0100872 * AES-192 and/or 3DES may be unavailable. This should not cause
873 * the selftest function to fail. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100874 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
875 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
876 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
877 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
878 if (verbose != 0) {
879 mbedtls_printf("skipped\n");
880 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100881 continue;
882 }
883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 if (verbose != 0) {
885 mbedtls_printf("failed\n");
886 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700887 goto exit;
888 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700889
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100890 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
891 if (verbose != 0) {
892 mbedtls_printf("failed\n");
893 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700894 goto exit;
895 }
896
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100897 if (verbose != 0) {
898 mbedtls_printf("passed\n");
899 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700900 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100901 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100902
Simon Butcher69283e52016-10-06 12:49:58 +0100903exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700905}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000906
Simon Butcher69283e52016-10-06 12:49:58 +0100907#if defined(MBEDTLS_AES_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100908static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700909{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000910 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000911 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100912 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 for (i = 0; i < NB_PRF_TESTS; i++) {
915 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
916 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
917 if (ret != 0 ||
918 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100919
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100920 if (verbose != 0) {
921 mbedtls_printf("failed\n");
922 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700923
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100924 return ret;
925 } else if (verbose != 0) {
926 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700927 }
928 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100929 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700930}
931#endif /* MBEDTLS_AES_C */
932
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100933int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700934{
Janos Follath24eed8d2019-11-22 13:21:35 +0000935 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100936
Simon Butcher69283e52016-10-06 12:49:58 +0100937#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100938 /* AES-128 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939 if ((ret = cmac_test_subkeys(verbose,
940 "AES 128",
941 aes_128_key,
942 128,
943 (const unsigned char *) aes_128_subkeys,
944 MBEDTLS_CIPHER_AES_128_ECB,
945 MBEDTLS_AES_BLOCK_SIZE,
946 NB_CMAC_TESTS_PER_KEY)) != 0) {
947 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100948 }
949
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100950 if ((ret = cmac_test_wth_cipher(verbose,
951 "AES 128",
952 aes_128_key,
953 128,
954 test_message,
955 aes_message_lengths,
956 (const unsigned char *) aes_128_expected_result,
957 MBEDTLS_CIPHER_AES_128_ECB,
958 MBEDTLS_AES_BLOCK_SIZE,
959 NB_CMAC_TESTS_PER_KEY)) != 0) {
960 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100961 }
962
963 /* AES-192 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100964 if ((ret = cmac_test_subkeys(verbose,
965 "AES 192",
966 aes_192_key,
967 192,
968 (const unsigned char *) aes_192_subkeys,
969 MBEDTLS_CIPHER_AES_192_ECB,
970 MBEDTLS_AES_BLOCK_SIZE,
971 NB_CMAC_TESTS_PER_KEY)) != 0) {
972 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700973 }
Brian Murray0f6af732016-05-19 15:59:23 -0700974
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100975 if ((ret = cmac_test_wth_cipher(verbose,
976 "AES 192",
977 aes_192_key,
978 192,
979 test_message,
980 aes_message_lengths,
981 (const unsigned char *) aes_192_expected_result,
982 MBEDTLS_CIPHER_AES_192_ECB,
983 MBEDTLS_AES_BLOCK_SIZE,
984 NB_CMAC_TESTS_PER_KEY)) != 0) {
985 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100986 }
987
988 /* AES-256 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100989 if ((ret = cmac_test_subkeys(verbose,
990 "AES 256",
991 aes_256_key,
992 256,
993 (const unsigned char *) aes_256_subkeys,
994 MBEDTLS_CIPHER_AES_256_ECB,
995 MBEDTLS_AES_BLOCK_SIZE,
996 NB_CMAC_TESTS_PER_KEY)) != 0) {
997 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700998 }
Brian Murray0f6af732016-05-19 15:59:23 -0700999
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000 if ((ret = cmac_test_wth_cipher(verbose,
1001 "AES 256",
1002 aes_256_key,
1003 256,
1004 test_message,
1005 aes_message_lengths,
1006 (const unsigned char *) aes_256_expected_result,
1007 MBEDTLS_CIPHER_AES_256_ECB,
1008 MBEDTLS_AES_BLOCK_SIZE,
1009 NB_CMAC_TESTS_PER_KEY)) != 0) {
1010 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001011 }
Brian Murray0f6af732016-05-19 15:59:23 -07001012#endif /* MBEDTLS_AES_C */
1013
Simon Butcher69283e52016-10-06 12:49:58 +01001014#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001015 /* 3DES 2 key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001016 if ((ret = cmac_test_subkeys(verbose,
1017 "3DES 2 key",
1018 des3_2key_key,
1019 192,
1020 (const unsigned char *) des3_2key_subkeys,
1021 MBEDTLS_CIPHER_DES_EDE3_ECB,
1022 MBEDTLS_DES3_BLOCK_SIZE,
1023 NB_CMAC_TESTS_PER_KEY)) != 0) {
1024 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001025 }
1026
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001027 if ((ret = cmac_test_wth_cipher(verbose,
1028 "3DES 2 key",
1029 des3_2key_key,
1030 192,
1031 test_message,
1032 des3_message_lengths,
1033 (const unsigned char *) des3_2key_expected_result,
1034 MBEDTLS_CIPHER_DES_EDE3_ECB,
1035 MBEDTLS_DES3_BLOCK_SIZE,
1036 NB_CMAC_TESTS_PER_KEY)) != 0) {
1037 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001038 }
Brian Murray0f6af732016-05-19 15:59:23 -07001039
Simon Butcher327398a2016-10-05 14:09:11 +01001040 /* 3DES 3 key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001041 if ((ret = cmac_test_subkeys(verbose,
1042 "3DES 3 key",
1043 des3_3key_key,
1044 192,
1045 (const unsigned char *) des3_3key_subkeys,
1046 MBEDTLS_CIPHER_DES_EDE3_ECB,
1047 MBEDTLS_DES3_BLOCK_SIZE,
1048 NB_CMAC_TESTS_PER_KEY)) != 0) {
1049 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001050 }
1051
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001052 if ((ret = cmac_test_wth_cipher(verbose,
1053 "3DES 3 key",
1054 des3_3key_key,
1055 192,
1056 test_message,
1057 des3_message_lengths,
1058 (const unsigned char *) des3_3key_expected_result,
1059 MBEDTLS_CIPHER_DES_EDE3_ECB,
1060 MBEDTLS_DES3_BLOCK_SIZE,
1061 NB_CMAC_TESTS_PER_KEY)) != 0) {
1062 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001063 }
Brian Murray0f6af732016-05-19 15:59:23 -07001064#endif /* MBEDTLS_DES_C */
1065
Simon Butcher69283e52016-10-06 12:49:58 +01001066#if defined(MBEDTLS_AES_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001067 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1068 return ret;
1069 }
Brian Murray0f6af732016-05-19 15:59:23 -07001070#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001071
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001072 if (verbose != 0) {
1073 mbedtls_printf("\n");
1074 }
Brian Murray0f6af732016-05-19 15:59:23 -07001075
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001076 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001077}
1078
Brian Murray0f6af732016-05-19 15:59:23 -07001079#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001080
1081#endif /* MBEDTLS_CMAC_C */