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