1817466cbSJens Wiklander /**
2817466cbSJens Wiklander * \file cmac.c
3817466cbSJens Wiklander *
4817466cbSJens Wiklander * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
5817466cbSJens Wiklander *
67901324dSJerome Forissier * Copyright The Mbed TLS Contributors
7*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8817466cbSJens Wiklander */
9817466cbSJens Wiklander
10817466cbSJens Wiklander /*
11817466cbSJens Wiklander * References:
12817466cbSJens Wiklander *
13817466cbSJens Wiklander * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
14817466cbSJens Wiklander * CMAC Mode for Authentication
15817466cbSJens Wiklander * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
16817466cbSJens Wiklander *
17817466cbSJens Wiklander * - RFC 4493 - The AES-CMAC Algorithm
18817466cbSJens Wiklander * https://tools.ietf.org/html/rfc4493
19817466cbSJens Wiklander *
20817466cbSJens Wiklander * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
21817466cbSJens Wiklander * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
22817466cbSJens Wiklander * Algorithm for the Internet Key Exchange Protocol (IKE)
23817466cbSJens Wiklander * https://tools.ietf.org/html/rfc4615
24817466cbSJens Wiklander *
25817466cbSJens Wiklander * Additional test vectors: ISO/IEC 9797-1
26817466cbSJens Wiklander *
27817466cbSJens Wiklander */
28817466cbSJens Wiklander
297901324dSJerome Forissier #include "common.h"
30817466cbSJens Wiklander
31817466cbSJens Wiklander #if defined(MBEDTLS_CMAC_C)
32817466cbSJens Wiklander
33817466cbSJens Wiklander #include "mbedtls/cmac.h"
343d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
3511fa71b9SJerome Forissier #include "mbedtls/error.h"
367901324dSJerome Forissier #include "mbedtls/platform.h"
37*b0563631STom Van Eyck #include "constant_time_internal.h"
38817466cbSJens Wiklander
39817466cbSJens Wiklander #include <string.h>
40817466cbSJens Wiklander
413d3b0591SJens Wiklander #if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
42817466cbSJens Wiklander
43817466cbSJens Wiklander /*
44817466cbSJens Wiklander * Multiplication by u in the Galois field of GF(2^n)
45817466cbSJens Wiklander *
46817466cbSJens Wiklander * As explained in NIST SP 800-38B, this can be computed:
47817466cbSJens Wiklander *
48817466cbSJens Wiklander * If MSB(p) = 0, then p = (p << 1)
49817466cbSJens Wiklander * If MSB(p) = 1, then p = (p << 1) ^ R_n
50817466cbSJens Wiklander * with R_64 = 0x1B and R_128 = 0x87
51817466cbSJens Wiklander *
52817466cbSJens Wiklander * Input and output MUST NOT point to the same buffer
53817466cbSJens Wiklander * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
54817466cbSJens Wiklander */
cmac_multiply_by_u(unsigned char * output,const unsigned char * input,size_t blocksize)55817466cbSJens Wiklander static int cmac_multiply_by_u(unsigned char *output,
56817466cbSJens Wiklander const unsigned char *input,
57817466cbSJens Wiklander size_t blocksize)
58817466cbSJens Wiklander {
59817466cbSJens Wiklander const unsigned char R_128 = 0x87;
60*b0563631STom Van Eyck unsigned char R_n;
61*b0563631STom Van Eyck uint32_t overflow = 0x00;
62817466cbSJens Wiklander int i;
63817466cbSJens Wiklander
6432b31808SJens Wiklander if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
65817466cbSJens Wiklander R_n = R_128;
66*b0563631STom Van Eyck }
67*b0563631STom Van Eyck #if defined(MBEDTLS_DES_C)
68*b0563631STom Van Eyck else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
69*b0563631STom Van Eyck const unsigned char R_64 = 0x1B;
70817466cbSJens Wiklander R_n = R_64;
71*b0563631STom Van Eyck }
72*b0563631STom Van Eyck #endif
73*b0563631STom Van Eyck else {
7432b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
75817466cbSJens Wiklander }
76817466cbSJens Wiklander
77*b0563631STom Van Eyck for (i = (int) blocksize - 4; i >= 0; i -= 4) {
78*b0563631STom Van Eyck uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
79*b0563631STom Van Eyck uint32_t new_overflow = i32 >> 31;
80*b0563631STom Van Eyck i32 = (i32 << 1) | overflow;
81*b0563631STom Van Eyck MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
82*b0563631STom Van Eyck overflow = new_overflow;
83817466cbSJens Wiklander }
84817466cbSJens Wiklander
85*b0563631STom Van Eyck R_n = (unsigned char) mbedtls_ct_uint_if_else_0(mbedtls_ct_bool(input[0] >> 7), R_n);
86*b0563631STom Van Eyck output[blocksize - 1] ^= R_n;
87817466cbSJens Wiklander
8832b31808SJens Wiklander return 0;
89817466cbSJens Wiklander }
90817466cbSJens Wiklander
91817466cbSJens Wiklander /*
92817466cbSJens Wiklander * Generate subkeys
93817466cbSJens Wiklander *
94817466cbSJens Wiklander * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
95817466cbSJens Wiklander */
cmac_generate_subkeys(mbedtls_cipher_context_t * ctx,unsigned char * K1,unsigned char * K2)96817466cbSJens Wiklander static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
97817466cbSJens Wiklander unsigned char *K1, unsigned char *K2)
98817466cbSJens Wiklander {
9911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
100*b0563631STom Van Eyck unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
101817466cbSJens Wiklander size_t olen, block_size;
102817466cbSJens Wiklander
1033d3b0591SJens Wiklander mbedtls_platform_zeroize(L, sizeof(L));
104817466cbSJens Wiklander
105*b0563631STom Van Eyck block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
106817466cbSJens Wiklander
107817466cbSJens Wiklander /* Calculate Ek(0) */
10832b31808SJens Wiklander if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
109817466cbSJens Wiklander goto exit;
11032b31808SJens Wiklander }
111817466cbSJens Wiklander
112817466cbSJens Wiklander /*
113817466cbSJens Wiklander * Generate K1 and K2
114817466cbSJens Wiklander */
11532b31808SJens Wiklander if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
116817466cbSJens Wiklander goto exit;
11732b31808SJens Wiklander }
118817466cbSJens Wiklander
11932b31808SJens Wiklander if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
120817466cbSJens Wiklander goto exit;
12132b31808SJens Wiklander }
122817466cbSJens Wiklander
123817466cbSJens Wiklander exit:
1243d3b0591SJens Wiklander mbedtls_platform_zeroize(L, sizeof(L));
125817466cbSJens Wiklander
12632b31808SJens Wiklander return ret;
127817466cbSJens Wiklander }
1283d3b0591SJens Wiklander #endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
129817466cbSJens Wiklander
1303d3b0591SJens Wiklander #if !defined(MBEDTLS_CMAC_ALT)
131817466cbSJens Wiklander
132817466cbSJens Wiklander /*
133817466cbSJens Wiklander * Create padded last block from (partial) last block.
134817466cbSJens Wiklander *
135817466cbSJens Wiklander * We can't use the padding option from the cipher layer, as it only works for
136817466cbSJens Wiklander * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
137817466cbSJens Wiklander */
cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],size_t padded_block_len,const unsigned char * last_block,size_t last_block_len)138*b0563631STom Van Eyck static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
139817466cbSJens Wiklander size_t padded_block_len,
140817466cbSJens Wiklander const unsigned char *last_block,
141817466cbSJens Wiklander size_t last_block_len)
142817466cbSJens Wiklander {
143817466cbSJens Wiklander size_t j;
144817466cbSJens Wiklander
14532b31808SJens Wiklander for (j = 0; j < padded_block_len; j++) {
14632b31808SJens Wiklander if (j < last_block_len) {
147817466cbSJens Wiklander padded_block[j] = last_block[j];
14832b31808SJens Wiklander } else if (j == last_block_len) {
149817466cbSJens Wiklander padded_block[j] = 0x80;
15032b31808SJens Wiklander } else {
151817466cbSJens Wiklander padded_block[j] = 0x00;
152817466cbSJens Wiklander }
153817466cbSJens Wiklander }
15432b31808SJens Wiklander }
155817466cbSJens Wiklander
mbedtls_cipher_cmac_setup(mbedtls_cipher_context_t * ctx)15612484fc7SEdison Ai int mbedtls_cipher_cmac_setup(mbedtls_cipher_context_t *ctx)
15712484fc7SEdison Ai {
15812484fc7SEdison Ai mbedtls_cmac_context_t *cmac_ctx;
15912484fc7SEdison Ai
16012484fc7SEdison Ai /* Allocated and initialise in the cipher context memory for the CMAC
16112484fc7SEdison Ai * context */
16212484fc7SEdison Ai cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
16312484fc7SEdison Ai if (cmac_ctx == NULL)
16432b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
16512484fc7SEdison Ai
16612484fc7SEdison Ai ctx->cmac_ctx = cmac_ctx;
16712484fc7SEdison Ai
16812484fc7SEdison Ai mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
16912484fc7SEdison Ai return 0;
17012484fc7SEdison Ai }
17112484fc7SEdison Ai
mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t * ctx,const unsigned char * key,size_t keybits)172817466cbSJens Wiklander int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
173817466cbSJens Wiklander const unsigned char *key, size_t keybits)
174817466cbSJens Wiklander {
175817466cbSJens Wiklander mbedtls_cipher_type_t type;
176817466cbSJens Wiklander int retval;
177817466cbSJens Wiklander
17832b31808SJens Wiklander if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
17932b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
18032b31808SJens Wiklander }
181817466cbSJens Wiklander
182817466cbSJens Wiklander if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
18332b31808SJens Wiklander MBEDTLS_ENCRYPT)) != 0) {
18432b31808SJens Wiklander return retval;
18532b31808SJens Wiklander }
186817466cbSJens Wiklander
187*b0563631STom Van Eyck type = mbedtls_cipher_info_get_type(ctx->cipher_info);
188817466cbSJens Wiklander
18932b31808SJens Wiklander switch (type) {
190817466cbSJens Wiklander case MBEDTLS_CIPHER_AES_128_ECB:
191817466cbSJens Wiklander case MBEDTLS_CIPHER_AES_192_ECB:
192817466cbSJens Wiklander case MBEDTLS_CIPHER_AES_256_ECB:
193817466cbSJens Wiklander case MBEDTLS_CIPHER_DES_EDE3_ECB:
194817466cbSJens Wiklander break;
195817466cbSJens Wiklander default:
19632b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
197817466cbSJens Wiklander }
198817466cbSJens Wiklander
19912484fc7SEdison Ai /* Check if cmac ctx had been allocated by mbedtls_cipher_cmac_setup() */
20012484fc7SEdison Ai if( ctx->cmac_ctx != NULL )
201817466cbSJens Wiklander return 0;
20212484fc7SEdison Ai
20312484fc7SEdison Ai return mbedtls_cipher_cmac_setup( ctx );
204817466cbSJens Wiklander }
205817466cbSJens Wiklander
mbedtls_cipher_cmac_update(mbedtls_cipher_context_t * ctx,const unsigned char * input,size_t ilen)206817466cbSJens Wiklander int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
207817466cbSJens Wiklander const unsigned char *input, size_t ilen)
208817466cbSJens Wiklander {
209817466cbSJens Wiklander mbedtls_cmac_context_t *cmac_ctx;
210817466cbSJens Wiklander unsigned char *state;
211817466cbSJens Wiklander int ret = 0;
212817466cbSJens Wiklander size_t n, j, olen, block_size;
213817466cbSJens Wiklander
214817466cbSJens Wiklander if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
21532b31808SJens Wiklander ctx->cmac_ctx == NULL) {
21632b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
21732b31808SJens Wiklander }
218817466cbSJens Wiklander
219817466cbSJens Wiklander cmac_ctx = ctx->cmac_ctx;
220*b0563631STom Van Eyck block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
221817466cbSJens Wiklander state = ctx->cmac_ctx->state;
222817466cbSJens Wiklander
223*b0563631STom Van Eyck /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
224*b0563631STom Van Eyck * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
225*b0563631STom Van Eyck MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE);
226*b0563631STom Van Eyck
227817466cbSJens Wiklander /* Is there data still to process from the last call, that's greater in
228817466cbSJens Wiklander * size than a block? */
229817466cbSJens Wiklander if (cmac_ctx->unprocessed_len > 0 &&
23032b31808SJens Wiklander ilen > block_size - cmac_ctx->unprocessed_len) {
231817466cbSJens Wiklander memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
232817466cbSJens Wiklander input,
233817466cbSJens Wiklander block_size - cmac_ctx->unprocessed_len);
234817466cbSJens Wiklander
235*b0563631STom Van Eyck mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
236817466cbSJens Wiklander
237817466cbSJens Wiklander if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
23832b31808SJens Wiklander &olen)) != 0) {
239817466cbSJens Wiklander goto exit;
240817466cbSJens Wiklander }
241817466cbSJens Wiklander
242817466cbSJens Wiklander input += block_size - cmac_ctx->unprocessed_len;
243817466cbSJens Wiklander ilen -= block_size - cmac_ctx->unprocessed_len;
244817466cbSJens Wiklander cmac_ctx->unprocessed_len = 0;
245817466cbSJens Wiklander }
246817466cbSJens Wiklander
247817466cbSJens Wiklander /* n is the number of blocks including any final partial block */
248817466cbSJens Wiklander n = (ilen + block_size - 1) / block_size;
249817466cbSJens Wiklander
250817466cbSJens Wiklander /* Iterate across the input data in block sized chunks, excluding any
251817466cbSJens Wiklander * final partial or complete block */
25232b31808SJens Wiklander for (j = 1; j < n; j++) {
253*b0563631STom Van Eyck mbedtls_xor_no_simd(state, input, state, block_size);
254817466cbSJens Wiklander
255817466cbSJens Wiklander if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
25632b31808SJens Wiklander &olen)) != 0) {
257817466cbSJens Wiklander goto exit;
25832b31808SJens Wiklander }
259817466cbSJens Wiklander
260817466cbSJens Wiklander ilen -= block_size;
261817466cbSJens Wiklander input += block_size;
262817466cbSJens Wiklander }
263817466cbSJens Wiklander
264817466cbSJens Wiklander /* If there is data left over that wasn't aligned to a block */
26532b31808SJens Wiklander if (ilen > 0) {
266817466cbSJens Wiklander memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
267817466cbSJens Wiklander input,
268817466cbSJens Wiklander ilen);
269817466cbSJens Wiklander cmac_ctx->unprocessed_len += ilen;
270817466cbSJens Wiklander }
271817466cbSJens Wiklander
272817466cbSJens Wiklander exit:
27332b31808SJens Wiklander return ret;
274817466cbSJens Wiklander }
275817466cbSJens Wiklander
mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t * ctx,unsigned char * output)276817466cbSJens Wiklander int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
277817466cbSJens Wiklander unsigned char *output)
278817466cbSJens Wiklander {
279817466cbSJens Wiklander mbedtls_cmac_context_t *cmac_ctx;
280817466cbSJens Wiklander unsigned char *state, *last_block;
281*b0563631STom Van Eyck unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
282*b0563631STom Van Eyck unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
283*b0563631STom Van Eyck unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
28411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
285817466cbSJens Wiklander size_t olen, block_size;
286817466cbSJens Wiklander
287817466cbSJens Wiklander if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
28832b31808SJens Wiklander output == NULL) {
28932b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
29032b31808SJens Wiklander }
291817466cbSJens Wiklander
292817466cbSJens Wiklander cmac_ctx = ctx->cmac_ctx;
293*b0563631STom Van Eyck block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
294*b0563631STom Van Eyck MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning
295817466cbSJens Wiklander state = cmac_ctx->state;
296817466cbSJens Wiklander
2973d3b0591SJens Wiklander mbedtls_platform_zeroize(K1, sizeof(K1));
2983d3b0591SJens Wiklander mbedtls_platform_zeroize(K2, sizeof(K2));
299817466cbSJens Wiklander cmac_generate_subkeys(ctx, K1, K2);
300817466cbSJens Wiklander
301817466cbSJens Wiklander last_block = cmac_ctx->unprocessed_block;
302817466cbSJens Wiklander
303817466cbSJens Wiklander /* Calculate last block */
30432b31808SJens Wiklander if (cmac_ctx->unprocessed_len < block_size) {
305817466cbSJens Wiklander cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
30632b31808SJens Wiklander mbedtls_xor(M_last, M_last, K2, block_size);
30732b31808SJens Wiklander } else {
308817466cbSJens Wiklander /* Last block is complete block */
30932b31808SJens Wiklander mbedtls_xor(M_last, last_block, K1, block_size);
310817466cbSJens Wiklander }
311817466cbSJens Wiklander
312817466cbSJens Wiklander
31332b31808SJens Wiklander mbedtls_xor(state, M_last, state, block_size);
314817466cbSJens Wiklander if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
31532b31808SJens Wiklander &olen)) != 0) {
316817466cbSJens Wiklander goto exit;
317817466cbSJens Wiklander }
318817466cbSJens Wiklander
319817466cbSJens Wiklander memcpy(output, state, block_size);
320817466cbSJens Wiklander
321817466cbSJens Wiklander exit:
322817466cbSJens Wiklander /* Wipe the generated keys on the stack, and any other transients to avoid
323817466cbSJens Wiklander * side channel leakage */
3243d3b0591SJens Wiklander mbedtls_platform_zeroize(K1, sizeof(K1));
3253d3b0591SJens Wiklander mbedtls_platform_zeroize(K2, sizeof(K2));
326817466cbSJens Wiklander
327817466cbSJens Wiklander cmac_ctx->unprocessed_len = 0;
3283d3b0591SJens Wiklander mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
329817466cbSJens Wiklander sizeof(cmac_ctx->unprocessed_block));
330817466cbSJens Wiklander
331*b0563631STom Van Eyck mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
33232b31808SJens Wiklander return ret;
333817466cbSJens Wiklander }
334817466cbSJens Wiklander
mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t * ctx)335817466cbSJens Wiklander int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
336817466cbSJens Wiklander {
337817466cbSJens Wiklander mbedtls_cmac_context_t *cmac_ctx;
338817466cbSJens Wiklander
33932b31808SJens Wiklander if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
34032b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
34132b31808SJens Wiklander }
342817466cbSJens Wiklander
343817466cbSJens Wiklander cmac_ctx = ctx->cmac_ctx;
344817466cbSJens Wiklander
345817466cbSJens Wiklander /* Reset the internal state */
346817466cbSJens Wiklander cmac_ctx->unprocessed_len = 0;
3473d3b0591SJens Wiklander mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
348817466cbSJens Wiklander sizeof(cmac_ctx->unprocessed_block));
3493d3b0591SJens Wiklander mbedtls_platform_zeroize(cmac_ctx->state,
350817466cbSJens Wiklander sizeof(cmac_ctx->state));
351817466cbSJens Wiklander
35232b31808SJens Wiklander return 0;
353817466cbSJens Wiklander }
354817466cbSJens Wiklander
mbedtls_cipher_cmac(const mbedtls_cipher_info_t * cipher_info,const unsigned char * key,size_t keylen,const unsigned char * input,size_t ilen,unsigned char * output)355817466cbSJens Wiklander int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
356817466cbSJens Wiklander const unsigned char *key, size_t keylen,
357817466cbSJens Wiklander const unsigned char *input, size_t ilen,
358817466cbSJens Wiklander unsigned char *output)
359817466cbSJens Wiklander {
360817466cbSJens Wiklander mbedtls_cipher_context_t ctx;
36111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
362817466cbSJens Wiklander
36332b31808SJens Wiklander if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
36432b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
36532b31808SJens Wiklander }
366817466cbSJens Wiklander
367817466cbSJens Wiklander mbedtls_cipher_init(&ctx);
368817466cbSJens Wiklander
36932b31808SJens Wiklander if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
370817466cbSJens Wiklander goto exit;
37132b31808SJens Wiklander }
372817466cbSJens Wiklander
373817466cbSJens Wiklander ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
37432b31808SJens Wiklander if (ret != 0) {
375817466cbSJens Wiklander goto exit;
37632b31808SJens Wiklander }
377817466cbSJens Wiklander
378817466cbSJens Wiklander ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
37932b31808SJens Wiklander if (ret != 0) {
380817466cbSJens Wiklander goto exit;
38132b31808SJens Wiklander }
382817466cbSJens Wiklander
383817466cbSJens Wiklander ret = mbedtls_cipher_cmac_finish(&ctx, output);
384817466cbSJens Wiklander
385817466cbSJens Wiklander exit:
386817466cbSJens Wiklander mbedtls_cipher_free(&ctx);
387817466cbSJens Wiklander
38832b31808SJens Wiklander return ret;
389817466cbSJens Wiklander }
390817466cbSJens Wiklander
391817466cbSJens Wiklander #if defined(MBEDTLS_AES_C)
392817466cbSJens Wiklander /*
393817466cbSJens Wiklander * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
394817466cbSJens Wiklander */
mbedtls_aes_cmac_prf_128(const unsigned char * key,size_t key_length,const unsigned char * input,size_t in_len,unsigned char output[16])395817466cbSJens Wiklander int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
396817466cbSJens Wiklander const unsigned char *input, size_t in_len,
3977901324dSJerome Forissier unsigned char output[16])
398817466cbSJens Wiklander {
39911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
400817466cbSJens Wiklander const mbedtls_cipher_info_t *cipher_info;
401817466cbSJens Wiklander unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
402817466cbSJens Wiklander unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
403817466cbSJens Wiklander
40432b31808SJens Wiklander if (key == NULL || input == NULL || output == NULL) {
40532b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
40632b31808SJens Wiklander }
407817466cbSJens Wiklander
408817466cbSJens Wiklander cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
40932b31808SJens Wiklander if (cipher_info == NULL) {
410817466cbSJens Wiklander /* Failing at this point must be due to a build issue */
411817466cbSJens Wiklander ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
412817466cbSJens Wiklander goto exit;
413817466cbSJens Wiklander }
414817466cbSJens Wiklander
41532b31808SJens Wiklander if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
416817466cbSJens Wiklander /* Use key as is */
417817466cbSJens Wiklander memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
41832b31808SJens Wiklander } else {
419817466cbSJens Wiklander memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
420817466cbSJens Wiklander
421817466cbSJens Wiklander ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
422817466cbSJens Wiklander key_length, int_key);
42332b31808SJens Wiklander if (ret != 0) {
424817466cbSJens Wiklander goto exit;
425817466cbSJens Wiklander }
42632b31808SJens Wiklander }
427817466cbSJens Wiklander
428817466cbSJens Wiklander ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
429817466cbSJens Wiklander output);
430817466cbSJens Wiklander
431817466cbSJens Wiklander exit:
4323d3b0591SJens Wiklander mbedtls_platform_zeroize(int_key, sizeof(int_key));
433817466cbSJens Wiklander
43432b31808SJens Wiklander return ret;
435817466cbSJens Wiklander }
436817466cbSJens Wiklander #endif /* MBEDTLS_AES_C */
437817466cbSJens Wiklander
4383d3b0591SJens Wiklander #endif /* !MBEDTLS_CMAC_ALT */
4393d3b0591SJens Wiklander
440817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
441817466cbSJens Wiklander /*
442817466cbSJens Wiklander * CMAC test data for SP800-38B
443817466cbSJens Wiklander * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
444817466cbSJens Wiklander * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
445817466cbSJens Wiklander *
446817466cbSJens Wiklander * AES-CMAC-PRF-128 test data from RFC 4615
447817466cbSJens Wiklander * https://tools.ietf.org/html/rfc4615#page-4
448817466cbSJens Wiklander */
449817466cbSJens Wiklander
450817466cbSJens Wiklander #define NB_CMAC_TESTS_PER_KEY 4
451817466cbSJens Wiklander #define NB_PRF_TESTS 3
452817466cbSJens Wiklander
453817466cbSJens Wiklander #if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
454817466cbSJens Wiklander /* All CMAC test inputs are truncated from the same 64 byte buffer. */
455817466cbSJens Wiklander static const unsigned char test_message[] = {
456817466cbSJens Wiklander /* PT */
457817466cbSJens Wiklander 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
458817466cbSJens Wiklander 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
459817466cbSJens Wiklander 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
460817466cbSJens Wiklander 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
461817466cbSJens Wiklander 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
462817466cbSJens Wiklander 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
463817466cbSJens Wiklander 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
464817466cbSJens Wiklander 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
465817466cbSJens Wiklander };
466817466cbSJens Wiklander #endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
467817466cbSJens Wiklander
468817466cbSJens Wiklander #if defined(MBEDTLS_AES_C)
469817466cbSJens Wiklander /* Truncation point of message for AES CMAC tests */
470817466cbSJens Wiklander static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
471817466cbSJens Wiklander /* Mlen */
472817466cbSJens Wiklander 0,
473817466cbSJens Wiklander 16,
474817466cbSJens Wiklander 20,
475817466cbSJens Wiklander 64
476817466cbSJens Wiklander };
477817466cbSJens Wiklander
478817466cbSJens Wiklander /* CMAC-AES128 Test Data */
479817466cbSJens Wiklander static const unsigned char aes_128_key[16] = {
480817466cbSJens Wiklander 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
481817466cbSJens Wiklander 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
482817466cbSJens Wiklander };
483817466cbSJens Wiklander static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
484817466cbSJens Wiklander {
485817466cbSJens Wiklander /* K1 */
486817466cbSJens Wiklander 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
487817466cbSJens Wiklander 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
488817466cbSJens Wiklander },
489817466cbSJens Wiklander {
490817466cbSJens Wiklander /* K2 */
491817466cbSJens Wiklander 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
492817466cbSJens Wiklander 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
493817466cbSJens Wiklander }
494817466cbSJens Wiklander };
49532b31808SJens Wiklander static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
49632b31808SJens Wiklander {
497817466cbSJens Wiklander {
498817466cbSJens Wiklander /* Example #1 */
499817466cbSJens Wiklander 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
500817466cbSJens Wiklander 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
501817466cbSJens Wiklander },
502817466cbSJens Wiklander {
503817466cbSJens Wiklander /* Example #2 */
504817466cbSJens Wiklander 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
505817466cbSJens Wiklander 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
506817466cbSJens Wiklander },
507817466cbSJens Wiklander {
508817466cbSJens Wiklander /* Example #3 */
509817466cbSJens Wiklander 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
510817466cbSJens Wiklander 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
511817466cbSJens Wiklander },
512817466cbSJens Wiklander {
513817466cbSJens Wiklander /* Example #4 */
514817466cbSJens Wiklander 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
515817466cbSJens Wiklander 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
516817466cbSJens Wiklander }
517817466cbSJens Wiklander };
518817466cbSJens Wiklander
519817466cbSJens Wiklander /* CMAC-AES192 Test Data */
520*b0563631STom Van Eyck #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
521817466cbSJens Wiklander static const unsigned char aes_192_key[24] = {
522817466cbSJens Wiklander 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
523817466cbSJens Wiklander 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
524817466cbSJens Wiklander 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
525817466cbSJens Wiklander };
526817466cbSJens Wiklander static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
527817466cbSJens Wiklander {
528817466cbSJens Wiklander /* K1 */
529817466cbSJens Wiklander 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
530817466cbSJens Wiklander 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
531817466cbSJens Wiklander },
532817466cbSJens Wiklander {
533817466cbSJens Wiklander /* K2 */
534817466cbSJens Wiklander 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
535817466cbSJens Wiklander 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
536817466cbSJens Wiklander }
537817466cbSJens Wiklander };
53832b31808SJens Wiklander static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
53932b31808SJens Wiklander {
540817466cbSJens Wiklander {
541817466cbSJens Wiklander /* Example #1 */
542817466cbSJens Wiklander 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
543817466cbSJens Wiklander 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
544817466cbSJens Wiklander },
545817466cbSJens Wiklander {
546817466cbSJens Wiklander /* Example #2 */
547817466cbSJens Wiklander 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
548817466cbSJens Wiklander 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
549817466cbSJens Wiklander },
550817466cbSJens Wiklander {
551817466cbSJens Wiklander /* Example #3 */
552817466cbSJens Wiklander 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
553817466cbSJens Wiklander 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
554817466cbSJens Wiklander },
555817466cbSJens Wiklander {
556817466cbSJens Wiklander /* Example #4 */
557817466cbSJens Wiklander 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
558817466cbSJens Wiklander 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
559817466cbSJens Wiklander }
560817466cbSJens Wiklander };
561*b0563631STom Van Eyck #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
562817466cbSJens Wiklander
563817466cbSJens Wiklander /* CMAC-AES256 Test Data */
564*b0563631STom Van Eyck #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
565817466cbSJens Wiklander static const unsigned char aes_256_key[32] = {
566817466cbSJens Wiklander 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
567817466cbSJens Wiklander 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
568817466cbSJens Wiklander 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
569817466cbSJens Wiklander 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
570817466cbSJens Wiklander };
571817466cbSJens Wiklander static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
572817466cbSJens Wiklander {
573817466cbSJens Wiklander /* K1 */
574817466cbSJens Wiklander 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
575817466cbSJens Wiklander 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
576817466cbSJens Wiklander },
577817466cbSJens Wiklander {
578817466cbSJens Wiklander /* K2 */
579817466cbSJens Wiklander 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
580817466cbSJens Wiklander 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
581817466cbSJens Wiklander }
582817466cbSJens Wiklander };
58332b31808SJens Wiklander static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
58432b31808SJens Wiklander {
585817466cbSJens Wiklander {
586817466cbSJens Wiklander /* Example #1 */
587817466cbSJens Wiklander 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
588817466cbSJens Wiklander 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
589817466cbSJens Wiklander },
590817466cbSJens Wiklander {
591817466cbSJens Wiklander /* Example #2 */
592817466cbSJens Wiklander 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
593817466cbSJens Wiklander 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
594817466cbSJens Wiklander },
595817466cbSJens Wiklander {
596817466cbSJens Wiklander /* Example #3 */
597817466cbSJens Wiklander 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
598817466cbSJens Wiklander 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
599817466cbSJens Wiklander },
600817466cbSJens Wiklander {
601817466cbSJens Wiklander /* Example #4 */
602817466cbSJens Wiklander 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
603817466cbSJens Wiklander 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
604817466cbSJens Wiklander }
605817466cbSJens Wiklander };
606*b0563631STom Van Eyck #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
607817466cbSJens Wiklander #endif /* MBEDTLS_AES_C */
608817466cbSJens Wiklander
609817466cbSJens Wiklander #if defined(MBEDTLS_DES_C)
610817466cbSJens Wiklander /* Truncation point of message for 3DES CMAC tests */
611817466cbSJens Wiklander static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
612817466cbSJens Wiklander 0,
613817466cbSJens Wiklander 16,
614817466cbSJens Wiklander 20,
615817466cbSJens Wiklander 32
616817466cbSJens Wiklander };
617817466cbSJens Wiklander
618817466cbSJens Wiklander /* CMAC-TDES (Generation) - 2 Key Test Data */
619817466cbSJens Wiklander static const unsigned char des3_2key_key[24] = {
620817466cbSJens Wiklander /* Key1 */
621817466cbSJens Wiklander 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
622817466cbSJens Wiklander /* Key2 */
623817466cbSJens Wiklander 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
624817466cbSJens Wiklander /* Key3 */
625817466cbSJens Wiklander 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
626817466cbSJens Wiklander };
627817466cbSJens Wiklander static const unsigned char des3_2key_subkeys[2][8] = {
628817466cbSJens Wiklander {
629817466cbSJens Wiklander /* K1 */
630817466cbSJens Wiklander 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
631817466cbSJens Wiklander },
632817466cbSJens Wiklander {
633817466cbSJens Wiklander /* K2 */
634817466cbSJens Wiklander 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
635817466cbSJens Wiklander }
636817466cbSJens Wiklander };
63732b31808SJens Wiklander static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
63832b31808SJens Wiklander = {
639817466cbSJens Wiklander {
640817466cbSJens Wiklander /* Sample #1 */
641817466cbSJens Wiklander 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
642817466cbSJens Wiklander },
643817466cbSJens Wiklander {
644817466cbSJens Wiklander /* Sample #2 */
645817466cbSJens Wiklander 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
646817466cbSJens Wiklander },
647817466cbSJens Wiklander {
648817466cbSJens Wiklander /* Sample #3 */
649817466cbSJens Wiklander 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
650817466cbSJens Wiklander },
651817466cbSJens Wiklander {
652817466cbSJens Wiklander /* Sample #4 */
653817466cbSJens Wiklander 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
654817466cbSJens Wiklander }
655817466cbSJens Wiklander };
656817466cbSJens Wiklander
657817466cbSJens Wiklander /* CMAC-TDES (Generation) - 3 Key Test Data */
658817466cbSJens Wiklander static const unsigned char des3_3key_key[24] = {
659817466cbSJens Wiklander /* Key1 */
660817466cbSJens Wiklander 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
661817466cbSJens Wiklander /* Key2 */
662817466cbSJens Wiklander 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
663817466cbSJens Wiklander /* Key3 */
664817466cbSJens Wiklander 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
665817466cbSJens Wiklander };
666817466cbSJens Wiklander static const unsigned char des3_3key_subkeys[2][8] = {
667817466cbSJens Wiklander {
668817466cbSJens Wiklander /* K1 */
669817466cbSJens Wiklander 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
670817466cbSJens Wiklander },
671817466cbSJens Wiklander {
672817466cbSJens Wiklander /* K2 */
673817466cbSJens Wiklander 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
674817466cbSJens Wiklander }
675817466cbSJens Wiklander };
67632b31808SJens Wiklander static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
67732b31808SJens Wiklander = {
678817466cbSJens Wiklander {
679817466cbSJens Wiklander /* Sample #1 */
680817466cbSJens Wiklander 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
681817466cbSJens Wiklander },
682817466cbSJens Wiklander {
683817466cbSJens Wiklander /* Sample #2 */
684817466cbSJens Wiklander 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
685817466cbSJens Wiklander },
686817466cbSJens Wiklander {
687817466cbSJens Wiklander /* Sample #3 */
688817466cbSJens Wiklander 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
689817466cbSJens Wiklander },
690817466cbSJens Wiklander {
691817466cbSJens Wiklander /* Sample #4 */
692817466cbSJens Wiklander 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
693817466cbSJens Wiklander }
694817466cbSJens Wiklander };
695817466cbSJens Wiklander
696817466cbSJens Wiklander #endif /* MBEDTLS_DES_C */
697817466cbSJens Wiklander
698817466cbSJens Wiklander #if defined(MBEDTLS_AES_C)
699817466cbSJens Wiklander /* AES AES-CMAC-PRF-128 Test Data */
700817466cbSJens Wiklander static const unsigned char PRFK[] = {
701817466cbSJens Wiklander /* Key */
702817466cbSJens Wiklander 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
703817466cbSJens Wiklander 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
704817466cbSJens Wiklander 0xed, 0xcb
705817466cbSJens Wiklander };
706817466cbSJens Wiklander
707817466cbSJens Wiklander /* Sizes in bytes */
708817466cbSJens Wiklander static const size_t PRFKlen[NB_PRF_TESTS] = {
709817466cbSJens Wiklander 18,
710817466cbSJens Wiklander 16,
711817466cbSJens Wiklander 10
712817466cbSJens Wiklander };
713817466cbSJens Wiklander
714817466cbSJens Wiklander /* Message */
715817466cbSJens Wiklander static const unsigned char PRFM[] = {
716817466cbSJens Wiklander 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
717817466cbSJens Wiklander 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
718817466cbSJens Wiklander 0x10, 0x11, 0x12, 0x13
719817466cbSJens Wiklander };
720817466cbSJens Wiklander
721817466cbSJens Wiklander static const unsigned char PRFT[NB_PRF_TESTS][16] = {
722817466cbSJens Wiklander {
723817466cbSJens Wiklander 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
724817466cbSJens Wiklander 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
725817466cbSJens Wiklander },
726817466cbSJens Wiklander {
727817466cbSJens Wiklander 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
728817466cbSJens Wiklander 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
729817466cbSJens Wiklander },
730817466cbSJens Wiklander {
731817466cbSJens Wiklander 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
732817466cbSJens Wiklander 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
733817466cbSJens Wiklander }
734817466cbSJens Wiklander };
735817466cbSJens Wiklander #endif /* MBEDTLS_AES_C */
736817466cbSJens Wiklander
cmac_test_subkeys(int verbose,const char * testname,const unsigned char * key,int keybits,const unsigned char * subkeys,mbedtls_cipher_type_t cipher_type,int block_size,int num_tests)737817466cbSJens Wiklander static int cmac_test_subkeys(int verbose,
738817466cbSJens Wiklander const char *testname,
739817466cbSJens Wiklander const unsigned char *key,
740817466cbSJens Wiklander int keybits,
741817466cbSJens Wiklander const unsigned char *subkeys,
742817466cbSJens Wiklander mbedtls_cipher_type_t cipher_type,
743817466cbSJens Wiklander int block_size,
744817466cbSJens Wiklander int num_tests)
745817466cbSJens Wiklander {
7463d3b0591SJens Wiklander int i, ret = 0;
747817466cbSJens Wiklander mbedtls_cipher_context_t ctx;
748817466cbSJens Wiklander const mbedtls_cipher_info_t *cipher_info;
749*b0563631STom Van Eyck unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
750*b0563631STom Van Eyck unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
751817466cbSJens Wiklander
752817466cbSJens Wiklander cipher_info = mbedtls_cipher_info_from_type(cipher_type);
75332b31808SJens Wiklander if (cipher_info == NULL) {
754817466cbSJens Wiklander /* Failing at this point must be due to a build issue */
75532b31808SJens Wiklander return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
756817466cbSJens Wiklander }
757817466cbSJens Wiklander
75832b31808SJens Wiklander for (i = 0; i < num_tests; i++) {
75932b31808SJens Wiklander if (verbose != 0) {
7607901324dSJerome Forissier mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
76132b31808SJens Wiklander }
762817466cbSJens Wiklander
763817466cbSJens Wiklander mbedtls_cipher_init(&ctx);
764817466cbSJens Wiklander
76532b31808SJens Wiklander if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
76632b31808SJens Wiklander if (verbose != 0) {
767817466cbSJens Wiklander mbedtls_printf("test execution failed\n");
76832b31808SJens Wiklander }
769817466cbSJens Wiklander
770817466cbSJens Wiklander goto cleanup;
771817466cbSJens Wiklander }
772817466cbSJens Wiklander
773817466cbSJens Wiklander if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
77432b31808SJens Wiklander MBEDTLS_ENCRYPT)) != 0) {
7757901324dSJerome Forissier /* When CMAC is implemented by an alternative implementation, or
7767901324dSJerome Forissier * the underlying primitive itself is implemented alternatively,
7777901324dSJerome Forissier * AES-192 may be unavailable. This should not cause the selftest
7787901324dSJerome Forissier * function to fail. */
7797901324dSJerome Forissier if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
7807901324dSJerome Forissier ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
7817901324dSJerome Forissier cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
78232b31808SJens Wiklander if (verbose != 0) {
7837901324dSJerome Forissier mbedtls_printf("skipped\n");
78432b31808SJens Wiklander }
7857901324dSJerome Forissier goto next_test;
7867901324dSJerome Forissier }
7877901324dSJerome Forissier
78832b31808SJens Wiklander if (verbose != 0) {
789817466cbSJens Wiklander mbedtls_printf("test execution failed\n");
79032b31808SJens Wiklander }
791817466cbSJens Wiklander
792817466cbSJens Wiklander goto cleanup;
793817466cbSJens Wiklander }
794817466cbSJens Wiklander
795817466cbSJens Wiklander ret = cmac_generate_subkeys(&ctx, K1, K2);
79632b31808SJens Wiklander if (ret != 0) {
79732b31808SJens Wiklander if (verbose != 0) {
798817466cbSJens Wiklander mbedtls_printf("failed\n");
79932b31808SJens Wiklander }
800817466cbSJens Wiklander
801817466cbSJens Wiklander goto cleanup;
802817466cbSJens Wiklander }
803817466cbSJens Wiklander
804817466cbSJens Wiklander if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
80532b31808SJens Wiklander (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
80632b31808SJens Wiklander if (verbose != 0) {
807817466cbSJens Wiklander mbedtls_printf("failed\n");
80832b31808SJens Wiklander }
809817466cbSJens Wiklander
810817466cbSJens Wiklander goto cleanup;
811817466cbSJens Wiklander }
812817466cbSJens Wiklander
81332b31808SJens Wiklander if (verbose != 0) {
814817466cbSJens Wiklander mbedtls_printf("passed\n");
81532b31808SJens Wiklander }
816817466cbSJens Wiklander
8177901324dSJerome Forissier next_test:
818817466cbSJens Wiklander mbedtls_cipher_free(&ctx);
819817466cbSJens Wiklander }
820817466cbSJens Wiklander
8213d3b0591SJens Wiklander ret = 0;
822817466cbSJens Wiklander goto exit;
823817466cbSJens Wiklander
824817466cbSJens Wiklander cleanup:
825817466cbSJens Wiklander mbedtls_cipher_free(&ctx);
826817466cbSJens Wiklander
827817466cbSJens Wiklander exit:
82832b31808SJens Wiklander return ret;
829817466cbSJens Wiklander }
830817466cbSJens Wiklander
cmac_test_wth_cipher(int verbose,const char * testname,const unsigned char * key,int keybits,const unsigned char * messages,const unsigned int message_lengths[4],const unsigned char * expected_result,mbedtls_cipher_type_t cipher_type,int block_size,int num_tests)831817466cbSJens Wiklander static int cmac_test_wth_cipher(int verbose,
832817466cbSJens Wiklander const char *testname,
833817466cbSJens Wiklander const unsigned char *key,
834817466cbSJens Wiklander int keybits,
835817466cbSJens Wiklander const unsigned char *messages,
836817466cbSJens Wiklander const unsigned int message_lengths[4],
837817466cbSJens Wiklander const unsigned char *expected_result,
838817466cbSJens Wiklander mbedtls_cipher_type_t cipher_type,
839817466cbSJens Wiklander int block_size,
840817466cbSJens Wiklander int num_tests)
841817466cbSJens Wiklander {
842817466cbSJens Wiklander const mbedtls_cipher_info_t *cipher_info;
8433d3b0591SJens Wiklander int i, ret = 0;
844*b0563631STom Van Eyck unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
845817466cbSJens Wiklander
846817466cbSJens Wiklander cipher_info = mbedtls_cipher_info_from_type(cipher_type);
84732b31808SJens Wiklander if (cipher_info == NULL) {
848817466cbSJens Wiklander /* Failing at this point must be due to a build issue */
849817466cbSJens Wiklander ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
850817466cbSJens Wiklander goto exit;
851817466cbSJens Wiklander }
852817466cbSJens Wiklander
85332b31808SJens Wiklander for (i = 0; i < num_tests; i++) {
85432b31808SJens Wiklander if (verbose != 0) {
8557901324dSJerome Forissier mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
85632b31808SJens Wiklander }
857817466cbSJens Wiklander
858817466cbSJens Wiklander if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
85932b31808SJens Wiklander message_lengths[i], output)) != 0) {
8607901324dSJerome Forissier /* When CMAC is implemented by an alternative implementation, or
8617901324dSJerome Forissier * the underlying primitive itself is implemented alternatively,
8627901324dSJerome Forissier * AES-192 and/or 3DES may be unavailable. This should not cause
8637901324dSJerome Forissier * the selftest function to fail. */
8647901324dSJerome Forissier if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
8657901324dSJerome Forissier ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
8667901324dSJerome Forissier (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
8677901324dSJerome Forissier cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
86832b31808SJens Wiklander if (verbose != 0) {
8697901324dSJerome Forissier mbedtls_printf("skipped\n");
87032b31808SJens Wiklander }
8717901324dSJerome Forissier continue;
8727901324dSJerome Forissier }
8737901324dSJerome Forissier
87432b31808SJens Wiklander if (verbose != 0) {
875817466cbSJens Wiklander mbedtls_printf("failed\n");
87632b31808SJens Wiklander }
877817466cbSJens Wiklander goto exit;
878817466cbSJens Wiklander }
879817466cbSJens Wiklander
88032b31808SJens Wiklander if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
88132b31808SJens Wiklander if (verbose != 0) {
882817466cbSJens Wiklander mbedtls_printf("failed\n");
88332b31808SJens Wiklander }
884817466cbSJens Wiklander goto exit;
885817466cbSJens Wiklander }
886817466cbSJens Wiklander
88732b31808SJens Wiklander if (verbose != 0) {
888817466cbSJens Wiklander mbedtls_printf("passed\n");
889817466cbSJens Wiklander }
89032b31808SJens Wiklander }
8913d3b0591SJens Wiklander ret = 0;
892817466cbSJens Wiklander
893817466cbSJens Wiklander exit:
89432b31808SJens Wiklander return ret;
895817466cbSJens Wiklander }
896817466cbSJens Wiklander
897817466cbSJens Wiklander #if defined(MBEDTLS_AES_C)
test_aes128_cmac_prf(int verbose)898817466cbSJens Wiklander static int test_aes128_cmac_prf(int verbose)
899817466cbSJens Wiklander {
900817466cbSJens Wiklander int i;
90111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
902817466cbSJens Wiklander unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
903817466cbSJens Wiklander
90432b31808SJens Wiklander for (i = 0; i < NB_PRF_TESTS; i++) {
9057901324dSJerome Forissier mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
906817466cbSJens Wiklander ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
907817466cbSJens Wiklander if (ret != 0 ||
90832b31808SJens Wiklander memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
909817466cbSJens Wiklander
91032b31808SJens Wiklander if (verbose != 0) {
911817466cbSJens Wiklander mbedtls_printf("failed\n");
912817466cbSJens Wiklander }
91332b31808SJens Wiklander
91432b31808SJens Wiklander return ret;
91532b31808SJens Wiklander } else if (verbose != 0) {
916817466cbSJens Wiklander mbedtls_printf("passed\n");
917817466cbSJens Wiklander }
918817466cbSJens Wiklander }
91932b31808SJens Wiklander return ret;
920817466cbSJens Wiklander }
921817466cbSJens Wiklander #endif /* MBEDTLS_AES_C */
922817466cbSJens Wiklander
mbedtls_cmac_self_test(int verbose)923817466cbSJens Wiklander int mbedtls_cmac_self_test(int verbose)
924817466cbSJens Wiklander {
92511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
926817466cbSJens Wiklander
927817466cbSJens Wiklander #if defined(MBEDTLS_AES_C)
928817466cbSJens Wiklander /* AES-128 */
929817466cbSJens Wiklander if ((ret = cmac_test_subkeys(verbose,
930817466cbSJens Wiklander "AES 128",
931817466cbSJens Wiklander aes_128_key,
932817466cbSJens Wiklander 128,
933817466cbSJens Wiklander (const unsigned char *) aes_128_subkeys,
934817466cbSJens Wiklander MBEDTLS_CIPHER_AES_128_ECB,
935817466cbSJens Wiklander MBEDTLS_AES_BLOCK_SIZE,
93632b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
93732b31808SJens Wiklander return ret;
938817466cbSJens Wiklander }
939817466cbSJens Wiklander
940817466cbSJens Wiklander if ((ret = cmac_test_wth_cipher(verbose,
941817466cbSJens Wiklander "AES 128",
942817466cbSJens Wiklander aes_128_key,
943817466cbSJens Wiklander 128,
944817466cbSJens Wiklander test_message,
945817466cbSJens Wiklander aes_message_lengths,
946817466cbSJens Wiklander (const unsigned char *) aes_128_expected_result,
947817466cbSJens Wiklander MBEDTLS_CIPHER_AES_128_ECB,
948817466cbSJens Wiklander MBEDTLS_AES_BLOCK_SIZE,
94932b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
95032b31808SJens Wiklander return ret;
951817466cbSJens Wiklander }
952817466cbSJens Wiklander
953817466cbSJens Wiklander /* AES-192 */
954*b0563631STom Van Eyck #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
955817466cbSJens Wiklander if ((ret = cmac_test_subkeys(verbose,
956817466cbSJens Wiklander "AES 192",
957817466cbSJens Wiklander aes_192_key,
958817466cbSJens Wiklander 192,
959817466cbSJens Wiklander (const unsigned char *) aes_192_subkeys,
960817466cbSJens Wiklander MBEDTLS_CIPHER_AES_192_ECB,
961817466cbSJens Wiklander MBEDTLS_AES_BLOCK_SIZE,
96232b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
96332b31808SJens Wiklander return ret;
964817466cbSJens Wiklander }
965817466cbSJens Wiklander
966817466cbSJens Wiklander if ((ret = cmac_test_wth_cipher(verbose,
967817466cbSJens Wiklander "AES 192",
968817466cbSJens Wiklander aes_192_key,
969817466cbSJens Wiklander 192,
970817466cbSJens Wiklander test_message,
971817466cbSJens Wiklander aes_message_lengths,
972817466cbSJens Wiklander (const unsigned char *) aes_192_expected_result,
973817466cbSJens Wiklander MBEDTLS_CIPHER_AES_192_ECB,
974817466cbSJens Wiklander MBEDTLS_AES_BLOCK_SIZE,
97532b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
97632b31808SJens Wiklander return ret;
977817466cbSJens Wiklander }
978*b0563631STom Van Eyck #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
979817466cbSJens Wiklander
980817466cbSJens Wiklander /* AES-256 */
981*b0563631STom Van Eyck #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
982817466cbSJens Wiklander if ((ret = cmac_test_subkeys(verbose,
983817466cbSJens Wiklander "AES 256",
984817466cbSJens Wiklander aes_256_key,
985817466cbSJens Wiklander 256,
986817466cbSJens Wiklander (const unsigned char *) aes_256_subkeys,
987817466cbSJens Wiklander MBEDTLS_CIPHER_AES_256_ECB,
988817466cbSJens Wiklander MBEDTLS_AES_BLOCK_SIZE,
98932b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
99032b31808SJens Wiklander return ret;
991817466cbSJens Wiklander }
992817466cbSJens Wiklander
993817466cbSJens Wiklander if ((ret = cmac_test_wth_cipher(verbose,
994817466cbSJens Wiklander "AES 256",
995817466cbSJens Wiklander aes_256_key,
996817466cbSJens Wiklander 256,
997817466cbSJens Wiklander test_message,
998817466cbSJens Wiklander aes_message_lengths,
999817466cbSJens Wiklander (const unsigned char *) aes_256_expected_result,
1000817466cbSJens Wiklander MBEDTLS_CIPHER_AES_256_ECB,
1001817466cbSJens Wiklander MBEDTLS_AES_BLOCK_SIZE,
100232b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
100332b31808SJens Wiklander return ret;
1004817466cbSJens Wiklander }
1005*b0563631STom Van Eyck #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1006817466cbSJens Wiklander #endif /* MBEDTLS_AES_C */
1007817466cbSJens Wiklander
1008817466cbSJens Wiklander #if defined(MBEDTLS_DES_C)
1009817466cbSJens Wiklander /* 3DES 2 key */
1010817466cbSJens Wiklander if ((ret = cmac_test_subkeys(verbose,
1011817466cbSJens Wiklander "3DES 2 key",
1012817466cbSJens Wiklander des3_2key_key,
1013817466cbSJens Wiklander 192,
1014817466cbSJens Wiklander (const unsigned char *) des3_2key_subkeys,
1015817466cbSJens Wiklander MBEDTLS_CIPHER_DES_EDE3_ECB,
1016817466cbSJens Wiklander MBEDTLS_DES3_BLOCK_SIZE,
101732b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
101832b31808SJens Wiklander return ret;
1019817466cbSJens Wiklander }
1020817466cbSJens Wiklander
1021817466cbSJens Wiklander if ((ret = cmac_test_wth_cipher(verbose,
1022817466cbSJens Wiklander "3DES 2 key",
1023817466cbSJens Wiklander des3_2key_key,
1024817466cbSJens Wiklander 192,
1025817466cbSJens Wiklander test_message,
1026817466cbSJens Wiklander des3_message_lengths,
1027817466cbSJens Wiklander (const unsigned char *) des3_2key_expected_result,
1028817466cbSJens Wiklander MBEDTLS_CIPHER_DES_EDE3_ECB,
1029817466cbSJens Wiklander MBEDTLS_DES3_BLOCK_SIZE,
103032b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
103132b31808SJens Wiklander return ret;
1032817466cbSJens Wiklander }
1033817466cbSJens Wiklander
1034817466cbSJens Wiklander /* 3DES 3 key */
1035817466cbSJens Wiklander if ((ret = cmac_test_subkeys(verbose,
1036817466cbSJens Wiklander "3DES 3 key",
1037817466cbSJens Wiklander des3_3key_key,
1038817466cbSJens Wiklander 192,
1039817466cbSJens Wiklander (const unsigned char *) des3_3key_subkeys,
1040817466cbSJens Wiklander MBEDTLS_CIPHER_DES_EDE3_ECB,
1041817466cbSJens Wiklander MBEDTLS_DES3_BLOCK_SIZE,
104232b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
104332b31808SJens Wiklander return ret;
1044817466cbSJens Wiklander }
1045817466cbSJens Wiklander
1046817466cbSJens Wiklander if ((ret = cmac_test_wth_cipher(verbose,
1047817466cbSJens Wiklander "3DES 3 key",
1048817466cbSJens Wiklander des3_3key_key,
1049817466cbSJens Wiklander 192,
1050817466cbSJens Wiklander test_message,
1051817466cbSJens Wiklander des3_message_lengths,
1052817466cbSJens Wiklander (const unsigned char *) des3_3key_expected_result,
1053817466cbSJens Wiklander MBEDTLS_CIPHER_DES_EDE3_ECB,
1054817466cbSJens Wiklander MBEDTLS_DES3_BLOCK_SIZE,
105532b31808SJens Wiklander NB_CMAC_TESTS_PER_KEY)) != 0) {
105632b31808SJens Wiklander return ret;
1057817466cbSJens Wiklander }
1058817466cbSJens Wiklander #endif /* MBEDTLS_DES_C */
1059817466cbSJens Wiklander
1060817466cbSJens Wiklander #if defined(MBEDTLS_AES_C)
106132b31808SJens Wiklander if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
106232b31808SJens Wiklander return ret;
106332b31808SJens Wiklander }
1064817466cbSJens Wiklander #endif /* MBEDTLS_AES_C */
1065817466cbSJens Wiklander
106632b31808SJens Wiklander if (verbose != 0) {
1067817466cbSJens Wiklander mbedtls_printf("\n");
106832b31808SJens Wiklander }
1069817466cbSJens Wiklander
107032b31808SJens Wiklander return 0;
1071817466cbSJens Wiklander }
1072817466cbSJens Wiklander
1073817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
1074817466cbSJens Wiklander
1075817466cbSJens Wiklander #endif /* MBEDTLS_CMAC_C */
1076