1a8e1175bSopenharmony_ci/**
2a8e1175bSopenharmony_ci * \file cmac.c
3a8e1175bSopenharmony_ci *
4a8e1175bSopenharmony_ci * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
5a8e1175bSopenharmony_ci *
6a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
7a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8a8e1175bSopenharmony_ci */
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci/*
11a8e1175bSopenharmony_ci * References:
12a8e1175bSopenharmony_ci *
13a8e1175bSopenharmony_ci * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
14a8e1175bSopenharmony_ci *      CMAC Mode for Authentication
15a8e1175bSopenharmony_ci *   http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
16a8e1175bSopenharmony_ci *
17a8e1175bSopenharmony_ci * - RFC 4493 - The AES-CMAC Algorithm
18a8e1175bSopenharmony_ci *   https://tools.ietf.org/html/rfc4493
19a8e1175bSopenharmony_ci *
20a8e1175bSopenharmony_ci * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
21a8e1175bSopenharmony_ci *      Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
22a8e1175bSopenharmony_ci *      Algorithm for the Internet Key Exchange Protocol (IKE)
23a8e1175bSopenharmony_ci *   https://tools.ietf.org/html/rfc4615
24a8e1175bSopenharmony_ci *
25a8e1175bSopenharmony_ci *   Additional test vectors: ISO/IEC 9797-1
26a8e1175bSopenharmony_ci *
27a8e1175bSopenharmony_ci */
28a8e1175bSopenharmony_ci
29a8e1175bSopenharmony_ci#include "common.h"
30a8e1175bSopenharmony_ci
31a8e1175bSopenharmony_ci#if defined(MBEDTLS_CMAC_C)
32a8e1175bSopenharmony_ci
33a8e1175bSopenharmony_ci#include "mbedtls/cmac.h"
34a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h"
35a8e1175bSopenharmony_ci#include "mbedtls/error.h"
36a8e1175bSopenharmony_ci#include "mbedtls/platform.h"
37a8e1175bSopenharmony_ci#include "constant_time_internal.h"
38a8e1175bSopenharmony_ci
39a8e1175bSopenharmony_ci#include <string.h>
40a8e1175bSopenharmony_ci
41a8e1175bSopenharmony_ci#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
42a8e1175bSopenharmony_ci
43a8e1175bSopenharmony_ci/*
44a8e1175bSopenharmony_ci * Multiplication by u in the Galois field of GF(2^n)
45a8e1175bSopenharmony_ci *
46a8e1175bSopenharmony_ci * As explained in NIST SP 800-38B, this can be computed:
47a8e1175bSopenharmony_ci *
48a8e1175bSopenharmony_ci *   If MSB(p) = 0, then p = (p << 1)
49a8e1175bSopenharmony_ci *   If MSB(p) = 1, then p = (p << 1) ^ R_n
50a8e1175bSopenharmony_ci *   with R_64 = 0x1B and  R_128 = 0x87
51a8e1175bSopenharmony_ci *
52a8e1175bSopenharmony_ci * Input and output MUST NOT point to the same buffer
53a8e1175bSopenharmony_ci * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
54a8e1175bSopenharmony_ci */
55a8e1175bSopenharmony_cistatic int cmac_multiply_by_u(unsigned char *output,
56a8e1175bSopenharmony_ci                              const unsigned char *input,
57a8e1175bSopenharmony_ci                              size_t blocksize)
58a8e1175bSopenharmony_ci{
59a8e1175bSopenharmony_ci    const unsigned char R_128 = 0x87;
60a8e1175bSopenharmony_ci    unsigned char R_n;
61a8e1175bSopenharmony_ci    uint32_t overflow = 0x00;
62a8e1175bSopenharmony_ci    int i;
63a8e1175bSopenharmony_ci
64a8e1175bSopenharmony_ci    if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
65a8e1175bSopenharmony_ci        R_n = R_128;
66a8e1175bSopenharmony_ci    }
67a8e1175bSopenharmony_ci#if defined(MBEDTLS_DES_C)
68a8e1175bSopenharmony_ci    else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
69a8e1175bSopenharmony_ci        const unsigned char R_64 = 0x1B;
70a8e1175bSopenharmony_ci        R_n = R_64;
71a8e1175bSopenharmony_ci    }
72a8e1175bSopenharmony_ci#endif
73a8e1175bSopenharmony_ci    else {
74a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
75a8e1175bSopenharmony_ci    }
76a8e1175bSopenharmony_ci
77a8e1175bSopenharmony_ci    for (i = (int) blocksize - 4; i >= 0; i -= 4) {
78a8e1175bSopenharmony_ci        uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
79a8e1175bSopenharmony_ci        uint32_t new_overflow = i32 >> 31;
80a8e1175bSopenharmony_ci        i32 = (i32 << 1) | overflow;
81a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
82a8e1175bSopenharmony_ci        overflow = new_overflow;
83a8e1175bSopenharmony_ci    }
84a8e1175bSopenharmony_ci
85a8e1175bSopenharmony_ci    R_n = (unsigned char) mbedtls_ct_uint_if_else_0(mbedtls_ct_bool(input[0] >> 7), R_n);
86a8e1175bSopenharmony_ci    output[blocksize - 1] ^= R_n;
87a8e1175bSopenharmony_ci
88a8e1175bSopenharmony_ci    return 0;
89a8e1175bSopenharmony_ci}
90a8e1175bSopenharmony_ci
91a8e1175bSopenharmony_ci/*
92a8e1175bSopenharmony_ci * Generate subkeys
93a8e1175bSopenharmony_ci *
94a8e1175bSopenharmony_ci * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
95a8e1175bSopenharmony_ci */
96a8e1175bSopenharmony_cistatic int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
97a8e1175bSopenharmony_ci                                 unsigned char *K1, unsigned char *K2)
98a8e1175bSopenharmony_ci{
99a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
100a8e1175bSopenharmony_ci    unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
101a8e1175bSopenharmony_ci    size_t olen, block_size;
102a8e1175bSopenharmony_ci
103a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(L, sizeof(L));
104a8e1175bSopenharmony_ci
105a8e1175bSopenharmony_ci    block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
106a8e1175bSopenharmony_ci
107a8e1175bSopenharmony_ci    /* Calculate Ek(0) */
108a8e1175bSopenharmony_ci    if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
109a8e1175bSopenharmony_ci        goto exit;
110a8e1175bSopenharmony_ci    }
111a8e1175bSopenharmony_ci
112a8e1175bSopenharmony_ci    /*
113a8e1175bSopenharmony_ci     * Generate K1 and K2
114a8e1175bSopenharmony_ci     */
115a8e1175bSopenharmony_ci    if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
116a8e1175bSopenharmony_ci        goto exit;
117a8e1175bSopenharmony_ci    }
118a8e1175bSopenharmony_ci
119a8e1175bSopenharmony_ci    if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
120a8e1175bSopenharmony_ci        goto exit;
121a8e1175bSopenharmony_ci    }
122a8e1175bSopenharmony_ci
123a8e1175bSopenharmony_ciexit:
124a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(L, sizeof(L));
125a8e1175bSopenharmony_ci
126a8e1175bSopenharmony_ci    return ret;
127a8e1175bSopenharmony_ci}
128a8e1175bSopenharmony_ci#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
129a8e1175bSopenharmony_ci
130a8e1175bSopenharmony_ci#if !defined(MBEDTLS_CMAC_ALT)
131a8e1175bSopenharmony_ci
132a8e1175bSopenharmony_ci/*
133a8e1175bSopenharmony_ci * Create padded last block from (partial) last block.
134a8e1175bSopenharmony_ci *
135a8e1175bSopenharmony_ci * We can't use the padding option from the cipher layer, as it only works for
136a8e1175bSopenharmony_ci * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
137a8e1175bSopenharmony_ci */
138a8e1175bSopenharmony_cistatic void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
139a8e1175bSopenharmony_ci                     size_t padded_block_len,
140a8e1175bSopenharmony_ci                     const unsigned char *last_block,
141a8e1175bSopenharmony_ci                     size_t last_block_len)
142a8e1175bSopenharmony_ci{
143a8e1175bSopenharmony_ci    size_t j;
144a8e1175bSopenharmony_ci
145a8e1175bSopenharmony_ci    for (j = 0; j < padded_block_len; j++) {
146a8e1175bSopenharmony_ci        if (j < last_block_len) {
147a8e1175bSopenharmony_ci            padded_block[j] = last_block[j];
148a8e1175bSopenharmony_ci        } else if (j == last_block_len) {
149a8e1175bSopenharmony_ci            padded_block[j] = 0x80;
150a8e1175bSopenharmony_ci        } else {
151a8e1175bSopenharmony_ci            padded_block[j] = 0x00;
152a8e1175bSopenharmony_ci        }
153a8e1175bSopenharmony_ci    }
154a8e1175bSopenharmony_ci}
155a8e1175bSopenharmony_ci
156a8e1175bSopenharmony_ciint mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
157a8e1175bSopenharmony_ci                               const unsigned char *key, size_t keybits)
158a8e1175bSopenharmony_ci{
159a8e1175bSopenharmony_ci    mbedtls_cipher_type_t type;
160a8e1175bSopenharmony_ci    mbedtls_cmac_context_t *cmac_ctx;
161a8e1175bSopenharmony_ci    int retval;
162a8e1175bSopenharmony_ci
163a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
164a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
165a8e1175bSopenharmony_ci    }
166a8e1175bSopenharmony_ci
167a8e1175bSopenharmony_ci    if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
168a8e1175bSopenharmony_ci                                        MBEDTLS_ENCRYPT)) != 0) {
169a8e1175bSopenharmony_ci        return retval;
170a8e1175bSopenharmony_ci    }
171a8e1175bSopenharmony_ci
172a8e1175bSopenharmony_ci    type = mbedtls_cipher_info_get_type(ctx->cipher_info);
173a8e1175bSopenharmony_ci
174a8e1175bSopenharmony_ci    switch (type) {
175a8e1175bSopenharmony_ci        case MBEDTLS_CIPHER_AES_128_ECB:
176a8e1175bSopenharmony_ci        case MBEDTLS_CIPHER_AES_192_ECB:
177a8e1175bSopenharmony_ci        case MBEDTLS_CIPHER_AES_256_ECB:
178a8e1175bSopenharmony_ci        case MBEDTLS_CIPHER_DES_EDE3_ECB:
179a8e1175bSopenharmony_ci            break;
180a8e1175bSopenharmony_ci        default:
181a8e1175bSopenharmony_ci            return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
182a8e1175bSopenharmony_ci    }
183a8e1175bSopenharmony_ci
184a8e1175bSopenharmony_ci    /* Allocated and initialise in the cipher context memory for the CMAC
185a8e1175bSopenharmony_ci     * context */
186a8e1175bSopenharmony_ci    cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
187a8e1175bSopenharmony_ci    if (cmac_ctx == NULL) {
188a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
189a8e1175bSopenharmony_ci    }
190a8e1175bSopenharmony_ci
191a8e1175bSopenharmony_ci    ctx->cmac_ctx = cmac_ctx;
192a8e1175bSopenharmony_ci
193a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
194a8e1175bSopenharmony_ci
195a8e1175bSopenharmony_ci    return 0;
196a8e1175bSopenharmony_ci}
197a8e1175bSopenharmony_ci
198a8e1175bSopenharmony_ciint mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
199a8e1175bSopenharmony_ci                               const unsigned char *input, size_t ilen)
200a8e1175bSopenharmony_ci{
201a8e1175bSopenharmony_ci    mbedtls_cmac_context_t *cmac_ctx;
202a8e1175bSopenharmony_ci    unsigned char *state;
203a8e1175bSopenharmony_ci    int ret = 0;
204a8e1175bSopenharmony_ci    size_t n, j, olen, block_size;
205a8e1175bSopenharmony_ci
206a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
207a8e1175bSopenharmony_ci        ctx->cmac_ctx == NULL) {
208a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
209a8e1175bSopenharmony_ci    }
210a8e1175bSopenharmony_ci
211a8e1175bSopenharmony_ci    cmac_ctx = ctx->cmac_ctx;
212a8e1175bSopenharmony_ci    block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
213a8e1175bSopenharmony_ci    state = ctx->cmac_ctx->state;
214a8e1175bSopenharmony_ci
215a8e1175bSopenharmony_ci    /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
216a8e1175bSopenharmony_ci     * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
217a8e1175bSopenharmony_ci    MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE);
218a8e1175bSopenharmony_ci
219a8e1175bSopenharmony_ci    /* Is there data still to process from the last call, that's greater in
220a8e1175bSopenharmony_ci     * size than a block? */
221a8e1175bSopenharmony_ci    if (cmac_ctx->unprocessed_len > 0 &&
222a8e1175bSopenharmony_ci        ilen > block_size - cmac_ctx->unprocessed_len) {
223a8e1175bSopenharmony_ci        memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
224a8e1175bSopenharmony_ci               input,
225a8e1175bSopenharmony_ci               block_size - cmac_ctx->unprocessed_len);
226a8e1175bSopenharmony_ci
227a8e1175bSopenharmony_ci        mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
228a8e1175bSopenharmony_ci
229a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
230a8e1175bSopenharmony_ci                                         &olen)) != 0) {
231a8e1175bSopenharmony_ci            goto exit;
232a8e1175bSopenharmony_ci        }
233a8e1175bSopenharmony_ci
234a8e1175bSopenharmony_ci        input += block_size - cmac_ctx->unprocessed_len;
235a8e1175bSopenharmony_ci        ilen -= block_size - cmac_ctx->unprocessed_len;
236a8e1175bSopenharmony_ci        cmac_ctx->unprocessed_len = 0;
237a8e1175bSopenharmony_ci    }
238a8e1175bSopenharmony_ci
239a8e1175bSopenharmony_ci    /* n is the number of blocks including any final partial block */
240a8e1175bSopenharmony_ci    n = (ilen + block_size - 1) / block_size;
241a8e1175bSopenharmony_ci
242a8e1175bSopenharmony_ci    /* Iterate across the input data in block sized chunks, excluding any
243a8e1175bSopenharmony_ci     * final partial or complete block */
244a8e1175bSopenharmony_ci    for (j = 1; j < n; j++) {
245a8e1175bSopenharmony_ci        mbedtls_xor_no_simd(state, input, state, block_size);
246a8e1175bSopenharmony_ci
247a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
248a8e1175bSopenharmony_ci                                         &olen)) != 0) {
249a8e1175bSopenharmony_ci            goto exit;
250a8e1175bSopenharmony_ci        }
251a8e1175bSopenharmony_ci
252a8e1175bSopenharmony_ci        ilen -= block_size;
253a8e1175bSopenharmony_ci        input += block_size;
254a8e1175bSopenharmony_ci    }
255a8e1175bSopenharmony_ci
256a8e1175bSopenharmony_ci    /* If there is data left over that wasn't aligned to a block */
257a8e1175bSopenharmony_ci    if (ilen > 0) {
258a8e1175bSopenharmony_ci        memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
259a8e1175bSopenharmony_ci               input,
260a8e1175bSopenharmony_ci               ilen);
261a8e1175bSopenharmony_ci        cmac_ctx->unprocessed_len += ilen;
262a8e1175bSopenharmony_ci    }
263a8e1175bSopenharmony_ci
264a8e1175bSopenharmony_ciexit:
265a8e1175bSopenharmony_ci    return ret;
266a8e1175bSopenharmony_ci}
267a8e1175bSopenharmony_ci
268a8e1175bSopenharmony_ciint mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
269a8e1175bSopenharmony_ci                               unsigned char *output)
270a8e1175bSopenharmony_ci{
271a8e1175bSopenharmony_ci    mbedtls_cmac_context_t *cmac_ctx;
272a8e1175bSopenharmony_ci    unsigned char *state, *last_block;
273a8e1175bSopenharmony_ci    unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
274a8e1175bSopenharmony_ci    unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
275a8e1175bSopenharmony_ci    unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
276a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
277a8e1175bSopenharmony_ci    size_t olen, block_size;
278a8e1175bSopenharmony_ci
279a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
280a8e1175bSopenharmony_ci        output == NULL) {
281a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
282a8e1175bSopenharmony_ci    }
283a8e1175bSopenharmony_ci
284a8e1175bSopenharmony_ci    cmac_ctx = ctx->cmac_ctx;
285a8e1175bSopenharmony_ci    block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
286a8e1175bSopenharmony_ci    MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning
287a8e1175bSopenharmony_ci    state = cmac_ctx->state;
288a8e1175bSopenharmony_ci
289a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(K1, sizeof(K1));
290a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(K2, sizeof(K2));
291a8e1175bSopenharmony_ci    cmac_generate_subkeys(ctx, K1, K2);
292a8e1175bSopenharmony_ci
293a8e1175bSopenharmony_ci    last_block = cmac_ctx->unprocessed_block;
294a8e1175bSopenharmony_ci
295a8e1175bSopenharmony_ci    /* Calculate last block */
296a8e1175bSopenharmony_ci    if (cmac_ctx->unprocessed_len < block_size) {
297a8e1175bSopenharmony_ci        cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
298a8e1175bSopenharmony_ci        mbedtls_xor(M_last, M_last, K2, block_size);
299a8e1175bSopenharmony_ci    } else {
300a8e1175bSopenharmony_ci        /* Last block is complete block */
301a8e1175bSopenharmony_ci        mbedtls_xor(M_last, last_block, K1, block_size);
302a8e1175bSopenharmony_ci    }
303a8e1175bSopenharmony_ci
304a8e1175bSopenharmony_ci
305a8e1175bSopenharmony_ci    mbedtls_xor(state, M_last, state, block_size);
306a8e1175bSopenharmony_ci    if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
307a8e1175bSopenharmony_ci                                     &olen)) != 0) {
308a8e1175bSopenharmony_ci        goto exit;
309a8e1175bSopenharmony_ci    }
310a8e1175bSopenharmony_ci
311a8e1175bSopenharmony_ci    memcpy(output, state, block_size);
312a8e1175bSopenharmony_ci
313a8e1175bSopenharmony_ciexit:
314a8e1175bSopenharmony_ci    /* Wipe the generated keys on the stack, and any other transients to avoid
315a8e1175bSopenharmony_ci     * side channel leakage */
316a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(K1, sizeof(K1));
317a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(K2, sizeof(K2));
318a8e1175bSopenharmony_ci
319a8e1175bSopenharmony_ci    cmac_ctx->unprocessed_len = 0;
320a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
321a8e1175bSopenharmony_ci                             sizeof(cmac_ctx->unprocessed_block));
322a8e1175bSopenharmony_ci
323a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
324a8e1175bSopenharmony_ci    return ret;
325a8e1175bSopenharmony_ci}
326a8e1175bSopenharmony_ci
327a8e1175bSopenharmony_ciint mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
328a8e1175bSopenharmony_ci{
329a8e1175bSopenharmony_ci    mbedtls_cmac_context_t *cmac_ctx;
330a8e1175bSopenharmony_ci
331a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
332a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
333a8e1175bSopenharmony_ci    }
334a8e1175bSopenharmony_ci
335a8e1175bSopenharmony_ci    cmac_ctx = ctx->cmac_ctx;
336a8e1175bSopenharmony_ci
337a8e1175bSopenharmony_ci    /* Reset the internal state */
338a8e1175bSopenharmony_ci    cmac_ctx->unprocessed_len = 0;
339a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
340a8e1175bSopenharmony_ci                             sizeof(cmac_ctx->unprocessed_block));
341a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(cmac_ctx->state,
342a8e1175bSopenharmony_ci                             sizeof(cmac_ctx->state));
343a8e1175bSopenharmony_ci
344a8e1175bSopenharmony_ci    return 0;
345a8e1175bSopenharmony_ci}
346a8e1175bSopenharmony_ci
347a8e1175bSopenharmony_ciint mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
348a8e1175bSopenharmony_ci                        const unsigned char *key, size_t keylen,
349a8e1175bSopenharmony_ci                        const unsigned char *input, size_t ilen,
350a8e1175bSopenharmony_ci                        unsigned char *output)
351a8e1175bSopenharmony_ci{
352a8e1175bSopenharmony_ci    mbedtls_cipher_context_t ctx;
353a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
354a8e1175bSopenharmony_ci
355a8e1175bSopenharmony_ci    if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
356a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
357a8e1175bSopenharmony_ci    }
358a8e1175bSopenharmony_ci
359a8e1175bSopenharmony_ci    mbedtls_cipher_init(&ctx);
360a8e1175bSopenharmony_ci
361a8e1175bSopenharmony_ci    if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
362a8e1175bSopenharmony_ci        goto exit;
363a8e1175bSopenharmony_ci    }
364a8e1175bSopenharmony_ci
365a8e1175bSopenharmony_ci    ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
366a8e1175bSopenharmony_ci    if (ret != 0) {
367a8e1175bSopenharmony_ci        goto exit;
368a8e1175bSopenharmony_ci    }
369a8e1175bSopenharmony_ci
370a8e1175bSopenharmony_ci    ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
371a8e1175bSopenharmony_ci    if (ret != 0) {
372a8e1175bSopenharmony_ci        goto exit;
373a8e1175bSopenharmony_ci    }
374a8e1175bSopenharmony_ci
375a8e1175bSopenharmony_ci    ret = mbedtls_cipher_cmac_finish(&ctx, output);
376a8e1175bSopenharmony_ci
377a8e1175bSopenharmony_ciexit:
378a8e1175bSopenharmony_ci    mbedtls_cipher_free(&ctx);
379a8e1175bSopenharmony_ci
380a8e1175bSopenharmony_ci    return ret;
381a8e1175bSopenharmony_ci}
382a8e1175bSopenharmony_ci
383a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C)
384a8e1175bSopenharmony_ci/*
385a8e1175bSopenharmony_ci * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
386a8e1175bSopenharmony_ci */
387a8e1175bSopenharmony_ciint mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
388a8e1175bSopenharmony_ci                             const unsigned char *input, size_t in_len,
389a8e1175bSopenharmony_ci                             unsigned char output[16])
390a8e1175bSopenharmony_ci{
391a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
392a8e1175bSopenharmony_ci    const mbedtls_cipher_info_t *cipher_info;
393a8e1175bSopenharmony_ci    unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
394a8e1175bSopenharmony_ci    unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
395a8e1175bSopenharmony_ci
396a8e1175bSopenharmony_ci    if (key == NULL || input == NULL || output == NULL) {
397a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
398a8e1175bSopenharmony_ci    }
399a8e1175bSopenharmony_ci
400a8e1175bSopenharmony_ci    cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
401a8e1175bSopenharmony_ci    if (cipher_info == NULL) {
402a8e1175bSopenharmony_ci        /* Failing at this point must be due to a build issue */
403a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
404a8e1175bSopenharmony_ci        goto exit;
405a8e1175bSopenharmony_ci    }
406a8e1175bSopenharmony_ci
407a8e1175bSopenharmony_ci    if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
408a8e1175bSopenharmony_ci        /* Use key as is */
409a8e1175bSopenharmony_ci        memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
410a8e1175bSopenharmony_ci    } else {
411a8e1175bSopenharmony_ci        memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
412a8e1175bSopenharmony_ci
413a8e1175bSopenharmony_ci        ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
414a8e1175bSopenharmony_ci                                  key_length, int_key);
415a8e1175bSopenharmony_ci        if (ret != 0) {
416a8e1175bSopenharmony_ci            goto exit;
417a8e1175bSopenharmony_ci        }
418a8e1175bSopenharmony_ci    }
419a8e1175bSopenharmony_ci
420a8e1175bSopenharmony_ci    ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
421a8e1175bSopenharmony_ci                              output);
422a8e1175bSopenharmony_ci
423a8e1175bSopenharmony_ciexit:
424a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(int_key, sizeof(int_key));
425a8e1175bSopenharmony_ci
426a8e1175bSopenharmony_ci    return ret;
427a8e1175bSopenharmony_ci}
428a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C */
429a8e1175bSopenharmony_ci
430a8e1175bSopenharmony_ci#endif /* !MBEDTLS_CMAC_ALT */
431a8e1175bSopenharmony_ci
432a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST)
433a8e1175bSopenharmony_ci/*
434a8e1175bSopenharmony_ci * CMAC test data for SP800-38B
435a8e1175bSopenharmony_ci * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
436a8e1175bSopenharmony_ci * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
437a8e1175bSopenharmony_ci *
438a8e1175bSopenharmony_ci * AES-CMAC-PRF-128 test data from RFC 4615
439a8e1175bSopenharmony_ci * https://tools.ietf.org/html/rfc4615#page-4
440a8e1175bSopenharmony_ci */
441a8e1175bSopenharmony_ci
442a8e1175bSopenharmony_ci#define NB_CMAC_TESTS_PER_KEY 4
443a8e1175bSopenharmony_ci#define NB_PRF_TESTS 3
444a8e1175bSopenharmony_ci
445a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
446a8e1175bSopenharmony_ci/* All CMAC test inputs are truncated from the same 64 byte buffer. */
447a8e1175bSopenharmony_cistatic const unsigned char test_message[] = {
448a8e1175bSopenharmony_ci    /* PT */
449a8e1175bSopenharmony_ci    0x6b, 0xc1, 0xbe, 0xe2,     0x2e, 0x40, 0x9f, 0x96,
450a8e1175bSopenharmony_ci    0xe9, 0x3d, 0x7e, 0x11,     0x73, 0x93, 0x17, 0x2a,
451a8e1175bSopenharmony_ci    0xae, 0x2d, 0x8a, 0x57,     0x1e, 0x03, 0xac, 0x9c,
452a8e1175bSopenharmony_ci    0x9e, 0xb7, 0x6f, 0xac,     0x45, 0xaf, 0x8e, 0x51,
453a8e1175bSopenharmony_ci    0x30, 0xc8, 0x1c, 0x46,     0xa3, 0x5c, 0xe4, 0x11,
454a8e1175bSopenharmony_ci    0xe5, 0xfb, 0xc1, 0x19,     0x1a, 0x0a, 0x52, 0xef,
455a8e1175bSopenharmony_ci    0xf6, 0x9f, 0x24, 0x45,     0xdf, 0x4f, 0x9b, 0x17,
456a8e1175bSopenharmony_ci    0xad, 0x2b, 0x41, 0x7b,     0xe6, 0x6c, 0x37, 0x10
457a8e1175bSopenharmony_ci};
458a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
459a8e1175bSopenharmony_ci
460a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C)
461a8e1175bSopenharmony_ci/* Truncation point of message for AES CMAC tests  */
462a8e1175bSopenharmony_cistatic const  unsigned int  aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
463a8e1175bSopenharmony_ci    /* Mlen */
464a8e1175bSopenharmony_ci    0,
465a8e1175bSopenharmony_ci    16,
466a8e1175bSopenharmony_ci    20,
467a8e1175bSopenharmony_ci    64
468a8e1175bSopenharmony_ci};
469a8e1175bSopenharmony_ci
470a8e1175bSopenharmony_ci/* CMAC-AES128 Test Data */
471a8e1175bSopenharmony_cistatic const unsigned char aes_128_key[16] = {
472a8e1175bSopenharmony_ci    0x2b, 0x7e, 0x15, 0x16,     0x28, 0xae, 0xd2, 0xa6,
473a8e1175bSopenharmony_ci    0xab, 0xf7, 0x15, 0x88,     0x09, 0xcf, 0x4f, 0x3c
474a8e1175bSopenharmony_ci};
475a8e1175bSopenharmony_cistatic const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
476a8e1175bSopenharmony_ci    {
477a8e1175bSopenharmony_ci        /* K1 */
478a8e1175bSopenharmony_ci        0xfb, 0xee, 0xd6, 0x18,     0x35, 0x71, 0x33, 0x66,
479a8e1175bSopenharmony_ci        0x7c, 0x85, 0xe0, 0x8f,     0x72, 0x36, 0xa8, 0xde
480a8e1175bSopenharmony_ci    },
481a8e1175bSopenharmony_ci    {
482a8e1175bSopenharmony_ci        /* K2 */
483a8e1175bSopenharmony_ci        0xf7, 0xdd, 0xac, 0x30,     0x6a, 0xe2, 0x66, 0xcc,
484a8e1175bSopenharmony_ci        0xf9, 0x0b, 0xc1, 0x1e,     0xe4, 0x6d, 0x51, 0x3b
485a8e1175bSopenharmony_ci    }
486a8e1175bSopenharmony_ci};
487a8e1175bSopenharmony_cistatic const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
488a8e1175bSopenharmony_ci{
489a8e1175bSopenharmony_ci    {
490a8e1175bSopenharmony_ci        /* Example #1 */
491a8e1175bSopenharmony_ci        0xbb, 0x1d, 0x69, 0x29,     0xe9, 0x59, 0x37, 0x28,
492a8e1175bSopenharmony_ci        0x7f, 0xa3, 0x7d, 0x12,     0x9b, 0x75, 0x67, 0x46
493a8e1175bSopenharmony_ci    },
494a8e1175bSopenharmony_ci    {
495a8e1175bSopenharmony_ci        /* Example #2 */
496a8e1175bSopenharmony_ci        0x07, 0x0a, 0x16, 0xb4,     0x6b, 0x4d, 0x41, 0x44,
497a8e1175bSopenharmony_ci        0xf7, 0x9b, 0xdd, 0x9d,     0xd0, 0x4a, 0x28, 0x7c
498a8e1175bSopenharmony_ci    },
499a8e1175bSopenharmony_ci    {
500a8e1175bSopenharmony_ci        /* Example #3 */
501a8e1175bSopenharmony_ci        0x7d, 0x85, 0x44, 0x9e,     0xa6, 0xea, 0x19, 0xc8,
502a8e1175bSopenharmony_ci        0x23, 0xa7, 0xbf, 0x78,     0x83, 0x7d, 0xfa, 0xde
503a8e1175bSopenharmony_ci    },
504a8e1175bSopenharmony_ci    {
505a8e1175bSopenharmony_ci        /* Example #4 */
506a8e1175bSopenharmony_ci        0x51, 0xf0, 0xbe, 0xbf,     0x7e, 0x3b, 0x9d, 0x92,
507a8e1175bSopenharmony_ci        0xfc, 0x49, 0x74, 0x17,     0x79, 0x36, 0x3c, 0xfe
508a8e1175bSopenharmony_ci    }
509a8e1175bSopenharmony_ci};
510a8e1175bSopenharmony_ci
511a8e1175bSopenharmony_ci/* CMAC-AES192 Test Data */
512a8e1175bSopenharmony_ci#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
513a8e1175bSopenharmony_cistatic const unsigned char aes_192_key[24] = {
514a8e1175bSopenharmony_ci    0x8e, 0x73, 0xb0, 0xf7,     0xda, 0x0e, 0x64, 0x52,
515a8e1175bSopenharmony_ci    0xc8, 0x10, 0xf3, 0x2b,     0x80, 0x90, 0x79, 0xe5,
516a8e1175bSopenharmony_ci    0x62, 0xf8, 0xea, 0xd2,     0x52, 0x2c, 0x6b, 0x7b
517a8e1175bSopenharmony_ci};
518a8e1175bSopenharmony_cistatic const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
519a8e1175bSopenharmony_ci    {
520a8e1175bSopenharmony_ci        /* K1 */
521a8e1175bSopenharmony_ci        0x44, 0x8a, 0x5b, 0x1c,     0x93, 0x51, 0x4b, 0x27,
522a8e1175bSopenharmony_ci        0x3e, 0xe6, 0x43, 0x9d,     0xd4, 0xda, 0xa2, 0x96
523a8e1175bSopenharmony_ci    },
524a8e1175bSopenharmony_ci    {
525a8e1175bSopenharmony_ci        /* K2 */
526a8e1175bSopenharmony_ci        0x89, 0x14, 0xb6, 0x39,     0x26, 0xa2, 0x96, 0x4e,
527a8e1175bSopenharmony_ci        0x7d, 0xcc, 0x87, 0x3b,     0xa9, 0xb5, 0x45, 0x2c
528a8e1175bSopenharmony_ci    }
529a8e1175bSopenharmony_ci};
530a8e1175bSopenharmony_cistatic const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
531a8e1175bSopenharmony_ci{
532a8e1175bSopenharmony_ci    {
533a8e1175bSopenharmony_ci        /* Example #1 */
534a8e1175bSopenharmony_ci        0xd1, 0x7d, 0xdf, 0x46,     0xad, 0xaa, 0xcd, 0xe5,
535a8e1175bSopenharmony_ci        0x31, 0xca, 0xc4, 0x83,     0xde, 0x7a, 0x93, 0x67
536a8e1175bSopenharmony_ci    },
537a8e1175bSopenharmony_ci    {
538a8e1175bSopenharmony_ci        /* Example #2 */
539a8e1175bSopenharmony_ci        0x9e, 0x99, 0xa7, 0xbf,     0x31, 0xe7, 0x10, 0x90,
540a8e1175bSopenharmony_ci        0x06, 0x62, 0xf6, 0x5e,     0x61, 0x7c, 0x51, 0x84
541a8e1175bSopenharmony_ci    },
542a8e1175bSopenharmony_ci    {
543a8e1175bSopenharmony_ci        /* Example #3 */
544a8e1175bSopenharmony_ci        0x3d, 0x75, 0xc1, 0x94,     0xed, 0x96, 0x07, 0x04,
545a8e1175bSopenharmony_ci        0x44, 0xa9, 0xfa, 0x7e,     0xc7, 0x40, 0xec, 0xf8
546a8e1175bSopenharmony_ci    },
547a8e1175bSopenharmony_ci    {
548a8e1175bSopenharmony_ci        /* Example #4 */
549a8e1175bSopenharmony_ci        0xa1, 0xd5, 0xdf, 0x0e,     0xed, 0x79, 0x0f, 0x79,
550a8e1175bSopenharmony_ci        0x4d, 0x77, 0x58, 0x96,     0x59, 0xf3, 0x9a, 0x11
551a8e1175bSopenharmony_ci    }
552a8e1175bSopenharmony_ci};
553a8e1175bSopenharmony_ci#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
554a8e1175bSopenharmony_ci
555a8e1175bSopenharmony_ci/* CMAC-AES256 Test Data */
556a8e1175bSopenharmony_ci#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
557a8e1175bSopenharmony_cistatic const unsigned char aes_256_key[32] = {
558a8e1175bSopenharmony_ci    0x60, 0x3d, 0xeb, 0x10,     0x15, 0xca, 0x71, 0xbe,
559a8e1175bSopenharmony_ci    0x2b, 0x73, 0xae, 0xf0,     0x85, 0x7d, 0x77, 0x81,
560a8e1175bSopenharmony_ci    0x1f, 0x35, 0x2c, 0x07,     0x3b, 0x61, 0x08, 0xd7,
561a8e1175bSopenharmony_ci    0x2d, 0x98, 0x10, 0xa3,     0x09, 0x14, 0xdf, 0xf4
562a8e1175bSopenharmony_ci};
563a8e1175bSopenharmony_cistatic const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
564a8e1175bSopenharmony_ci    {
565a8e1175bSopenharmony_ci        /* K1 */
566a8e1175bSopenharmony_ci        0xca, 0xd1, 0xed, 0x03,     0x29, 0x9e, 0xed, 0xac,
567a8e1175bSopenharmony_ci        0x2e, 0x9a, 0x99, 0x80,     0x86, 0x21, 0x50, 0x2f
568a8e1175bSopenharmony_ci    },
569a8e1175bSopenharmony_ci    {
570a8e1175bSopenharmony_ci        /* K2 */
571a8e1175bSopenharmony_ci        0x95, 0xa3, 0xda, 0x06,     0x53, 0x3d, 0xdb, 0x58,
572a8e1175bSopenharmony_ci        0x5d, 0x35, 0x33, 0x01,     0x0c, 0x42, 0xa0, 0xd9
573a8e1175bSopenharmony_ci    }
574a8e1175bSopenharmony_ci};
575a8e1175bSopenharmony_cistatic const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
576a8e1175bSopenharmony_ci{
577a8e1175bSopenharmony_ci    {
578a8e1175bSopenharmony_ci        /* Example #1 */
579a8e1175bSopenharmony_ci        0x02, 0x89, 0x62, 0xf6,     0x1b, 0x7b, 0xf8, 0x9e,
580a8e1175bSopenharmony_ci        0xfc, 0x6b, 0x55, 0x1f,     0x46, 0x67, 0xd9, 0x83
581a8e1175bSopenharmony_ci    },
582a8e1175bSopenharmony_ci    {
583a8e1175bSopenharmony_ci        /* Example #2 */
584a8e1175bSopenharmony_ci        0x28, 0xa7, 0x02, 0x3f,     0x45, 0x2e, 0x8f, 0x82,
585a8e1175bSopenharmony_ci        0xbd, 0x4b, 0xf2, 0x8d,     0x8c, 0x37, 0xc3, 0x5c
586a8e1175bSopenharmony_ci    },
587a8e1175bSopenharmony_ci    {
588a8e1175bSopenharmony_ci        /* Example #3 */
589a8e1175bSopenharmony_ci        0x15, 0x67, 0x27, 0xdc,     0x08, 0x78, 0x94, 0x4a,
590a8e1175bSopenharmony_ci        0x02, 0x3c, 0x1f, 0xe0,     0x3b, 0xad, 0x6d, 0x93
591a8e1175bSopenharmony_ci    },
592a8e1175bSopenharmony_ci    {
593a8e1175bSopenharmony_ci        /* Example #4 */
594a8e1175bSopenharmony_ci        0xe1, 0x99, 0x21, 0x90,     0x54, 0x9f, 0x6e, 0xd5,
595a8e1175bSopenharmony_ci        0x69, 0x6a, 0x2c, 0x05,     0x6c, 0x31, 0x54, 0x10
596a8e1175bSopenharmony_ci    }
597a8e1175bSopenharmony_ci};
598a8e1175bSopenharmony_ci#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
599a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C */
600a8e1175bSopenharmony_ci
601a8e1175bSopenharmony_ci#if defined(MBEDTLS_DES_C)
602a8e1175bSopenharmony_ci/* Truncation point of message for 3DES CMAC tests  */
603a8e1175bSopenharmony_cistatic const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
604a8e1175bSopenharmony_ci    0,
605a8e1175bSopenharmony_ci    16,
606a8e1175bSopenharmony_ci    20,
607a8e1175bSopenharmony_ci    32
608a8e1175bSopenharmony_ci};
609a8e1175bSopenharmony_ci
610a8e1175bSopenharmony_ci/* CMAC-TDES (Generation) - 2 Key Test Data */
611a8e1175bSopenharmony_cistatic const unsigned char des3_2key_key[24] = {
612a8e1175bSopenharmony_ci    /* Key1 */
613a8e1175bSopenharmony_ci    0x01, 0x23, 0x45, 0x67,     0x89, 0xab, 0xcd, 0xef,
614a8e1175bSopenharmony_ci    /* Key2 */
615a8e1175bSopenharmony_ci    0x23, 0x45, 0x67, 0x89,     0xab, 0xcd, 0xEF, 0x01,
616a8e1175bSopenharmony_ci    /* Key3 */
617a8e1175bSopenharmony_ci    0x01, 0x23, 0x45, 0x67,     0x89, 0xab, 0xcd, 0xef
618a8e1175bSopenharmony_ci};
619a8e1175bSopenharmony_cistatic const unsigned char des3_2key_subkeys[2][8] = {
620a8e1175bSopenharmony_ci    {
621a8e1175bSopenharmony_ci        /* K1 */
622a8e1175bSopenharmony_ci        0x0d, 0xd2, 0xcb, 0x7a,     0x3d, 0x88, 0x88, 0xd9
623a8e1175bSopenharmony_ci    },
624a8e1175bSopenharmony_ci    {
625a8e1175bSopenharmony_ci        /* K2 */
626a8e1175bSopenharmony_ci        0x1b, 0xa5, 0x96, 0xf4,     0x7b, 0x11, 0x11, 0xb2
627a8e1175bSopenharmony_ci    }
628a8e1175bSopenharmony_ci};
629a8e1175bSopenharmony_cistatic const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
630a8e1175bSopenharmony_ci    = {
631a8e1175bSopenharmony_ci    {
632a8e1175bSopenharmony_ci        /* Sample #1 */
633a8e1175bSopenharmony_ci        0x79, 0xce, 0x52, 0xa7,     0xf7, 0x86, 0xa9, 0x60
634a8e1175bSopenharmony_ci    },
635a8e1175bSopenharmony_ci    {
636a8e1175bSopenharmony_ci        /* Sample #2 */
637a8e1175bSopenharmony_ci        0xcc, 0x18, 0xa0, 0xb7,     0x9a, 0xf2, 0x41, 0x3b
638a8e1175bSopenharmony_ci    },
639a8e1175bSopenharmony_ci    {
640a8e1175bSopenharmony_ci        /* Sample #3 */
641a8e1175bSopenharmony_ci        0xc0, 0x6d, 0x37, 0x7e,     0xcd, 0x10, 0x19, 0x69
642a8e1175bSopenharmony_ci    },
643a8e1175bSopenharmony_ci    {
644a8e1175bSopenharmony_ci        /* Sample #4 */
645a8e1175bSopenharmony_ci        0x9c, 0xd3, 0x35, 0x80,     0xf9, 0xb6, 0x4d, 0xfb
646a8e1175bSopenharmony_ci    }
647a8e1175bSopenharmony_ci    };
648a8e1175bSopenharmony_ci
649a8e1175bSopenharmony_ci/* CMAC-TDES (Generation) - 3 Key Test Data */
650a8e1175bSopenharmony_cistatic const unsigned char des3_3key_key[24] = {
651a8e1175bSopenharmony_ci    /* Key1 */
652a8e1175bSopenharmony_ci    0x01, 0x23, 0x45, 0x67,     0x89, 0xaa, 0xcd, 0xef,
653a8e1175bSopenharmony_ci    /* Key2 */
654a8e1175bSopenharmony_ci    0x23, 0x45, 0x67, 0x89,     0xab, 0xcd, 0xef, 0x01,
655a8e1175bSopenharmony_ci    /* Key3 */
656a8e1175bSopenharmony_ci    0x45, 0x67, 0x89, 0xab,     0xcd, 0xef, 0x01, 0x23
657a8e1175bSopenharmony_ci};
658a8e1175bSopenharmony_cistatic const unsigned char des3_3key_subkeys[2][8] = {
659a8e1175bSopenharmony_ci    {
660a8e1175bSopenharmony_ci        /* K1 */
661a8e1175bSopenharmony_ci        0x9d, 0x74, 0xe7, 0x39,     0x33, 0x17, 0x96, 0xc0
662a8e1175bSopenharmony_ci    },
663a8e1175bSopenharmony_ci    {
664a8e1175bSopenharmony_ci        /* K2 */
665a8e1175bSopenharmony_ci        0x3a, 0xe9, 0xce, 0x72,     0x66, 0x2f, 0x2d, 0x9b
666a8e1175bSopenharmony_ci    }
667a8e1175bSopenharmony_ci};
668a8e1175bSopenharmony_cistatic const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
669a8e1175bSopenharmony_ci    = {
670a8e1175bSopenharmony_ci    {
671a8e1175bSopenharmony_ci        /* Sample #1 */
672a8e1175bSopenharmony_ci        0x7d, 0xb0, 0xd3, 0x7d,     0xf9, 0x36, 0xc5, 0x50
673a8e1175bSopenharmony_ci    },
674a8e1175bSopenharmony_ci    {
675a8e1175bSopenharmony_ci        /* Sample #2 */
676a8e1175bSopenharmony_ci        0x30, 0x23, 0x9c, 0xf1,     0xf5, 0x2e, 0x66, 0x09
677a8e1175bSopenharmony_ci    },
678a8e1175bSopenharmony_ci    {
679a8e1175bSopenharmony_ci        /* Sample #3 */
680a8e1175bSopenharmony_ci        0x6c, 0x9f, 0x3e, 0xe4,     0x92, 0x3f, 0x6b, 0xe2
681a8e1175bSopenharmony_ci    },
682a8e1175bSopenharmony_ci    {
683a8e1175bSopenharmony_ci        /* Sample #4 */
684a8e1175bSopenharmony_ci        0x99, 0x42, 0x9b, 0xd0,     0xbF, 0x79, 0x04, 0xe5
685a8e1175bSopenharmony_ci    }
686a8e1175bSopenharmony_ci    };
687a8e1175bSopenharmony_ci
688a8e1175bSopenharmony_ci#endif /* MBEDTLS_DES_C */
689a8e1175bSopenharmony_ci
690a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C)
691a8e1175bSopenharmony_ci/* AES AES-CMAC-PRF-128 Test Data */
692a8e1175bSopenharmony_cistatic const unsigned char PRFK[] = {
693a8e1175bSopenharmony_ci    /* Key */
694a8e1175bSopenharmony_ci    0x00, 0x01, 0x02, 0x03,     0x04, 0x05, 0x06, 0x07,
695a8e1175bSopenharmony_ci    0x08, 0x09, 0x0a, 0x0b,     0x0c, 0x0d, 0x0e, 0x0f,
696a8e1175bSopenharmony_ci    0xed, 0xcb
697a8e1175bSopenharmony_ci};
698a8e1175bSopenharmony_ci
699a8e1175bSopenharmony_ci/* Sizes in bytes */
700a8e1175bSopenharmony_cistatic const size_t PRFKlen[NB_PRF_TESTS] = {
701a8e1175bSopenharmony_ci    18,
702a8e1175bSopenharmony_ci    16,
703a8e1175bSopenharmony_ci    10
704a8e1175bSopenharmony_ci};
705a8e1175bSopenharmony_ci
706a8e1175bSopenharmony_ci/* Message */
707a8e1175bSopenharmony_cistatic const unsigned char PRFM[] = {
708a8e1175bSopenharmony_ci    0x00, 0x01, 0x02, 0x03,     0x04, 0x05, 0x06, 0x07,
709a8e1175bSopenharmony_ci    0x08, 0x09, 0x0a, 0x0b,     0x0c, 0x0d, 0x0e, 0x0f,
710a8e1175bSopenharmony_ci    0x10, 0x11, 0x12, 0x13
711a8e1175bSopenharmony_ci};
712a8e1175bSopenharmony_ci
713a8e1175bSopenharmony_cistatic const unsigned char PRFT[NB_PRF_TESTS][16] = {
714a8e1175bSopenharmony_ci    {
715a8e1175bSopenharmony_ci        0x84, 0xa3, 0x48, 0xa4,     0xa4, 0x5d, 0x23, 0x5b,
716a8e1175bSopenharmony_ci        0xab, 0xff, 0xfc, 0x0d,     0x2b, 0x4d, 0xa0, 0x9a
717a8e1175bSopenharmony_ci    },
718a8e1175bSopenharmony_ci    {
719a8e1175bSopenharmony_ci        0x98, 0x0a, 0xe8, 0x7b,     0x5f, 0x4c, 0x9c, 0x52,
720a8e1175bSopenharmony_ci        0x14, 0xf5, 0xb6, 0xa8,     0x45, 0x5e, 0x4c, 0x2d
721a8e1175bSopenharmony_ci    },
722a8e1175bSopenharmony_ci    {
723a8e1175bSopenharmony_ci        0x29, 0x0d, 0x9e, 0x11,     0x2e, 0xdb, 0x09, 0xee,
724a8e1175bSopenharmony_ci        0x14, 0x1f, 0xcf, 0x64,     0xc0, 0xb7, 0x2f, 0x3d
725a8e1175bSopenharmony_ci    }
726a8e1175bSopenharmony_ci};
727a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C */
728a8e1175bSopenharmony_ci
729a8e1175bSopenharmony_cistatic int cmac_test_subkeys(int verbose,
730a8e1175bSopenharmony_ci                             const char *testname,
731a8e1175bSopenharmony_ci                             const unsigned char *key,
732a8e1175bSopenharmony_ci                             int keybits,
733a8e1175bSopenharmony_ci                             const unsigned char *subkeys,
734a8e1175bSopenharmony_ci                             mbedtls_cipher_type_t cipher_type,
735a8e1175bSopenharmony_ci                             int block_size,
736a8e1175bSopenharmony_ci                             int num_tests)
737a8e1175bSopenharmony_ci{
738a8e1175bSopenharmony_ci    int i, ret = 0;
739a8e1175bSopenharmony_ci    mbedtls_cipher_context_t ctx;
740a8e1175bSopenharmony_ci    const mbedtls_cipher_info_t *cipher_info;
741a8e1175bSopenharmony_ci    unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
742a8e1175bSopenharmony_ci    unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
743a8e1175bSopenharmony_ci
744a8e1175bSopenharmony_ci    cipher_info = mbedtls_cipher_info_from_type(cipher_type);
745a8e1175bSopenharmony_ci    if (cipher_info == NULL) {
746a8e1175bSopenharmony_ci        /* Failing at this point must be due to a build issue */
747a8e1175bSopenharmony_ci        return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
748a8e1175bSopenharmony_ci    }
749a8e1175bSopenharmony_ci
750a8e1175bSopenharmony_ci    for (i = 0; i < num_tests; i++) {
751a8e1175bSopenharmony_ci        if (verbose != 0) {
752a8e1175bSopenharmony_ci            mbedtls_printf("  %s CMAC subkey #%d: ", testname, i + 1);
753a8e1175bSopenharmony_ci        }
754a8e1175bSopenharmony_ci
755a8e1175bSopenharmony_ci        mbedtls_cipher_init(&ctx);
756a8e1175bSopenharmony_ci
757a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
758a8e1175bSopenharmony_ci            if (verbose != 0) {
759a8e1175bSopenharmony_ci                mbedtls_printf("test execution failed\n");
760a8e1175bSopenharmony_ci            }
761a8e1175bSopenharmony_ci
762a8e1175bSopenharmony_ci            goto cleanup;
763a8e1175bSopenharmony_ci        }
764a8e1175bSopenharmony_ci
765a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
766a8e1175bSopenharmony_ci                                         MBEDTLS_ENCRYPT)) != 0) {
767a8e1175bSopenharmony_ci            /* When CMAC is implemented by an alternative implementation, or
768a8e1175bSopenharmony_ci             * the underlying primitive itself is implemented alternatively,
769a8e1175bSopenharmony_ci             * AES-192 may be unavailable. This should not cause the selftest
770a8e1175bSopenharmony_ci             * function to fail. */
771a8e1175bSopenharmony_ci            if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
772a8e1175bSopenharmony_ci                 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
773a8e1175bSopenharmony_ci                cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
774a8e1175bSopenharmony_ci                if (verbose != 0) {
775a8e1175bSopenharmony_ci                    mbedtls_printf("skipped\n");
776a8e1175bSopenharmony_ci                }
777a8e1175bSopenharmony_ci                goto next_test;
778a8e1175bSopenharmony_ci            }
779a8e1175bSopenharmony_ci
780a8e1175bSopenharmony_ci            if (verbose != 0) {
781a8e1175bSopenharmony_ci                mbedtls_printf("test execution failed\n");
782a8e1175bSopenharmony_ci            }
783a8e1175bSopenharmony_ci
784a8e1175bSopenharmony_ci            goto cleanup;
785a8e1175bSopenharmony_ci        }
786a8e1175bSopenharmony_ci
787a8e1175bSopenharmony_ci        ret = cmac_generate_subkeys(&ctx, K1, K2);
788a8e1175bSopenharmony_ci        if (ret != 0) {
789a8e1175bSopenharmony_ci            if (verbose != 0) {
790a8e1175bSopenharmony_ci                mbedtls_printf("failed\n");
791a8e1175bSopenharmony_ci            }
792a8e1175bSopenharmony_ci
793a8e1175bSopenharmony_ci            goto cleanup;
794a8e1175bSopenharmony_ci        }
795a8e1175bSopenharmony_ci
796a8e1175bSopenharmony_ci        if ((ret = memcmp(K1, subkeys, block_size)) != 0  ||
797a8e1175bSopenharmony_ci            (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
798a8e1175bSopenharmony_ci            if (verbose != 0) {
799a8e1175bSopenharmony_ci                mbedtls_printf("failed\n");
800a8e1175bSopenharmony_ci            }
801a8e1175bSopenharmony_ci
802a8e1175bSopenharmony_ci            goto cleanup;
803a8e1175bSopenharmony_ci        }
804a8e1175bSopenharmony_ci
805a8e1175bSopenharmony_ci        if (verbose != 0) {
806a8e1175bSopenharmony_ci            mbedtls_printf("passed\n");
807a8e1175bSopenharmony_ci        }
808a8e1175bSopenharmony_ci
809a8e1175bSopenharmony_cinext_test:
810a8e1175bSopenharmony_ci        mbedtls_cipher_free(&ctx);
811a8e1175bSopenharmony_ci    }
812a8e1175bSopenharmony_ci
813a8e1175bSopenharmony_ci    ret = 0;
814a8e1175bSopenharmony_ci    goto exit;
815a8e1175bSopenharmony_ci
816a8e1175bSopenharmony_cicleanup:
817a8e1175bSopenharmony_ci    mbedtls_cipher_free(&ctx);
818a8e1175bSopenharmony_ci
819a8e1175bSopenharmony_ciexit:
820a8e1175bSopenharmony_ci    return ret;
821a8e1175bSopenharmony_ci}
822a8e1175bSopenharmony_ci
823a8e1175bSopenharmony_cistatic int cmac_test_wth_cipher(int verbose,
824a8e1175bSopenharmony_ci                                const char *testname,
825a8e1175bSopenharmony_ci                                const unsigned char *key,
826a8e1175bSopenharmony_ci                                int keybits,
827a8e1175bSopenharmony_ci                                const unsigned char *messages,
828a8e1175bSopenharmony_ci                                const unsigned int message_lengths[4],
829a8e1175bSopenharmony_ci                                const unsigned char *expected_result,
830a8e1175bSopenharmony_ci                                mbedtls_cipher_type_t cipher_type,
831a8e1175bSopenharmony_ci                                int block_size,
832a8e1175bSopenharmony_ci                                int num_tests)
833a8e1175bSopenharmony_ci{
834a8e1175bSopenharmony_ci    const mbedtls_cipher_info_t *cipher_info;
835a8e1175bSopenharmony_ci    int i, ret = 0;
836a8e1175bSopenharmony_ci    unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
837a8e1175bSopenharmony_ci
838a8e1175bSopenharmony_ci    cipher_info = mbedtls_cipher_info_from_type(cipher_type);
839a8e1175bSopenharmony_ci    if (cipher_info == NULL) {
840a8e1175bSopenharmony_ci        /* Failing at this point must be due to a build issue */
841a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
842a8e1175bSopenharmony_ci        goto exit;
843a8e1175bSopenharmony_ci    }
844a8e1175bSopenharmony_ci
845a8e1175bSopenharmony_ci    for (i = 0; i < num_tests; i++) {
846a8e1175bSopenharmony_ci        if (verbose != 0) {
847a8e1175bSopenharmony_ci            mbedtls_printf("  %s CMAC #%d: ", testname, i + 1);
848a8e1175bSopenharmony_ci        }
849a8e1175bSopenharmony_ci
850a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
851a8e1175bSopenharmony_ci                                       message_lengths[i], output)) != 0) {
852a8e1175bSopenharmony_ci            /* When CMAC is implemented by an alternative implementation, or
853a8e1175bSopenharmony_ci             * the underlying primitive itself is implemented alternatively,
854a8e1175bSopenharmony_ci             * AES-192 and/or 3DES may be unavailable. This should not cause
855a8e1175bSopenharmony_ci             * the selftest function to fail. */
856a8e1175bSopenharmony_ci            if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
857a8e1175bSopenharmony_ci                 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
858a8e1175bSopenharmony_ci                (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
859a8e1175bSopenharmony_ci                 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
860a8e1175bSopenharmony_ci                if (verbose != 0) {
861a8e1175bSopenharmony_ci                    mbedtls_printf("skipped\n");
862a8e1175bSopenharmony_ci                }
863a8e1175bSopenharmony_ci                continue;
864a8e1175bSopenharmony_ci            }
865a8e1175bSopenharmony_ci
866a8e1175bSopenharmony_ci            if (verbose != 0) {
867a8e1175bSopenharmony_ci                mbedtls_printf("failed\n");
868a8e1175bSopenharmony_ci            }
869a8e1175bSopenharmony_ci            goto exit;
870a8e1175bSopenharmony_ci        }
871a8e1175bSopenharmony_ci
872a8e1175bSopenharmony_ci        if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
873a8e1175bSopenharmony_ci            if (verbose != 0) {
874a8e1175bSopenharmony_ci                mbedtls_printf("failed\n");
875a8e1175bSopenharmony_ci            }
876a8e1175bSopenharmony_ci            goto exit;
877a8e1175bSopenharmony_ci        }
878a8e1175bSopenharmony_ci
879a8e1175bSopenharmony_ci        if (verbose != 0) {
880a8e1175bSopenharmony_ci            mbedtls_printf("passed\n");
881a8e1175bSopenharmony_ci        }
882a8e1175bSopenharmony_ci    }
883a8e1175bSopenharmony_ci    ret = 0;
884a8e1175bSopenharmony_ci
885a8e1175bSopenharmony_ciexit:
886a8e1175bSopenharmony_ci    return ret;
887a8e1175bSopenharmony_ci}
888a8e1175bSopenharmony_ci
889a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C)
890a8e1175bSopenharmony_cistatic int test_aes128_cmac_prf(int verbose)
891a8e1175bSopenharmony_ci{
892a8e1175bSopenharmony_ci    int i;
893a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
894a8e1175bSopenharmony_ci    unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
895a8e1175bSopenharmony_ci
896a8e1175bSopenharmony_ci    for (i = 0; i < NB_PRF_TESTS; i++) {
897a8e1175bSopenharmony_ci        mbedtls_printf("  AES CMAC 128 PRF #%d: ", i);
898a8e1175bSopenharmony_ci        ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
899a8e1175bSopenharmony_ci        if (ret != 0 ||
900a8e1175bSopenharmony_ci            memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
901a8e1175bSopenharmony_ci
902a8e1175bSopenharmony_ci            if (verbose != 0) {
903a8e1175bSopenharmony_ci                mbedtls_printf("failed\n");
904a8e1175bSopenharmony_ci            }
905a8e1175bSopenharmony_ci
906a8e1175bSopenharmony_ci            return ret;
907a8e1175bSopenharmony_ci        } else if (verbose != 0) {
908a8e1175bSopenharmony_ci            mbedtls_printf("passed\n");
909a8e1175bSopenharmony_ci        }
910a8e1175bSopenharmony_ci    }
911a8e1175bSopenharmony_ci    return ret;
912a8e1175bSopenharmony_ci}
913a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C */
914a8e1175bSopenharmony_ci
915a8e1175bSopenharmony_ciint mbedtls_cmac_self_test(int verbose)
916a8e1175bSopenharmony_ci{
917a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
918a8e1175bSopenharmony_ci
919a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C)
920a8e1175bSopenharmony_ci    /* AES-128 */
921a8e1175bSopenharmony_ci    if ((ret = cmac_test_subkeys(verbose,
922a8e1175bSopenharmony_ci                                 "AES 128",
923a8e1175bSopenharmony_ci                                 aes_128_key,
924a8e1175bSopenharmony_ci                                 128,
925a8e1175bSopenharmony_ci                                 (const unsigned char *) aes_128_subkeys,
926a8e1175bSopenharmony_ci                                 MBEDTLS_CIPHER_AES_128_ECB,
927a8e1175bSopenharmony_ci                                 MBEDTLS_AES_BLOCK_SIZE,
928a8e1175bSopenharmony_ci                                 NB_CMAC_TESTS_PER_KEY)) != 0) {
929a8e1175bSopenharmony_ci        return ret;
930a8e1175bSopenharmony_ci    }
931a8e1175bSopenharmony_ci
932a8e1175bSopenharmony_ci    if ((ret = cmac_test_wth_cipher(verbose,
933a8e1175bSopenharmony_ci                                    "AES 128",
934a8e1175bSopenharmony_ci                                    aes_128_key,
935a8e1175bSopenharmony_ci                                    128,
936a8e1175bSopenharmony_ci                                    test_message,
937a8e1175bSopenharmony_ci                                    aes_message_lengths,
938a8e1175bSopenharmony_ci                                    (const unsigned char *) aes_128_expected_result,
939a8e1175bSopenharmony_ci                                    MBEDTLS_CIPHER_AES_128_ECB,
940a8e1175bSopenharmony_ci                                    MBEDTLS_AES_BLOCK_SIZE,
941a8e1175bSopenharmony_ci                                    NB_CMAC_TESTS_PER_KEY)) != 0) {
942a8e1175bSopenharmony_ci        return ret;
943a8e1175bSopenharmony_ci    }
944a8e1175bSopenharmony_ci
945a8e1175bSopenharmony_ci    /* AES-192 */
946a8e1175bSopenharmony_ci#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
947a8e1175bSopenharmony_ci    if ((ret = cmac_test_subkeys(verbose,
948a8e1175bSopenharmony_ci                                 "AES 192",
949a8e1175bSopenharmony_ci                                 aes_192_key,
950a8e1175bSopenharmony_ci                                 192,
951a8e1175bSopenharmony_ci                                 (const unsigned char *) aes_192_subkeys,
952a8e1175bSopenharmony_ci                                 MBEDTLS_CIPHER_AES_192_ECB,
953a8e1175bSopenharmony_ci                                 MBEDTLS_AES_BLOCK_SIZE,
954a8e1175bSopenharmony_ci                                 NB_CMAC_TESTS_PER_KEY)) != 0) {
955a8e1175bSopenharmony_ci        return ret;
956a8e1175bSopenharmony_ci    }
957a8e1175bSopenharmony_ci
958a8e1175bSopenharmony_ci    if ((ret = cmac_test_wth_cipher(verbose,
959a8e1175bSopenharmony_ci                                    "AES 192",
960a8e1175bSopenharmony_ci                                    aes_192_key,
961a8e1175bSopenharmony_ci                                    192,
962a8e1175bSopenharmony_ci                                    test_message,
963a8e1175bSopenharmony_ci                                    aes_message_lengths,
964a8e1175bSopenharmony_ci                                    (const unsigned char *) aes_192_expected_result,
965a8e1175bSopenharmony_ci                                    MBEDTLS_CIPHER_AES_192_ECB,
966a8e1175bSopenharmony_ci                                    MBEDTLS_AES_BLOCK_SIZE,
967a8e1175bSopenharmony_ci                                    NB_CMAC_TESTS_PER_KEY)) != 0) {
968a8e1175bSopenharmony_ci        return ret;
969a8e1175bSopenharmony_ci    }
970a8e1175bSopenharmony_ci#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
971a8e1175bSopenharmony_ci
972a8e1175bSopenharmony_ci    /* AES-256 */
973a8e1175bSopenharmony_ci#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
974a8e1175bSopenharmony_ci    if ((ret = cmac_test_subkeys(verbose,
975a8e1175bSopenharmony_ci                                 "AES 256",
976a8e1175bSopenharmony_ci                                 aes_256_key,
977a8e1175bSopenharmony_ci                                 256,
978a8e1175bSopenharmony_ci                                 (const unsigned char *) aes_256_subkeys,
979a8e1175bSopenharmony_ci                                 MBEDTLS_CIPHER_AES_256_ECB,
980a8e1175bSopenharmony_ci                                 MBEDTLS_AES_BLOCK_SIZE,
981a8e1175bSopenharmony_ci                                 NB_CMAC_TESTS_PER_KEY)) != 0) {
982a8e1175bSopenharmony_ci        return ret;
983a8e1175bSopenharmony_ci    }
984a8e1175bSopenharmony_ci
985a8e1175bSopenharmony_ci    if ((ret = cmac_test_wth_cipher(verbose,
986a8e1175bSopenharmony_ci                                    "AES 256",
987a8e1175bSopenharmony_ci                                    aes_256_key,
988a8e1175bSopenharmony_ci                                    256,
989a8e1175bSopenharmony_ci                                    test_message,
990a8e1175bSopenharmony_ci                                    aes_message_lengths,
991a8e1175bSopenharmony_ci                                    (const unsigned char *) aes_256_expected_result,
992a8e1175bSopenharmony_ci                                    MBEDTLS_CIPHER_AES_256_ECB,
993a8e1175bSopenharmony_ci                                    MBEDTLS_AES_BLOCK_SIZE,
994a8e1175bSopenharmony_ci                                    NB_CMAC_TESTS_PER_KEY)) != 0) {
995a8e1175bSopenharmony_ci        return ret;
996a8e1175bSopenharmony_ci    }
997a8e1175bSopenharmony_ci#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
998a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C */
999a8e1175bSopenharmony_ci
1000a8e1175bSopenharmony_ci#if defined(MBEDTLS_DES_C)
1001a8e1175bSopenharmony_ci    /* 3DES 2 key */
1002a8e1175bSopenharmony_ci    if ((ret = cmac_test_subkeys(verbose,
1003a8e1175bSopenharmony_ci                                 "3DES 2 key",
1004a8e1175bSopenharmony_ci                                 des3_2key_key,
1005a8e1175bSopenharmony_ci                                 192,
1006a8e1175bSopenharmony_ci                                 (const unsigned char *) des3_2key_subkeys,
1007a8e1175bSopenharmony_ci                                 MBEDTLS_CIPHER_DES_EDE3_ECB,
1008a8e1175bSopenharmony_ci                                 MBEDTLS_DES3_BLOCK_SIZE,
1009a8e1175bSopenharmony_ci                                 NB_CMAC_TESTS_PER_KEY)) != 0) {
1010a8e1175bSopenharmony_ci        return ret;
1011a8e1175bSopenharmony_ci    }
1012a8e1175bSopenharmony_ci
1013a8e1175bSopenharmony_ci    if ((ret = cmac_test_wth_cipher(verbose,
1014a8e1175bSopenharmony_ci                                    "3DES 2 key",
1015a8e1175bSopenharmony_ci                                    des3_2key_key,
1016a8e1175bSopenharmony_ci                                    192,
1017a8e1175bSopenharmony_ci                                    test_message,
1018a8e1175bSopenharmony_ci                                    des3_message_lengths,
1019a8e1175bSopenharmony_ci                                    (const unsigned char *) des3_2key_expected_result,
1020a8e1175bSopenharmony_ci                                    MBEDTLS_CIPHER_DES_EDE3_ECB,
1021a8e1175bSopenharmony_ci                                    MBEDTLS_DES3_BLOCK_SIZE,
1022a8e1175bSopenharmony_ci                                    NB_CMAC_TESTS_PER_KEY)) != 0) {
1023a8e1175bSopenharmony_ci        return ret;
1024a8e1175bSopenharmony_ci    }
1025a8e1175bSopenharmony_ci
1026a8e1175bSopenharmony_ci    /* 3DES 3 key */
1027a8e1175bSopenharmony_ci    if ((ret = cmac_test_subkeys(verbose,
1028a8e1175bSopenharmony_ci                                 "3DES 3 key",
1029a8e1175bSopenharmony_ci                                 des3_3key_key,
1030a8e1175bSopenharmony_ci                                 192,
1031a8e1175bSopenharmony_ci                                 (const unsigned char *) des3_3key_subkeys,
1032a8e1175bSopenharmony_ci                                 MBEDTLS_CIPHER_DES_EDE3_ECB,
1033a8e1175bSopenharmony_ci                                 MBEDTLS_DES3_BLOCK_SIZE,
1034a8e1175bSopenharmony_ci                                 NB_CMAC_TESTS_PER_KEY)) != 0) {
1035a8e1175bSopenharmony_ci        return ret;
1036a8e1175bSopenharmony_ci    }
1037a8e1175bSopenharmony_ci
1038a8e1175bSopenharmony_ci    if ((ret = cmac_test_wth_cipher(verbose,
1039a8e1175bSopenharmony_ci                                    "3DES 3 key",
1040a8e1175bSopenharmony_ci                                    des3_3key_key,
1041a8e1175bSopenharmony_ci                                    192,
1042a8e1175bSopenharmony_ci                                    test_message,
1043a8e1175bSopenharmony_ci                                    des3_message_lengths,
1044a8e1175bSopenharmony_ci                                    (const unsigned char *) des3_3key_expected_result,
1045a8e1175bSopenharmony_ci                                    MBEDTLS_CIPHER_DES_EDE3_ECB,
1046a8e1175bSopenharmony_ci                                    MBEDTLS_DES3_BLOCK_SIZE,
1047a8e1175bSopenharmony_ci                                    NB_CMAC_TESTS_PER_KEY)) != 0) {
1048a8e1175bSopenharmony_ci        return ret;
1049a8e1175bSopenharmony_ci    }
1050a8e1175bSopenharmony_ci#endif /* MBEDTLS_DES_C */
1051a8e1175bSopenharmony_ci
1052a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C)
1053a8e1175bSopenharmony_ci    if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1054a8e1175bSopenharmony_ci        return ret;
1055a8e1175bSopenharmony_ci    }
1056a8e1175bSopenharmony_ci#endif /* MBEDTLS_AES_C */
1057a8e1175bSopenharmony_ci
1058a8e1175bSopenharmony_ci    if (verbose != 0) {
1059a8e1175bSopenharmony_ci        mbedtls_printf("\n");
1060a8e1175bSopenharmony_ci    }
1061a8e1175bSopenharmony_ci
1062a8e1175bSopenharmony_ci    return 0;
1063a8e1175bSopenharmony_ci}
1064a8e1175bSopenharmony_ci
1065a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */
1066a8e1175bSopenharmony_ci
1067a8e1175bSopenharmony_ci#endif /* MBEDTLS_CMAC_C */
1068