Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cmac.c Source File

cmac.c

Go to the documentation of this file.
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 */