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