Rtos API example

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 /* 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 bytes 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 = (int)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 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_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_zeroize( K1, sizeof( K1 ) );
00330     mbedtls_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_zeroize( K1, sizeof( K1 ) );
00361     mbedtls_zeroize( K2, sizeof( K2 ) );
00362 
00363     cmac_ctx->unprocessed_len = 0;
00364     mbedtls_zeroize( cmac_ctx->unprocessed_block,
00365                      sizeof( cmac_ctx->unprocessed_block ) );
00366 
00367     mbedtls_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_zeroize( cmac_ctx->unprocessed_block,
00383                      sizeof( cmac_ctx->unprocessed_block ) );
00384     mbedtls_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_zeroize( int_key, sizeof( int_key ) );
00466 
00467     return( ret );
00468 }
00469 #endif /* MBEDTLS_AES_C */
00470 
00471 #if defined(MBEDTLS_SELF_TEST)
00472 /*
00473  * CMAC test data for SP800-38B
00474  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
00475  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
00476  *
00477  * AES-CMAC-PRF-128 test data from RFC 4615
00478  * https://tools.ietf.org/html/rfc4615#page-4
00479  */
00480 
00481 #define NB_CMAC_TESTS_PER_KEY 4
00482 #define NB_PRF_TESTS 3
00483 
00484 #if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
00485 /* All CMAC test inputs are truncated from the same 64 byte buffer. */
00486 static const unsigned char test_message[] = {
00487     /* PT */
00488     0x6b, 0xc1, 0xbe, 0xe2,     0x2e, 0x40, 0x9f, 0x96,
00489     0xe9, 0x3d, 0x7e, 0x11,     0x73, 0x93, 0x17, 0x2a,
00490     0xae, 0x2d, 0x8a, 0x57,     0x1e, 0x03, 0xac, 0x9c,
00491     0x9e, 0xb7, 0x6f, 0xac,     0x45, 0xaf, 0x8e, 0x51,
00492     0x30, 0xc8, 0x1c, 0x46,     0xa3, 0x5c, 0xe4, 0x11,
00493     0xe5, 0xfb, 0xc1, 0x19,     0x1a, 0x0a, 0x52, 0xef,
00494     0xf6, 0x9f, 0x24, 0x45,     0xdf, 0x4f, 0x9b, 0x17,
00495     0xad, 0x2b, 0x41, 0x7b,     0xe6, 0x6c, 0x37, 0x10
00496 };
00497 #endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
00498 
00499 #if defined(MBEDTLS_AES_C)
00500 /* Truncation point of message for AES CMAC tests  */
00501 static const  unsigned int  aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
00502     /* Mlen */
00503     0,
00504     16,
00505     20,
00506     64
00507 };
00508 
00509 /* CMAC-AES128 Test Data */
00510 static const unsigned char aes_128_key[16] = {
00511     0x2b, 0x7e, 0x15, 0x16,     0x28, 0xae, 0xd2, 0xa6,
00512     0xab, 0xf7, 0x15, 0x88,     0x09, 0xcf, 0x4f, 0x3c
00513 };
00514 static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
00515     {
00516         /* K1 */
00517         0xfb, 0xee, 0xd6, 0x18,     0x35, 0x71, 0x33, 0x66,
00518         0x7c, 0x85, 0xe0, 0x8f,     0x72, 0x36, 0xa8, 0xde
00519     },
00520     {
00521         /* K2 */
00522         0xf7, 0xdd, 0xac, 0x30,     0x6a, 0xe2, 0x66, 0xcc,
00523         0xf9, 0x0b, 0xc1, 0x1e,     0xe4, 0x6d, 0x51, 0x3b
00524     }
00525 };
00526 static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
00527     {
00528         /* Example #1 */
00529         0xbb, 0x1d, 0x69, 0x29,     0xe9, 0x59, 0x37, 0x28,
00530         0x7f, 0xa3, 0x7d, 0x12,     0x9b, 0x75, 0x67, 0x46
00531     },
00532     {
00533         /* Example #2 */
00534         0x07, 0x0a, 0x16, 0xb4,     0x6b, 0x4d, 0x41, 0x44,
00535         0xf7, 0x9b, 0xdd, 0x9d,     0xd0, 0x4a, 0x28, 0x7c
00536     },
00537     {
00538         /* Example #3 */
00539         0x7d, 0x85, 0x44, 0x9e,     0xa6, 0xea, 0x19, 0xc8,
00540         0x23, 0xa7, 0xbf, 0x78,     0x83, 0x7d, 0xfa, 0xde
00541     },
00542     {
00543         /* Example #4 */
00544         0x51, 0xf0, 0xbe, 0xbf,     0x7e, 0x3b, 0x9d, 0x92,
00545         0xfc, 0x49, 0x74, 0x17,     0x79, 0x36, 0x3c, 0xfe
00546     }
00547 };
00548 
00549 /* CMAC-AES192 Test Data */
00550 static const unsigned char aes_192_key[24] = {
00551     0x8e, 0x73, 0xb0, 0xf7,     0xda, 0x0e, 0x64, 0x52,
00552     0xc8, 0x10, 0xf3, 0x2b,     0x80, 0x90, 0x79, 0xe5,
00553     0x62, 0xf8, 0xea, 0xd2,     0x52, 0x2c, 0x6b, 0x7b
00554 };
00555 static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
00556     {
00557         /* K1 */
00558         0x44, 0x8a, 0x5b, 0x1c,     0x93, 0x51, 0x4b, 0x27,
00559         0x3e, 0xe6, 0x43, 0x9d,     0xd4, 0xda, 0xa2, 0x96
00560     },
00561     {
00562         /* K2 */
00563         0x89, 0x14, 0xb6, 0x39,     0x26, 0xa2, 0x96, 0x4e,
00564         0x7d, 0xcc, 0x87, 0x3b,     0xa9, 0xb5, 0x45, 0x2c
00565     }
00566 };
00567 static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
00568     {
00569         /* Example #1 */
00570         0xd1, 0x7d, 0xdf, 0x46,     0xad, 0xaa, 0xcd, 0xe5,
00571         0x31, 0xca, 0xc4, 0x83,     0xde, 0x7a, 0x93, 0x67
00572     },
00573     {
00574         /* Example #2 */
00575         0x9e, 0x99, 0xa7, 0xbf,     0x31, 0xe7, 0x10, 0x90,
00576         0x06, 0x62, 0xf6, 0x5e,     0x61, 0x7c, 0x51, 0x84
00577     },
00578     {
00579         /* Example #3 */
00580         0x3d, 0x75, 0xc1, 0x94,     0xed, 0x96, 0x07, 0x04,
00581         0x44, 0xa9, 0xfa, 0x7e,     0xc7, 0x40, 0xec, 0xf8
00582     },
00583     {
00584         /* Example #4 */
00585         0xa1, 0xd5, 0xdf, 0x0e,     0xed, 0x79, 0x0f, 0x79,
00586         0x4d, 0x77, 0x58, 0x96,     0x59, 0xf3, 0x9a, 0x11
00587     }
00588 };
00589 
00590 /* CMAC-AES256 Test Data */
00591 static const unsigned char aes_256_key[32] = {
00592     0x60, 0x3d, 0xeb, 0x10,     0x15, 0xca, 0x71, 0xbe,
00593     0x2b, 0x73, 0xae, 0xf0,     0x85, 0x7d, 0x77, 0x81,
00594     0x1f, 0x35, 0x2c, 0x07,     0x3b, 0x61, 0x08, 0xd7,
00595     0x2d, 0x98, 0x10, 0xa3,     0x09, 0x14, 0xdf, 0xf4
00596 };
00597 static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
00598     {
00599         /* K1 */
00600         0xca, 0xd1, 0xed, 0x03,     0x29, 0x9e, 0xed, 0xac,
00601         0x2e, 0x9a, 0x99, 0x80,     0x86, 0x21, 0x50, 0x2f
00602     },
00603     {
00604         /* K2 */
00605         0x95, 0xa3, 0xda, 0x06,     0x53, 0x3d, 0xdb, 0x58,
00606         0x5d, 0x35, 0x33, 0x01,     0x0c, 0x42, 0xa0, 0xd9
00607     }
00608 };
00609 static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
00610     {
00611         /* Example #1 */
00612         0x02, 0x89, 0x62, 0xf6,     0x1b, 0x7b, 0xf8, 0x9e,
00613         0xfc, 0x6b, 0x55, 0x1f,     0x46, 0x67, 0xd9, 0x83
00614     },
00615     {
00616         /* Example #2 */
00617         0x28, 0xa7, 0x02, 0x3f,     0x45, 0x2e, 0x8f, 0x82,
00618         0xbd, 0x4b, 0xf2, 0x8d,     0x8c, 0x37, 0xc3, 0x5c
00619     },
00620     {
00621         /* Example #3 */
00622         0x15, 0x67, 0x27, 0xdc,     0x08, 0x78, 0x94, 0x4a,
00623         0x02, 0x3c, 0x1f, 0xe0,     0x3b, 0xad, 0x6d, 0x93
00624     },
00625     {
00626         /* Example #4 */
00627         0xe1, 0x99, 0x21, 0x90,     0x54, 0x9f, 0x6e, 0xd5,
00628         0x69, 0x6a, 0x2c, 0x05,     0x6c, 0x31, 0x54, 0x10
00629     }
00630 };
00631 #endif /* MBEDTLS_AES_C */
00632 
00633 #if defined(MBEDTLS_DES_C)
00634 /* Truncation point of message for 3DES CMAC tests  */
00635 static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
00636     0,
00637     16,
00638     20,
00639     32
00640 };
00641 
00642 /* CMAC-TDES (Generation) - 2 Key Test Data */
00643 static const unsigned char des3_2key_key[24] = {
00644     /* Key1 */
00645     0x01, 0x23, 0x45, 0x67,     0x89, 0xab, 0xcd, 0xef,
00646     /* Key2 */
00647     0x23, 0x45, 0x67, 0x89,     0xab, 0xcd, 0xEF, 0x01,
00648     /* Key3 */
00649     0x01, 0x23, 0x45, 0x67,     0x89, 0xab, 0xcd, 0xef
00650 };
00651 static const unsigned char des3_2key_subkeys[2][8] = {
00652     {
00653         /* K1 */
00654         0x0d, 0xd2, 0xcb, 0x7a,     0x3d, 0x88, 0x88, 0xd9
00655     },
00656     {
00657         /* K2 */
00658         0x1b, 0xa5, 0x96, 0xf4,     0x7b, 0x11, 0x11, 0xb2
00659     }
00660 };
00661 static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
00662     {
00663         /* Sample #1 */
00664         0x79, 0xce, 0x52, 0xa7,     0xf7, 0x86, 0xa9, 0x60
00665     },
00666     {
00667         /* Sample #2 */
00668         0xcc, 0x18, 0xa0, 0xb7,     0x9a, 0xf2, 0x41, 0x3b
00669     },
00670     {
00671         /* Sample #3 */
00672         0xc0, 0x6d, 0x37, 0x7e,     0xcd, 0x10, 0x19, 0x69
00673     },
00674     {
00675         /* Sample #4 */
00676         0x9c, 0xd3, 0x35, 0x80,     0xf9, 0xb6, 0x4d, 0xfb
00677     }
00678 };
00679 
00680 /* CMAC-TDES (Generation) - 3 Key Test Data */
00681 static const unsigned char des3_3key_key[24] = {
00682     /* Key1 */
00683     0x01, 0x23, 0x45, 0x67,     0x89, 0xaa, 0xcd, 0xef,
00684     /* Key2 */
00685     0x23, 0x45, 0x67, 0x89,     0xab, 0xcd, 0xef, 0x01,
00686     /* Key3 */
00687     0x45, 0x67, 0x89, 0xab,     0xcd, 0xef, 0x01, 0x23
00688 };
00689 static const unsigned char des3_3key_subkeys[2][8] = {
00690     {
00691         /* K1 */
00692         0x9d, 0x74, 0xe7, 0x39,     0x33, 0x17, 0x96, 0xc0
00693     },
00694     {
00695         /* K2 */
00696         0x3a, 0xe9, 0xce, 0x72,     0x66, 0x2f, 0x2d, 0x9b
00697     }
00698 };
00699 static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
00700     {
00701         /* Sample #1 */
00702         0x7d, 0xb0, 0xd3, 0x7d,     0xf9, 0x36, 0xc5, 0x50
00703     },
00704     {
00705         /* Sample #2 */
00706         0x30, 0x23, 0x9c, 0xf1,     0xf5, 0x2e, 0x66, 0x09
00707     },
00708     {
00709         /* Sample #3 */
00710         0x6c, 0x9f, 0x3e, 0xe4,     0x92, 0x3f, 0x6b, 0xe2
00711     },
00712     {
00713         /* Sample #4 */
00714         0x99, 0x42, 0x9b, 0xd0,     0xbF, 0x79, 0x04, 0xe5
00715     }
00716 };
00717 
00718 #endif /* MBEDTLS_DES_C */
00719 
00720 #if defined(MBEDTLS_AES_C)
00721 /* AES AES-CMAC-PRF-128 Test Data */
00722 static const unsigned char PRFK[] = {
00723     /* Key */
00724     0x00, 0x01, 0x02, 0x03,     0x04, 0x05, 0x06, 0x07,
00725     0x08, 0x09, 0x0a, 0x0b,     0x0c, 0x0d, 0x0e, 0x0f,
00726     0xed, 0xcb
00727 };
00728 
00729 /* Sizes in bytes */
00730 static const size_t PRFKlen[NB_PRF_TESTS] = {
00731     18,
00732     16,
00733     10
00734 };
00735 
00736 /* Message */
00737 static const unsigned char PRFM[] = {
00738     0x00, 0x01, 0x02, 0x03,     0x04, 0x05, 0x06, 0x07,
00739     0x08, 0x09, 0x0a, 0x0b,     0x0c, 0x0d, 0x0e, 0x0f,
00740     0x10, 0x11, 0x12, 0x13
00741 };
00742 
00743 static const unsigned char PRFT[NB_PRF_TESTS][16] = {
00744     {
00745         0x84, 0xa3, 0x48, 0xa4,     0xa4, 0x5d, 0x23, 0x5b,
00746         0xab, 0xff, 0xfc, 0x0d,     0x2b, 0x4d, 0xa0, 0x9a
00747     },
00748     {
00749         0x98, 0x0a, 0xe8, 0x7b,     0x5f, 0x4c, 0x9c, 0x52,
00750         0x14, 0xf5, 0xb6, 0xa8,     0x45, 0x5e, 0x4c, 0x2d
00751     },
00752     {
00753         0x29, 0x0d, 0x9e, 0x11,     0x2e, 0xdb, 0x09, 0xee,
00754         0x14, 0x1f, 0xcf, 0x64,     0xc0, 0xb7, 0x2f, 0x3d
00755     }
00756 };
00757 #endif /* MBEDTLS_AES_C */
00758 
00759 static int cmac_test_subkeys( int verbose,
00760                               const char* testname,
00761                               const unsigned char* key,
00762                               int keybits,
00763                               const unsigned char* subkeys,
00764                               mbedtls_cipher_type_t cipher_type,
00765                               int block_size,
00766                               int num_tests )
00767 {
00768     int i, ret;
00769     mbedtls_cipher_context_t ctx;
00770     const mbedtls_cipher_info_t *cipher_info;
00771     unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
00772     unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
00773 
00774     cipher_info = mbedtls_cipher_info_from_type( cipher_type );
00775     if( cipher_info == NULL )
00776     {
00777         /* Failing at this point must be due to a build issue */
00778         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00779     }
00780 
00781     for( i = 0; i < num_tests; i++ )
00782     {
00783         if( verbose != 0 )
00784             mbedtls_printf( "  %s CMAC subkey #%u: ", testname, i + 1 );
00785 
00786         mbedtls_cipher_init( &ctx );
00787 
00788         if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
00789         {
00790             if( verbose != 0 )
00791                 mbedtls_printf( "test execution failed\n" );
00792 
00793             goto cleanup;
00794         }
00795 
00796         if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
00797                                        MBEDTLS_ENCRYPT ) ) != 0 )
00798         {
00799             if( verbose != 0 )
00800                 mbedtls_printf( "test execution failed\n" );
00801 
00802             goto cleanup;
00803         }
00804 
00805         ret = cmac_generate_subkeys( &ctx, K1, K2 );
00806         if( ret != 0 )
00807         {
00808            if( verbose != 0 )
00809                 mbedtls_printf( "failed\n" );
00810 
00811             goto cleanup;
00812         }
00813 
00814         if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0  ||
00815             ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
00816         {
00817             if( verbose != 0 )
00818                 mbedtls_printf( "failed\n" );
00819 
00820             goto cleanup;
00821         }
00822 
00823         if( verbose != 0 )
00824             mbedtls_printf( "passed\n" );
00825 
00826         mbedtls_cipher_free( &ctx );
00827     }
00828 
00829     goto exit;
00830 
00831 cleanup:
00832     mbedtls_cipher_free( &ctx );
00833 
00834 exit:
00835     return( ret );
00836 }
00837 
00838 static int cmac_test_wth_cipher( int verbose,
00839                                  const char* testname,
00840                                  const unsigned char* key,
00841                                  int keybits,
00842                                  const unsigned char* messages,
00843                                  const unsigned int message_lengths[4],
00844                                  const unsigned char* expected_result,
00845                                  mbedtls_cipher_type_t cipher_type,
00846                                  int block_size,
00847                                  int num_tests )
00848 {
00849     const mbedtls_cipher_info_t *cipher_info;
00850     int i, ret;
00851     unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
00852 
00853     cipher_info = mbedtls_cipher_info_from_type( cipher_type );
00854     if( cipher_info == NULL )
00855     {
00856         /* Failing at this point must be due to a build issue */
00857         ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
00858         goto exit;
00859     }
00860 
00861     for( i = 0; i < num_tests; i++ )
00862     {
00863         if( verbose != 0 )
00864             mbedtls_printf( "  %s CMAC #%u: ", testname, i + 1 );
00865 
00866         if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
00867                                          message_lengths[i], output ) ) != 0 )
00868         {
00869             if( verbose != 0 )
00870                 mbedtls_printf( "failed\n" );
00871             goto exit;
00872         }
00873 
00874         if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
00875         {
00876             if( verbose != 0 )
00877                 mbedtls_printf( "failed\n" );
00878             goto exit;
00879         }
00880 
00881         if( verbose != 0 )
00882             mbedtls_printf( "passed\n" );
00883     }
00884 
00885 exit:
00886     return( ret );
00887 }
00888 
00889 #if defined(MBEDTLS_AES_C)
00890 static int test_aes128_cmac_prf( int verbose )
00891 {
00892     int i;
00893     int ret;
00894     unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
00895 
00896     for( i = 0; i < NB_PRF_TESTS; i++ )
00897     {
00898         mbedtls_printf( "  AES CMAC 128 PRF #%u: ", i );
00899         ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
00900         if( ret != 0 ||
00901             memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
00902         {
00903 
00904             if( verbose != 0 )
00905                 mbedtls_printf( "failed\n" );
00906 
00907             return( ret );
00908         }
00909         else if( verbose != 0 )
00910         {
00911             mbedtls_printf( "passed\n" );
00912         }
00913     }
00914     return( ret );
00915 }
00916 #endif /* MBEDTLS_AES_C */
00917 
00918 int mbedtls_cmac_self_test( int verbose )
00919 {
00920     int ret;
00921 
00922 #if defined(MBEDTLS_AES_C)
00923     /* AES-128 */
00924     if( ( ret = cmac_test_subkeys( verbose,
00925                                    "AES 128",
00926                                    aes_128_key,
00927                                    128,
00928                                    (const unsigned char*)aes_128_subkeys,
00929                                    MBEDTLS_CIPHER_AES_128_ECB,
00930                                    MBEDTLS_AES_BLOCK_SIZE,
00931                                    NB_CMAC_TESTS_PER_KEY ) ) != 0 )
00932     {
00933         return( ret );
00934     }
00935 
00936     if( ( ret = cmac_test_wth_cipher( verbose,
00937                                       "AES 128",
00938                                       aes_128_key,
00939                                       128,
00940                                       test_message,
00941                                       aes_message_lengths,
00942                                       (const unsigned char*)aes_128_expected_result,
00943                                       MBEDTLS_CIPHER_AES_128_ECB,
00944                                       MBEDTLS_AES_BLOCK_SIZE,
00945                                       NB_CMAC_TESTS_PER_KEY ) ) != 0 )
00946     {
00947         return( ret );
00948     }
00949 
00950     /* AES-192 */
00951     if( ( ret = cmac_test_subkeys( verbose,
00952                                    "AES 192",
00953                                    aes_192_key,
00954                                    192,
00955                                    (const unsigned char*)aes_192_subkeys,
00956                                    MBEDTLS_CIPHER_AES_192_ECB,
00957                                    MBEDTLS_AES_BLOCK_SIZE,
00958                                    NB_CMAC_TESTS_PER_KEY ) ) != 0 )
00959     {
00960         return( ret );
00961     }
00962 
00963     if( ( ret = cmac_test_wth_cipher( verbose,
00964                                       "AES 192",
00965                                       aes_192_key,
00966                                       192,
00967                                       test_message,
00968                                       aes_message_lengths,
00969                                       (const unsigned char*)aes_192_expected_result,
00970                                       MBEDTLS_CIPHER_AES_192_ECB,
00971                                       MBEDTLS_AES_BLOCK_SIZE,
00972                                       NB_CMAC_TESTS_PER_KEY ) ) != 0 )
00973     {
00974         return( ret );
00975     }
00976 
00977     /* AES-256 */
00978     if( ( ret = cmac_test_subkeys( verbose,
00979                                    "AES 256",
00980                                    aes_256_key,
00981                                    256,
00982                                    (const unsigned char*)aes_256_subkeys,
00983                                    MBEDTLS_CIPHER_AES_256_ECB,
00984                                    MBEDTLS_AES_BLOCK_SIZE,
00985                                    NB_CMAC_TESTS_PER_KEY ) ) != 0 )
00986     {
00987         return( ret );
00988     }
00989 
00990     if( ( ret = cmac_test_wth_cipher ( verbose,
00991                                        "AES 256",
00992                                        aes_256_key,
00993                                        256,
00994                                        test_message,
00995                                        aes_message_lengths,
00996                                        (const unsigned char*)aes_256_expected_result,
00997                                        MBEDTLS_CIPHER_AES_256_ECB,
00998                                        MBEDTLS_AES_BLOCK_SIZE,
00999                                        NB_CMAC_TESTS_PER_KEY ) ) != 0 )
01000     {
01001         return( ret );
01002     }
01003 #endif /* MBEDTLS_AES_C */
01004 
01005 #if defined(MBEDTLS_DES_C)
01006     /* 3DES 2 key */
01007     if( ( ret = cmac_test_subkeys( verbose,
01008                                    "3DES 2 key",
01009                                    des3_2key_key,
01010                                    192,
01011                                    (const unsigned char*)des3_2key_subkeys,
01012                                    MBEDTLS_CIPHER_DES_EDE3_ECB,
01013                                    MBEDTLS_DES3_BLOCK_SIZE,
01014                                    NB_CMAC_TESTS_PER_KEY ) ) != 0 )
01015     {
01016         return( ret );
01017     }
01018 
01019     if( ( ret = cmac_test_wth_cipher( verbose,
01020                                       "3DES 2 key",
01021                                       des3_2key_key,
01022                                       192,
01023                                       test_message,
01024                                       des3_message_lengths,
01025                                       (const unsigned char*)des3_2key_expected_result,
01026                                       MBEDTLS_CIPHER_DES_EDE3_ECB,
01027                                       MBEDTLS_DES3_BLOCK_SIZE,
01028                                       NB_CMAC_TESTS_PER_KEY ) ) != 0 )
01029     {
01030         return( ret );
01031     }
01032 
01033     /* 3DES 3 key */
01034     if( ( ret = cmac_test_subkeys( verbose,
01035                                    "3DES 3 key",
01036                                    des3_3key_key,
01037                                    192,
01038                                    (const unsigned char*)des3_3key_subkeys,
01039                                    MBEDTLS_CIPHER_DES_EDE3_ECB,
01040                                    MBEDTLS_DES3_BLOCK_SIZE,
01041                                    NB_CMAC_TESTS_PER_KEY ) ) != 0 )
01042     {
01043         return( ret );
01044     }
01045 
01046     if( ( ret = cmac_test_wth_cipher( verbose,
01047                                       "3DES 3 key",
01048                                       des3_3key_key,
01049                                       192,
01050                                       test_message,
01051                                       des3_message_lengths,
01052                                       (const unsigned char*)des3_3key_expected_result,
01053                                       MBEDTLS_CIPHER_DES_EDE3_ECB,
01054                                       MBEDTLS_DES3_BLOCK_SIZE,
01055                                       NB_CMAC_TESTS_PER_KEY ) ) != 0 )
01056     {
01057         return( ret );
01058     }
01059 #endif /* MBEDTLS_DES_C */
01060 
01061 #if defined(MBEDTLS_AES_C)
01062     if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
01063         return( ret );
01064 #endif /* MBEDTLS_AES_C */
01065 
01066     if( verbose != 0 )
01067         mbedtls_printf( "\n" );
01068 
01069     return( 0 );
01070 }
01071 
01072 #endif /* MBEDTLS_SELF_TEST */
01073 
01074 #endif /* MBEDTLS_CMAC_C */