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