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