Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
cmac.c
00001 /** 00002 * \file cmac.c 00003 * 00004 * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES 00005 * 00006 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 * 00021 * This file is part of mbed TLS (https://tls.mbed.org) 00022 */ 00023 00024 /* 00025 * References: 00026 * 00027 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The 00028 * CMAC Mode for Authentication 00029 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf 00030 * 00031 * - RFC 4493 - The AES-CMAC Algorithm 00032 * https://tools.ietf.org/html/rfc4493 00033 * 00034 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message 00035 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) 00036 * Algorithm for the Internet Key Exchange Protocol (IKE) 00037 * https://tools.ietf.org/html/rfc4615 00038 * 00039 * Additional test vectors: ISO/IEC 9797-1 00040 * 00041 */ 00042 00043 #if !defined(MBEDTLS_CONFIG_FILE) 00044 #include "mbedtls/config.h" 00045 #else 00046 #include MBEDTLS_CONFIG_FILE 00047 #endif 00048 00049 #if defined(MBEDTLS_CMAC_C) 00050 00051 #include "mbedtls/cmac.h" 00052 00053 #include <string.h> 00054 00055 00056 #if defined(MBEDTLS_PLATFORM_C) 00057 #include "mbedtls/platform.h" 00058 #else 00059 #include <stdlib.h> 00060 #define mbedtls_calloc calloc 00061 #define mbedtls_free free 00062 #if defined(MBEDTLS_SELF_TEST) 00063 #include <stdio.h> 00064 #define mbedtls_printf printf 00065 #endif /* MBEDTLS_SELF_TEST */ 00066 #endif /* MBEDTLS_PLATFORM_C */ 00067 00068 #if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) 00069 00070 /* Implementation that should never be optimized out by the compiler */ 00071 static void mbedtls_zeroize( void *v, size_t n ) { 00072 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; 00073 } 00074 00075 /* 00076 * Multiplication by u in the Galois field of GF(2^n) 00077 * 00078 * As explained in NIST SP 800-38B, this can be computed: 00079 * 00080 * If MSB(p) = 0, then p = (p << 1) 00081 * If MSB(p) = 1, then p = (p << 1) ^ R_n 00082 * with R_64 = 0x1B and R_128 = 0x87 00083 * 00084 * Input and output MUST NOT point to the same buffer 00085 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. 00086 */ 00087 static int cmac_multiply_by_u( unsigned char *output, 00088 const unsigned char *input, 00089 size_t blocksize ) 00090 { 00091 const unsigned char R_128 = 0x87; 00092 const unsigned char R_64 = 0x1B; 00093 unsigned char R_n, mask; 00094 unsigned char overflow = 0x00; 00095 int i; 00096 00097 if( blocksize == MBEDTLS_AES_BLOCK_SIZE ) 00098 { 00099 R_n = R_128; 00100 } 00101 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE ) 00102 { 00103 R_n = R_64; 00104 } 00105 else 00106 { 00107 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00108 } 00109 00110 for( i = (int)blocksize - 1; i >= 0; i-- ) 00111 { 00112 output[i] = input[i] << 1 | overflow; 00113 overflow = input[i] >> 7; 00114 } 00115 00116 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00 00117 * using bit operations to avoid branches */ 00118 00119 /* MSVC has a warning about unary minus on unsigned, but this is 00120 * well-defined and precisely what we want to do here */ 00121 #if defined(_MSC_VER) 00122 #pragma warning( push ) 00123 #pragma warning( disable : 4146 ) 00124 #endif 00125 mask = - ( input[0] >> 7 ); 00126 #if defined(_MSC_VER) 00127 #pragma warning( pop ) 00128 #endif 00129 00130 output[ blocksize - 1 ] ^= R_n & mask; 00131 00132 return( 0 ); 00133 } 00134 00135 /* 00136 * Generate subkeys 00137 * 00138 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm 00139 */ 00140 static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, 00141 unsigned char* K1, unsigned char* K2 ) 00142 { 00143 int ret; 00144 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00145 size_t olen, block_size; 00146 00147 mbedtls_zeroize( L, sizeof( L ) ); 00148 00149 block_size = ctx->cipher_info->block_size; 00150 00151 /* Calculate Ek(0) */ 00152 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 ) 00153 goto exit; 00154 00155 /* 00156 * Generate K1 and K2 00157 */ 00158 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 ) 00159 goto exit; 00160 00161 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 ) 00162 goto exit; 00163 00164 exit: 00165 mbedtls_zeroize( L, sizeof( L ) ); 00166 00167 return( ret ); 00168 } 00169 #endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ 00170 00171 #if !defined(MBEDTLS_CMAC_ALT) 00172 static void cmac_xor_block( unsigned char *output, const unsigned char *input1, 00173 const unsigned char *input2, 00174 const size_t block_size ) 00175 { 00176 size_t idx; 00177 00178 for( idx = 0; idx < block_size; idx++ ) 00179 output[ idx ] = input1[ idx ] ^ input2[ idx ]; 00180 } 00181 00182 /* 00183 * Create padded last block from (partial) last block. 00184 * 00185 * We can't use the padding option from the cipher layer, as it only works for 00186 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. 00187 */ 00188 static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX], 00189 size_t padded_block_len, 00190 const unsigned char *last_block, 00191 size_t last_block_len ) 00192 { 00193 size_t j; 00194 00195 for( j = 0; j < padded_block_len; j++ ) 00196 { 00197 if( j < last_block_len ) 00198 padded_block[j] = last_block[j]; 00199 else if( j == last_block_len ) 00200 padded_block[j] = 0x80; 00201 else 00202 padded_block[j] = 0x00; 00203 } 00204 } 00205 00206 int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, 00207 const unsigned char *key, size_t keybits ) 00208 { 00209 mbedtls_cipher_type_t type; 00210 mbedtls_cmac_context_t *cmac_ctx; 00211 int retval; 00212 00213 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL ) 00214 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00215 00216 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits, 00217 MBEDTLS_ENCRYPT ) ) != 0 ) 00218 return( retval ); 00219 00220 type = ctx->cipher_info->type; 00221 00222 switch( type ) 00223 { 00224 case MBEDTLS_CIPHER_AES_128_ECB: 00225 case MBEDTLS_CIPHER_AES_192_ECB: 00226 case MBEDTLS_CIPHER_AES_256_ECB: 00227 case MBEDTLS_CIPHER_DES_EDE3_ECB: 00228 break; 00229 default: 00230 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00231 } 00232 00233 /* Allocated and initialise in the cipher context memory for the CMAC 00234 * context */ 00235 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) ); 00236 if( cmac_ctx == NULL ) 00237 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); 00238 00239 ctx->cmac_ctx = cmac_ctx; 00240 00241 mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); 00242 00243 return 0; 00244 } 00245 00246 int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, 00247 const unsigned char *input, size_t ilen ) 00248 { 00249 mbedtls_cmac_context_t* cmac_ctx; 00250 unsigned char *state; 00251 int ret = 0; 00252 size_t n, j, olen, block_size; 00253 00254 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL || 00255 ctx->cmac_ctx == NULL ) 00256 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00257 00258 cmac_ctx = ctx->cmac_ctx; 00259 block_size = ctx->cipher_info->block_size; 00260 state = ctx->cmac_ctx->state; 00261 00262 /* Is there data still to process from the last call, that's greater in 00263 * size than a block? */ 00264 if( cmac_ctx->unprocessed_len > 0 && 00265 ilen > block_size - cmac_ctx->unprocessed_len ) 00266 { 00267 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], 00268 input, 00269 block_size - cmac_ctx->unprocessed_len ); 00270 00271 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); 00272 00273 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, 00274 &olen ) ) != 0 ) 00275 { 00276 goto exit; 00277 } 00278 00279 input += block_size - cmac_ctx->unprocessed_len; 00280 ilen -= block_size - cmac_ctx->unprocessed_len; 00281 cmac_ctx->unprocessed_len = 0; 00282 } 00283 00284 /* n is the number of blocks including any final partial block */ 00285 n = ( ilen + block_size - 1 ) / block_size; 00286 00287 /* Iterate across the input data in block sized chunks, excluding any 00288 * final partial or complete block */ 00289 for( j = 1; j < n; j++ ) 00290 { 00291 cmac_xor_block( state, input, state, block_size ); 00292 00293 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, 00294 &olen ) ) != 0 ) 00295 goto exit; 00296 00297 ilen -= block_size; 00298 input += block_size; 00299 } 00300 00301 /* If there is data left over that wasn't aligned to a block */ 00302 if( ilen > 0 ) 00303 { 00304 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], 00305 input, 00306 ilen ); 00307 cmac_ctx->unprocessed_len += ilen; 00308 } 00309 00310 exit: 00311 return( ret ); 00312 } 00313 00314 int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, 00315 unsigned char *output ) 00316 { 00317 mbedtls_cmac_context_t* cmac_ctx; 00318 unsigned char *state, *last_block; 00319 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00320 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00321 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00322 int ret; 00323 size_t olen, block_size; 00324 00325 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || 00326 output == NULL ) 00327 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00328 00329 cmac_ctx = ctx->cmac_ctx; 00330 block_size = ctx->cipher_info->block_size; 00331 state = cmac_ctx->state; 00332 00333 mbedtls_zeroize( K1, sizeof( K1 ) ); 00334 mbedtls_zeroize( K2, sizeof( K2 ) ); 00335 cmac_generate_subkeys( ctx, K1, K2 ); 00336 00337 last_block = cmac_ctx->unprocessed_block; 00338 00339 /* Calculate last block */ 00340 if( cmac_ctx->unprocessed_len < block_size ) 00341 { 00342 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); 00343 cmac_xor_block( M_last, M_last, K2, block_size ); 00344 } 00345 else 00346 { 00347 /* Last block is complete block */ 00348 cmac_xor_block( M_last, last_block, K1, block_size ); 00349 } 00350 00351 00352 cmac_xor_block( state, M_last, state, block_size ); 00353 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, 00354 &olen ) ) != 0 ) 00355 { 00356 goto exit; 00357 } 00358 00359 memcpy( output, state, block_size ); 00360 00361 exit: 00362 /* Wipe the generated keys on the stack, and any other transients to avoid 00363 * side channel leakage */ 00364 mbedtls_zeroize( K1, sizeof( K1 ) ); 00365 mbedtls_zeroize( K2, sizeof( K2 ) ); 00366 00367 cmac_ctx->unprocessed_len = 0; 00368 mbedtls_zeroize( cmac_ctx->unprocessed_block, 00369 sizeof( cmac_ctx->unprocessed_block ) ); 00370 00371 mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); 00372 return( ret ); 00373 } 00374 00375 int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) 00376 { 00377 mbedtls_cmac_context_t* cmac_ctx; 00378 00379 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ) 00380 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00381 00382 cmac_ctx = ctx->cmac_ctx; 00383 00384 /* Reset the internal state */ 00385 cmac_ctx->unprocessed_len = 0; 00386 mbedtls_zeroize( cmac_ctx->unprocessed_block, 00387 sizeof( cmac_ctx->unprocessed_block ) ); 00388 mbedtls_zeroize( cmac_ctx->state, 00389 sizeof( cmac_ctx->state ) ); 00390 00391 return( 0 ); 00392 } 00393 00394 int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, 00395 const unsigned char *key, size_t keylen, 00396 const unsigned char *input, size_t ilen, 00397 unsigned char *output ) 00398 { 00399 mbedtls_cipher_context_t ctx; 00400 int ret; 00401 00402 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) 00403 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00404 00405 mbedtls_cipher_init( &ctx ); 00406 00407 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) 00408 goto exit; 00409 00410 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen ); 00411 if( ret != 0 ) 00412 goto exit; 00413 00414 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen ); 00415 if( ret != 0 ) 00416 goto exit; 00417 00418 ret = mbedtls_cipher_cmac_finish( &ctx, output ); 00419 00420 exit: 00421 mbedtls_cipher_free( &ctx ); 00422 00423 return( ret ); 00424 } 00425 00426 #if defined(MBEDTLS_AES_C) 00427 /* 00428 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 00429 */ 00430 int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, 00431 const unsigned char *input, size_t in_len, 00432 unsigned char *output ) 00433 { 00434 int ret; 00435 const mbedtls_cipher_info_t *cipher_info; 00436 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; 00437 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; 00438 00439 if( key == NULL || input == NULL || output == NULL ) 00440 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00441 00442 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB ); 00443 if( cipher_info == NULL ) 00444 { 00445 /* Failing at this point must be due to a build issue */ 00446 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; 00447 goto exit; 00448 } 00449 00450 if( key_length == MBEDTLS_AES_BLOCK_SIZE ) 00451 { 00452 /* Use key as is */ 00453 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); 00454 } 00455 else 00456 { 00457 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); 00458 00459 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, 00460 key_length, int_key ); 00461 if( ret != 0 ) 00462 goto exit; 00463 } 00464 00465 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len, 00466 output ); 00467 00468 exit: 00469 mbedtls_zeroize( int_key, sizeof( int_key ) ); 00470 00471 return( ret ); 00472 } 00473 #endif /* MBEDTLS_AES_C */ 00474 00475 #endif /* !MBEDTLS_CMAC_ALT */ 00476 00477 #if defined(MBEDTLS_SELF_TEST) 00478 /* 00479 * CMAC test data for SP800-38B 00480 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf 00481 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf 00482 * 00483 * AES-CMAC-PRF-128 test data from RFC 4615 00484 * https://tools.ietf.org/html/rfc4615#page-4 00485 */ 00486 00487 #define NB_CMAC_TESTS_PER_KEY 4 00488 #define NB_PRF_TESTS 3 00489 00490 #if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) 00491 /* All CMAC test inputs are truncated from the same 64 byte buffer. */ 00492 static const unsigned char test_message[] = { 00493 /* PT */ 00494 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 00495 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 00496 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 00497 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 00498 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 00499 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 00500 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 00501 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 00502 }; 00503 #endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ 00504 00505 #if defined(MBEDTLS_AES_C) 00506 /* Truncation point of message for AES CMAC tests */ 00507 static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { 00508 /* Mlen */ 00509 0, 00510 16, 00511 20, 00512 64 00513 }; 00514 00515 /* CMAC-AES128 Test Data */ 00516 static const unsigned char aes_128_key[16] = { 00517 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 00518 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c 00519 }; 00520 static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { 00521 { 00522 /* K1 */ 00523 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, 00524 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde 00525 }, 00526 { 00527 /* K2 */ 00528 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, 00529 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b 00530 } 00531 }; 00532 static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { 00533 { 00534 /* Example #1 */ 00535 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 00536 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 00537 }, 00538 { 00539 /* Example #2 */ 00540 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 00541 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c 00542 }, 00543 { 00544 /* Example #3 */ 00545 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, 00546 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde 00547 }, 00548 { 00549 /* Example #4 */ 00550 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 00551 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe 00552 } 00553 }; 00554 00555 /* CMAC-AES192 Test Data */ 00556 static const unsigned char aes_192_key[24] = { 00557 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 00558 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 00559 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b 00560 }; 00561 static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { 00562 { 00563 /* K1 */ 00564 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, 00565 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 00566 }, 00567 { 00568 /* K2 */ 00569 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, 00570 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c 00571 } 00572 }; 00573 static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { 00574 { 00575 /* Example #1 */ 00576 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, 00577 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 00578 }, 00579 { 00580 /* Example #2 */ 00581 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, 00582 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 00583 }, 00584 { 00585 /* Example #3 */ 00586 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, 00587 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 00588 }, 00589 { 00590 /* Example #4 */ 00591 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, 00592 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 00593 } 00594 }; 00595 00596 /* CMAC-AES256 Test Data */ 00597 static const unsigned char aes_256_key[32] = { 00598 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 00599 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 00600 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 00601 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 00602 }; 00603 static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { 00604 { 00605 /* K1 */ 00606 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, 00607 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f 00608 }, 00609 { 00610 /* K2 */ 00611 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, 00612 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 00613 } 00614 }; 00615 static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { 00616 { 00617 /* Example #1 */ 00618 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, 00619 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 00620 }, 00621 { 00622 /* Example #2 */ 00623 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, 00624 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c 00625 }, 00626 { 00627 /* Example #3 */ 00628 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, 00629 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 00630 }, 00631 { 00632 /* Example #4 */ 00633 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, 00634 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 00635 } 00636 }; 00637 #endif /* MBEDTLS_AES_C */ 00638 00639 #if defined(MBEDTLS_DES_C) 00640 /* Truncation point of message for 3DES CMAC tests */ 00641 static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { 00642 0, 00643 16, 00644 20, 00645 32 00646 }; 00647 00648 /* CMAC-TDES (Generation) - 2 Key Test Data */ 00649 static const unsigned char des3_2key_key[24] = { 00650 /* Key1 */ 00651 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 00652 /* Key2 */ 00653 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, 00654 /* Key3 */ 00655 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef 00656 }; 00657 static const unsigned char des3_2key_subkeys[2][8] = { 00658 { 00659 /* K1 */ 00660 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 00661 }, 00662 { 00663 /* K2 */ 00664 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 00665 } 00666 }; 00667 static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { 00668 { 00669 /* Sample #1 */ 00670 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 00671 }, 00672 { 00673 /* Sample #2 */ 00674 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b 00675 }, 00676 { 00677 /* Sample #3 */ 00678 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 00679 }, 00680 { 00681 /* Sample #4 */ 00682 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb 00683 } 00684 }; 00685 00686 /* CMAC-TDES (Generation) - 3 Key Test Data */ 00687 static const unsigned char des3_3key_key[24] = { 00688 /* Key1 */ 00689 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, 00690 /* Key2 */ 00691 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 00692 /* Key3 */ 00693 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 00694 }; 00695 static const unsigned char des3_3key_subkeys[2][8] = { 00696 { 00697 /* K1 */ 00698 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 00699 }, 00700 { 00701 /* K2 */ 00702 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b 00703 } 00704 }; 00705 static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { 00706 { 00707 /* Sample #1 */ 00708 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 00709 }, 00710 { 00711 /* Sample #2 */ 00712 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 00713 }, 00714 { 00715 /* Sample #3 */ 00716 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 00717 }, 00718 { 00719 /* Sample #4 */ 00720 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 00721 } 00722 }; 00723 00724 #endif /* MBEDTLS_DES_C */ 00725 00726 #if defined(MBEDTLS_AES_C) 00727 /* AES AES-CMAC-PRF-128 Test Data */ 00728 static const unsigned char PRFK[] = { 00729 /* Key */ 00730 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 00731 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 00732 0xed, 0xcb 00733 }; 00734 00735 /* Sizes in bytes */ 00736 static const size_t PRFKlen[NB_PRF_TESTS] = { 00737 18, 00738 16, 00739 10 00740 }; 00741 00742 /* Message */ 00743 static const unsigned char PRFM[] = { 00744 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 00745 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 00746 0x10, 0x11, 0x12, 0x13 00747 }; 00748 00749 static const unsigned char PRFT[NB_PRF_TESTS][16] = { 00750 { 00751 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, 00752 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a 00753 }, 00754 { 00755 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, 00756 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d 00757 }, 00758 { 00759 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, 00760 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d 00761 } 00762 }; 00763 #endif /* MBEDTLS_AES_C */ 00764 00765 static int cmac_test_subkeys( int verbose, 00766 const char* testname, 00767 const unsigned char* key, 00768 int keybits, 00769 const unsigned char* subkeys, 00770 mbedtls_cipher_type_t cipher_type, 00771 int block_size, 00772 int num_tests ) 00773 { 00774 int i, ret; 00775 mbedtls_cipher_context_t ctx; 00776 const mbedtls_cipher_info_t *cipher_info; 00777 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00778 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00779 00780 cipher_info = mbedtls_cipher_info_from_type( cipher_type ); 00781 if( cipher_info == NULL ) 00782 { 00783 /* Failing at this point must be due to a build issue */ 00784 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00785 } 00786 00787 for( i = 0; i < num_tests; i++ ) 00788 { 00789 if( verbose != 0 ) 00790 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 ); 00791 00792 mbedtls_cipher_init( &ctx ); 00793 00794 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) 00795 { 00796 if( verbose != 0 ) 00797 mbedtls_printf( "test execution failed\n" ); 00798 00799 goto cleanup; 00800 } 00801 00802 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits, 00803 MBEDTLS_ENCRYPT ) ) != 0 ) 00804 { 00805 if( verbose != 0 ) 00806 mbedtls_printf( "test execution failed\n" ); 00807 00808 goto cleanup; 00809 } 00810 00811 ret = cmac_generate_subkeys( &ctx, K1, K2 ); 00812 if( ret != 0 ) 00813 { 00814 if( verbose != 0 ) 00815 mbedtls_printf( "failed\n" ); 00816 00817 goto cleanup; 00818 } 00819 00820 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 || 00821 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 ) 00822 { 00823 if( verbose != 0 ) 00824 mbedtls_printf( "failed\n" ); 00825 00826 goto cleanup; 00827 } 00828 00829 if( verbose != 0 ) 00830 mbedtls_printf( "passed\n" ); 00831 00832 mbedtls_cipher_free( &ctx ); 00833 } 00834 00835 goto exit; 00836 00837 cleanup: 00838 mbedtls_cipher_free( &ctx ); 00839 00840 exit: 00841 return( ret ); 00842 } 00843 00844 static int cmac_test_wth_cipher( int verbose, 00845 const char* testname, 00846 const unsigned char* key, 00847 int keybits, 00848 const unsigned char* messages, 00849 const unsigned int message_lengths[4], 00850 const unsigned char* expected_result, 00851 mbedtls_cipher_type_t cipher_type, 00852 int block_size, 00853 int num_tests ) 00854 { 00855 const mbedtls_cipher_info_t *cipher_info; 00856 int i, ret; 00857 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; 00858 00859 cipher_info = mbedtls_cipher_info_from_type( cipher_type ); 00860 if( cipher_info == NULL ) 00861 { 00862 /* Failing at this point must be due to a build issue */ 00863 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; 00864 goto exit; 00865 } 00866 00867 for( i = 0; i < num_tests; i++ ) 00868 { 00869 if( verbose != 0 ) 00870 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 ); 00871 00872 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages, 00873 message_lengths[i], output ) ) != 0 ) 00874 { 00875 if( verbose != 0 ) 00876 mbedtls_printf( "failed\n" ); 00877 goto exit; 00878 } 00879 00880 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 ) 00881 { 00882 if( verbose != 0 ) 00883 mbedtls_printf( "failed\n" ); 00884 goto exit; 00885 } 00886 00887 if( verbose != 0 ) 00888 mbedtls_printf( "passed\n" ); 00889 } 00890 00891 exit: 00892 return( ret ); 00893 } 00894 00895 #if defined(MBEDTLS_AES_C) 00896 static int test_aes128_cmac_prf( int verbose ) 00897 { 00898 int i; 00899 int ret; 00900 unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; 00901 00902 for( i = 0; i < NB_PRF_TESTS; i++ ) 00903 { 00904 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); 00905 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); 00906 if( ret != 0 || 00907 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) 00908 { 00909 00910 if( verbose != 0 ) 00911 mbedtls_printf( "failed\n" ); 00912 00913 return( ret ); 00914 } 00915 else if( verbose != 0 ) 00916 { 00917 mbedtls_printf( "passed\n" ); 00918 } 00919 } 00920 return( ret ); 00921 } 00922 #endif /* MBEDTLS_AES_C */ 00923 00924 int mbedtls_cmac_self_test( int verbose ) 00925 { 00926 int ret; 00927 00928 #if defined(MBEDTLS_AES_C) 00929 /* AES-128 */ 00930 if( ( ret = cmac_test_subkeys( verbose, 00931 "AES 128", 00932 aes_128_key, 00933 128, 00934 (const unsigned char*)aes_128_subkeys, 00935 MBEDTLS_CIPHER_AES_128_ECB, 00936 MBEDTLS_AES_BLOCK_SIZE, 00937 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 00938 { 00939 return( ret ); 00940 } 00941 00942 if( ( ret = cmac_test_wth_cipher( verbose, 00943 "AES 128", 00944 aes_128_key, 00945 128, 00946 test_message, 00947 aes_message_lengths, 00948 (const unsigned char*)aes_128_expected_result, 00949 MBEDTLS_CIPHER_AES_128_ECB, 00950 MBEDTLS_AES_BLOCK_SIZE, 00951 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 00952 { 00953 return( ret ); 00954 } 00955 00956 /* AES-192 */ 00957 if( ( ret = cmac_test_subkeys( verbose, 00958 "AES 192", 00959 aes_192_key, 00960 192, 00961 (const unsigned char*)aes_192_subkeys, 00962 MBEDTLS_CIPHER_AES_192_ECB, 00963 MBEDTLS_AES_BLOCK_SIZE, 00964 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 00965 { 00966 return( ret ); 00967 } 00968 00969 if( ( ret = cmac_test_wth_cipher( verbose, 00970 "AES 192", 00971 aes_192_key, 00972 192, 00973 test_message, 00974 aes_message_lengths, 00975 (const unsigned char*)aes_192_expected_result, 00976 MBEDTLS_CIPHER_AES_192_ECB, 00977 MBEDTLS_AES_BLOCK_SIZE, 00978 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 00979 { 00980 return( ret ); 00981 } 00982 00983 /* AES-256 */ 00984 if( ( ret = cmac_test_subkeys( verbose, 00985 "AES 256", 00986 aes_256_key, 00987 256, 00988 (const unsigned char*)aes_256_subkeys, 00989 MBEDTLS_CIPHER_AES_256_ECB, 00990 MBEDTLS_AES_BLOCK_SIZE, 00991 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 00992 { 00993 return( ret ); 00994 } 00995 00996 if( ( ret = cmac_test_wth_cipher ( verbose, 00997 "AES 256", 00998 aes_256_key, 00999 256, 01000 test_message, 01001 aes_message_lengths, 01002 (const unsigned char*)aes_256_expected_result, 01003 MBEDTLS_CIPHER_AES_256_ECB, 01004 MBEDTLS_AES_BLOCK_SIZE, 01005 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 01006 { 01007 return( ret ); 01008 } 01009 #endif /* MBEDTLS_AES_C */ 01010 01011 #if defined(MBEDTLS_DES_C) 01012 /* 3DES 2 key */ 01013 if( ( ret = cmac_test_subkeys( verbose, 01014 "3DES 2 key", 01015 des3_2key_key, 01016 192, 01017 (const unsigned char*)des3_2key_subkeys, 01018 MBEDTLS_CIPHER_DES_EDE3_ECB, 01019 MBEDTLS_DES3_BLOCK_SIZE, 01020 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 01021 { 01022 return( ret ); 01023 } 01024 01025 if( ( ret = cmac_test_wth_cipher( verbose, 01026 "3DES 2 key", 01027 des3_2key_key, 01028 192, 01029 test_message, 01030 des3_message_lengths, 01031 (const unsigned char*)des3_2key_expected_result, 01032 MBEDTLS_CIPHER_DES_EDE3_ECB, 01033 MBEDTLS_DES3_BLOCK_SIZE, 01034 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 01035 { 01036 return( ret ); 01037 } 01038 01039 /* 3DES 3 key */ 01040 if( ( ret = cmac_test_subkeys( verbose, 01041 "3DES 3 key", 01042 des3_3key_key, 01043 192, 01044 (const unsigned char*)des3_3key_subkeys, 01045 MBEDTLS_CIPHER_DES_EDE3_ECB, 01046 MBEDTLS_DES3_BLOCK_SIZE, 01047 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 01048 { 01049 return( ret ); 01050 } 01051 01052 if( ( ret = cmac_test_wth_cipher( verbose, 01053 "3DES 3 key", 01054 des3_3key_key, 01055 192, 01056 test_message, 01057 des3_message_lengths, 01058 (const unsigned char*)des3_3key_expected_result, 01059 MBEDTLS_CIPHER_DES_EDE3_ECB, 01060 MBEDTLS_DES3_BLOCK_SIZE, 01061 NB_CMAC_TESTS_PER_KEY ) ) != 0 ) 01062 { 01063 return( ret ); 01064 } 01065 #endif /* MBEDTLS_DES_C */ 01066 01067 #if defined(MBEDTLS_AES_C) 01068 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 ) 01069 return( ret ); 01070 #endif /* MBEDTLS_AES_C */ 01071 01072 if( verbose != 0 ) 01073 mbedtls_printf( "\n" ); 01074 01075 return( 0 ); 01076 } 01077 01078 #endif /* MBEDTLS_SELF_TEST */ 01079 01080 #endif /* MBEDTLS_CMAC_C */
Generated on Tue Jul 12 2022 14:23:31 by
