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