blob: 7d90ad2f5fa7862eddd3677d6c0cf54bd24e39f8 [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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +010076 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070077 R_n = R_128;
Gilles Peskine449bd832023-01-11 14:50:10 +010078 } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070079 R_n = R_64;
Gilles Peskine449bd832023-01-11 14:50:10 +010080 } else {
81 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070082 }
83
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100103 output[blocksize - 1] ^= R_n & mask;
Simon Butcher327398a2016-10-05 14:09:11 +0100104
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100125 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700126 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100132 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700133 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100137 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 }
Simon Butcher327398a2016-10-05 14:09:11 +0100139
140exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +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)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000148
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000149/*
150 * Create padded last block from (partial) last block.
151 *
152 * We can't use the padding option from the cipher layer, as it only works for
153 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
154 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100155static void cmac_pad(unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
156 size_t padded_block_len,
157 const unsigned char *last_block,
158 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000159{
160 size_t j;
161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 for (j = 0; j < padded_block_len; j++) {
163 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000164 padded_block[j] = last_block[j];
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000166 padded_block[j] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000168 padded_block[j] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000170 }
171}
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
174 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000175{
Simon Butcher327398a2016-10-05 14:09:11 +0100176 mbedtls_cipher_type_t type;
177 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100178 int retval;
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
181 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
182 }
Simon Butcher327398a2016-10-05 14:09:11 +0100183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
185 MBEDTLS_ENCRYPT)) != 0) {
186 return retval;
187 }
Simon Butcher327398a2016-10-05 14:09:11 +0100188
Simon Butcher327398a2016-10-05 14:09:11 +0100189 type = ctx->cipher_info->type;
190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100192 case MBEDTLS_CIPHER_AES_128_ECB:
193 case MBEDTLS_CIPHER_AES_192_ECB:
194 case MBEDTLS_CIPHER_AES_256_ECB:
195 case MBEDTLS_CIPHER_DES_EDE3_ECB:
196 break;
197 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100199 }
200
201 /* Allocated and initialise in the cipher context memory for the CMAC
202 * context */
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
204 if (cmac_ctx == NULL) {
205 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
206 }
Simon Butcher327398a2016-10-05 14:09:11 +0100207
208 ctx->cmac_ctx = cmac_ctx;
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100211
212 return 0;
213}
214
Gilles Peskine449bd832023-01-11 14:50:10 +0100215int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
216 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100217{
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700219 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000220 int ret = 0;
221 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
224 ctx->cmac_ctx == NULL) {
225 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
226 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700227
Simon Butcher327398a2016-10-05 14:09:11 +0100228 cmac_ctx = ctx->cmac_ctx;
229 block_size = ctx->cipher_info->block_size;
230 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000231
Simon Butcher6b0774a2016-10-10 21:37:42 +0100232 /* Is there data still to process from the last call, that's greater in
233 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 if (cmac_ctx->unprocessed_len > 0 &&
235 ilen > block_size - cmac_ctx->unprocessed_len) {
236 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
237 input,
238 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 mbedtls_xor(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
243 &olen)) != 0) {
244 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100245 }
246
Simon Butcher6b0774a2016-10-10 21:37:42 +0100247 input += block_size - cmac_ctx->unprocessed_len;
248 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100249 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700250 }
251
Simon Butcher327398a2016-10-05 14:09:11 +0100252 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100254
Simon B3249cb72016-11-03 01:11:37 +0000255 /* Iterate across the input data in block sized chunks, excluding any
256 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 for (j = 1; j < n; j++) {
258 mbedtls_xor(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
261 &olen)) != 0) {
262 goto exit;
263 }
Simon Butcher327398a2016-10-05 14:09:11 +0100264
265 ilen -= block_size;
266 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700267 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000268
Simon Butcher327398a2016-10-05 14:09:11 +0100269 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 if (ilen > 0) {
271 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
272 input,
273 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100274 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100275 }
276
277exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100279}
280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
282 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100283{
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100285 unsigned char *state, *last_block;
286 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
287 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
288 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Janos Follath24eed8d2019-11-22 13:21:35 +0000289 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100290 size_t olen, block_size;
291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
293 output == NULL) {
294 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
295 }
Simon Butcher327398a2016-10-05 14:09:11 +0100296
297 cmac_ctx = ctx->cmac_ctx;
298 block_size = ctx->cipher_info->block_size;
299 state = cmac_ctx->state;
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_platform_zeroize(K1, sizeof(K1));
302 mbedtls_platform_zeroize(K2, sizeof(K2));
303 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100304
Simon Butcher69283e52016-10-06 12:49:58 +0100305 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000306
307 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 if (cmac_ctx->unprocessed_len < block_size) {
309 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
310 mbedtls_xor(M_last, M_last, K2, block_size);
311 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000312 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000314 }
315
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_xor(state, M_last, state, block_size);
318 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
319 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100320 goto exit;
321 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100324
325exit:
326 /* Wipe the generated keys on the stack, and any other transients to avoid
327 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 mbedtls_platform_zeroize(K1, sizeof(K1));
329 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100330
331 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
333 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 mbedtls_platform_zeroize(state, MBEDTLS_CIPHER_BLKSIZE_MAX);
336 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000337}
338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000340{
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
344 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
345 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700346
Simon Butcher327398a2016-10-05 14:09:11 +0100347 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000348
Simon Butcher327398a2016-10-05 14:09:11 +0100349 /* Reset the internal state */
350 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
352 sizeof(cmac_ctx->unprocessed_block));
353 mbedtls_platform_zeroize(cmac_ctx->state,
354 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000357}
358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
360 const unsigned char *key, size_t keylen,
361 const unsigned char *input, size_t ilen,
362 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100363{
364 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
368 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
369 }
Simon Butcher327398a2016-10-05 14:09:11 +0100370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100374 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 }
Simon Butcher327398a2016-10-05 14:09:11 +0100376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
378 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100379 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 }
Simon Butcher327398a2016-10-05 14:09:11 +0100381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
383 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100384 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 }
Simon Butcher327398a2016-10-05 14:09:11 +0100386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100388
389exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100393}
Simon Butcher327398a2016-10-05 14:09:11 +0100394
Simon Butcher69283e52016-10-06 12:49:58 +0100395#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000396/*
Simon Butcher69283e52016-10-06 12:49:58 +0100397 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000398 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100399int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
400 const unsigned char *input, size_t in_len,
401 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000402{
Janos Follath24eed8d2019-11-22 13:21:35 +0000403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100404 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100405 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
406 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 if (key == NULL || input == NULL || output == NULL) {
409 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
410 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
413 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100414 /* Failing at this point must be due to a build issue */
415 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
416 goto exit;
417 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000420 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
422 } else {
423 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
426 key_length, int_key);
427 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700428 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000430 }
431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
433 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000434
Simon Butcher327398a2016-10-05 14:09:11 +0100435exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000439}
Brian Murrayb439d452016-05-19 16:02:42 -0700440#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000441
Steven Cooreman63342772017-04-04 11:47:16 +0200442#endif /* !MBEDTLS_CMAC_ALT */
443
Simon Butcher69283e52016-10-06 12:49:58 +0100444#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000445/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000446 * CMAC test data for SP800-38B
447 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
448 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700449 *
450 * AES-CMAC-PRF-128 test data from RFC 4615
451 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000452 */
453
Brian Murray0f6af732016-05-19 15:59:23 -0700454#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000455#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100456
Brian Murray0f6af732016-05-19 15:59:23 -0700457#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
458/* All CMAC test inputs are truncated from the same 64 byte buffer. */
459static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000460 /* PT */
461 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
462 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
463 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
464 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
465 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
466 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
467 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
468 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000469};
Simon Butcher69283e52016-10-06 12:49:58 +0100470#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700471
Simon Butcher69283e52016-10-06 12:49:58 +0100472#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700473/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700474static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000475 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700476 0,
477 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000478 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700479 64
480};
481
Janos Follathcd13bd22016-12-13 11:51:04 +0000482/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700483static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000484 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
485 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700486};
Simon Butcher69283e52016-10-06 12:49:58 +0100487static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700488 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000489 /* K1 */
490 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
491 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700492 },
493 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000494 /* K2 */
495 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
496 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700497 }
498};
Gilles Peskine449bd832023-01-11 14:50:10 +0100499static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
500{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000502 /* Example #1 */
503 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
504 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000505 },
506 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000507 /* Example #2 */
508 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
509 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000510 },
511 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000512 /* Example #3 */
513 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
514 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000515 },
516 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000517 /* Example #4 */
518 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
519 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000520 }
521};
522
Janos Follathcd13bd22016-12-13 11:51:04 +0000523/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700524static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000525 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
526 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
527 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000528};
Simon Butcher69283e52016-10-06 12:49:58 +0100529static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700530 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000531 /* K1 */
532 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
533 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700534 },
535 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000536 /* K2 */
537 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
538 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700539 }
540};
Gilles Peskine449bd832023-01-11 14:50:10 +0100541static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
542{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700543 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000544 /* Example #1 */
545 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
546 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700547 },
548 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000549 /* Example #2 */
550 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
551 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700552 },
553 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000554 /* Example #3 */
555 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
556 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700557 },
558 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000559 /* Example #4 */
560 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
561 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700562 }
563};
564
Janos Follathcd13bd22016-12-13 11:51:04 +0000565/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700566static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000567 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
568 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
569 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
570 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700571};
Simon Butcher69283e52016-10-06 12:49:58 +0100572static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700573 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000574 /* K1 */
575 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
576 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700577 },
578 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000579 /* K2 */
580 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
581 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700582 }
583};
Gilles Peskine449bd832023-01-11 14:50:10 +0100584static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
585{
Brian Murray0f6af732016-05-19 15:59:23 -0700586 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000587 /* Example #1 */
588 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
589 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700590 },
591 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000592 /* Example #2 */
593 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
594 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700595 },
596 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000597 /* Example #3 */
598 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
599 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700600 },
601 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000602 /* Example #4 */
603 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
604 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700605 }
606};
607#endif /* MBEDTLS_AES_C */
608
Simon Butcher69283e52016-10-06 12:49:58 +0100609#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700610/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700611static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700612 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000613 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700614 20,
615 32
616};
617
Janos Follathcd13bd22016-12-13 11:51:04 +0000618/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700619static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000620 /* Key1 */
621 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
622 /* Key2 */
623 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
624 /* Key3 */
625 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700626};
627static const unsigned char des3_2key_subkeys[2][8] = {
628 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000629 /* K1 */
630 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700631 },
632 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000633 /* K2 */
634 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700635 }
636};
Gilles Peskine449bd832023-01-11 14:50:10 +0100637static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
638 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700639 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000640 /* Sample #1 */
641 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700642 },
643 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000644 /* Sample #2 */
645 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700646 },
647 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000648 /* Sample #3 */
649 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700650 },
651 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000652 /* Sample #4 */
653 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700654 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700656
Janos Follathcd13bd22016-12-13 11:51:04 +0000657/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700658static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000659 /* Key1 */
660 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
661 /* Key2 */
662 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
663 /* Key3 */
664 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700665};
666static const unsigned char des3_3key_subkeys[2][8] = {
667 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000668 /* K1 */
669 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700670 },
671 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000672 /* K2 */
673 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700674 }
675};
Gilles Peskine449bd832023-01-11 14:50:10 +0100676static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
677 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700678 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000679 /* Sample #1 */
680 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700681 },
682 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000683 /* Sample #2 */
684 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700685 },
686 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000687 /* Sample #3 */
688 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700689 },
690 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000691 /* Sample #4 */
692 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700693 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700695
Brian Murray0f6af732016-05-19 15:59:23 -0700696#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700697
Simon Butcher69283e52016-10-06 12:49:58 +0100698#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700699/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000700static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000701 /* Key */
702 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
703 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000704 0xed, 0xcb
705};
706
707/* Sizes in bytes */
708static const size_t PRFKlen[NB_PRF_TESTS] = {
709 18,
710 16,
711 10
712};
713
Janos Follathcd13bd22016-12-13 11:51:04 +0000714/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000715static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000716 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
717 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000718 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000719};
720
721static const unsigned char PRFT[NB_PRF_TESTS][16] = {
722 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000723 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
724 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000725 },
726 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000727 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
728 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000729 },
730 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000731 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
732 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000733 }
734};
Brian Murray0f6af732016-05-19 15:59:23 -0700735#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737static int cmac_test_subkeys(int verbose,
738 const char *testname,
739 const unsigned char *key,
740 int keybits,
741 const unsigned char *subkeys,
742 mbedtls_cipher_type_t cipher_type,
743 int block_size,
744 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100745{
Brian Murray2fab5c92016-12-15 18:51:13 -0800746 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100747 mbedtls_cipher_context_t ctx;
748 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100749 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
750 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
753 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100754 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100756 }
757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 for (i = 0; i < num_tests; i++) {
759 if (verbose != 0) {
760 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
761 }
Simon Butcher327398a2016-10-05 14:09:11 +0100762
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
766 if (verbose != 0) {
767 mbedtls_printf("test execution failed\n");
768 }
Simon Butcher327398a2016-10-05 14:09:11 +0100769
Janos Follathd4443582016-10-12 10:00:42 +0100770 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100771 }
772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
774 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100775 /* When CMAC is implemented by an alternative implementation, or
776 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100777 * AES-192 may be unavailable. This should not cause the selftest
778 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
780 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
781 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
782 if (verbose != 0) {
783 mbedtls_printf("skipped\n");
784 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100785 goto next_test;
786 }
787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 if (verbose != 0) {
789 mbedtls_printf("test execution failed\n");
790 }
Simon Butcher327398a2016-10-05 14:09:11 +0100791
Janos Follathd4443582016-10-12 10:00:42 +0100792 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100793 }
794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 ret = cmac_generate_subkeys(&ctx, K1, K2);
796 if (ret != 0) {
797 if (verbose != 0) {
798 mbedtls_printf("failed\n");
799 }
Janos Follathd4443582016-10-12 10:00:42 +0100800
801 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100802 }
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
805 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
806 if (verbose != 0) {
807 mbedtls_printf("failed\n");
808 }
Janos Follathd4443582016-10-12 10:00:42 +0100809
810 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100811 }
812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 if (verbose != 0) {
814 mbedtls_printf("passed\n");
815 }
Janos Follathd4443582016-10-12 10:00:42 +0100816
Steven Cooreman830d5af2021-01-08 18:01:46 +0100817next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100819 }
820
Gilles Peskinedf761d52018-03-01 22:18:14 +0100821 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100822 goto exit;
823
824cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100826
Janos Follathd4443582016-10-12 10:00:42 +0100827exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100829}
830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831static int cmac_test_wth_cipher(int verbose,
832 const char *testname,
833 const unsigned char *key,
834 int keybits,
835 const unsigned char *messages,
836 const unsigned int message_lengths[4],
837 const unsigned char *expected_result,
838 mbedtls_cipher_type_t cipher_type,
839 int block_size,
840 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700841{
Simon Butcher327398a2016-10-05 14:09:11 +0100842 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800843 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100844 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
847 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100848 /* Failing at this point must be due to a build issue */
849 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700850 goto exit;
851 }
852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 for (i = 0; i < num_tests; i++) {
854 if (verbose != 0) {
855 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
856 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
859 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100860 /* When CMAC is implemented by an alternative implementation, or
861 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100862 * AES-192 and/or 3DES may be unavailable. This should not cause
863 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
865 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
866 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
867 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
868 if (verbose != 0) {
869 mbedtls_printf("skipped\n");
870 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100871 continue;
872 }
873
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 if (verbose != 0) {
875 mbedtls_printf("failed\n");
876 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700877 goto exit;
878 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
881 if (verbose != 0) {
882 mbedtls_printf("failed\n");
883 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700884 goto exit;
885 }
886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 if (verbose != 0) {
888 mbedtls_printf("passed\n");
889 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700890 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100891 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100892
Simon Butcher69283e52016-10-06 12:49:58 +0100893exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700895}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000896
Simon Butcher69283e52016-10-06 12:49:58 +0100897#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100898static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700899{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000900 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000901 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100902 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 for (i = 0; i < NB_PRF_TESTS; i++) {
905 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
906 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
907 if (ret != 0 ||
908 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 if (verbose != 0) {
911 mbedtls_printf("failed\n");
912 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 return ret;
915 } else if (verbose != 0) {
916 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700917 }
918 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700920}
921#endif /* MBEDTLS_AES_C */
922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700924{
Janos Follath24eed8d2019-11-22 13:21:35 +0000925 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100926
Simon Butcher69283e52016-10-06 12:49:58 +0100927#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100928 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 if ((ret = cmac_test_subkeys(verbose,
930 "AES 128",
931 aes_128_key,
932 128,
933 (const unsigned char *) aes_128_subkeys,
934 MBEDTLS_CIPHER_AES_128_ECB,
935 MBEDTLS_AES_BLOCK_SIZE,
936 NB_CMAC_TESTS_PER_KEY)) != 0) {
937 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100938 }
939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 if ((ret = cmac_test_wth_cipher(verbose,
941 "AES 128",
942 aes_128_key,
943 128,
944 test_message,
945 aes_message_lengths,
946 (const unsigned char *) aes_128_expected_result,
947 MBEDTLS_CIPHER_AES_128_ECB,
948 MBEDTLS_AES_BLOCK_SIZE,
949 NB_CMAC_TESTS_PER_KEY)) != 0) {
950 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100951 }
952
953 /* AES-192 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 if ((ret = cmac_test_subkeys(verbose,
955 "AES 192",
956 aes_192_key,
957 192,
958 (const unsigned char *) aes_192_subkeys,
959 MBEDTLS_CIPHER_AES_192_ECB,
960 MBEDTLS_AES_BLOCK_SIZE,
961 NB_CMAC_TESTS_PER_KEY)) != 0) {
962 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700963 }
Brian Murray0f6af732016-05-19 15:59:23 -0700964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 if ((ret = cmac_test_wth_cipher(verbose,
966 "AES 192",
967 aes_192_key,
968 192,
969 test_message,
970 aes_message_lengths,
971 (const unsigned char *) aes_192_expected_result,
972 MBEDTLS_CIPHER_AES_192_ECB,
973 MBEDTLS_AES_BLOCK_SIZE,
974 NB_CMAC_TESTS_PER_KEY)) != 0) {
975 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100976 }
977
978 /* AES-256 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if ((ret = cmac_test_subkeys(verbose,
980 "AES 256",
981 aes_256_key,
982 256,
983 (const unsigned char *) aes_256_subkeys,
984 MBEDTLS_CIPHER_AES_256_ECB,
985 MBEDTLS_AES_BLOCK_SIZE,
986 NB_CMAC_TESTS_PER_KEY)) != 0) {
987 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700988 }
Brian Murray0f6af732016-05-19 15:59:23 -0700989
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 if ((ret = cmac_test_wth_cipher(verbose,
991 "AES 256",
992 aes_256_key,
993 256,
994 test_message,
995 aes_message_lengths,
996 (const unsigned char *) aes_256_expected_result,
997 MBEDTLS_CIPHER_AES_256_ECB,
998 MBEDTLS_AES_BLOCK_SIZE,
999 NB_CMAC_TESTS_PER_KEY)) != 0) {
1000 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001001 }
Brian Murray0f6af732016-05-19 15:59:23 -07001002#endif /* MBEDTLS_AES_C */
1003
Simon Butcher69283e52016-10-06 12:49:58 +01001004#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001005 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 if ((ret = cmac_test_subkeys(verbose,
1007 "3DES 2 key",
1008 des3_2key_key,
1009 192,
1010 (const unsigned char *) des3_2key_subkeys,
1011 MBEDTLS_CIPHER_DES_EDE3_ECB,
1012 MBEDTLS_DES3_BLOCK_SIZE,
1013 NB_CMAC_TESTS_PER_KEY)) != 0) {
1014 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001015 }
1016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if ((ret = cmac_test_wth_cipher(verbose,
1018 "3DES 2 key",
1019 des3_2key_key,
1020 192,
1021 test_message,
1022 des3_message_lengths,
1023 (const unsigned char *) des3_2key_expected_result,
1024 MBEDTLS_CIPHER_DES_EDE3_ECB,
1025 MBEDTLS_DES3_BLOCK_SIZE,
1026 NB_CMAC_TESTS_PER_KEY)) != 0) {
1027 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001028 }
Brian Murray0f6af732016-05-19 15:59:23 -07001029
Simon Butcher327398a2016-10-05 14:09:11 +01001030 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 if ((ret = cmac_test_subkeys(verbose,
1032 "3DES 3 key",
1033 des3_3key_key,
1034 192,
1035 (const unsigned char *) des3_3key_subkeys,
1036 MBEDTLS_CIPHER_DES_EDE3_ECB,
1037 MBEDTLS_DES3_BLOCK_SIZE,
1038 NB_CMAC_TESTS_PER_KEY)) != 0) {
1039 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001040 }
1041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 if ((ret = cmac_test_wth_cipher(verbose,
1043 "3DES 3 key",
1044 des3_3key_key,
1045 192,
1046 test_message,
1047 des3_message_lengths,
1048 (const unsigned char *) des3_3key_expected_result,
1049 MBEDTLS_CIPHER_DES_EDE3_ECB,
1050 MBEDTLS_DES3_BLOCK_SIZE,
1051 NB_CMAC_TESTS_PER_KEY)) != 0) {
1052 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001053 }
Brian Murray0f6af732016-05-19 15:59:23 -07001054#endif /* MBEDTLS_DES_C */
1055
Simon Butcher69283e52016-10-06 12:49:58 +01001056#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1058 return ret;
1059 }
Brian Murray0f6af732016-05-19 15:59:23 -07001060#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 if (verbose != 0) {
1063 mbedtls_printf("\n");
1064 }
Brian Murray0f6af732016-05-19 15:59:23 -07001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001067}
1068
Brian Murray0f6af732016-05-19 15:59:23 -07001069#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001070
1071#endif /* MBEDTLS_CMAC_C */