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