Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cmac_alt.c Source File

cmac_alt.c

00001 /*
00002  *  cmac_alt.c
00003  *
00004  *  Copyright (C) 2019, Arm Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  */
00020 
00021 #include "mbedtls/cmac.h"
00022 #if defined(MBEDTLS_CMAC_ALT)
00023 #include "mbedtls/platform.h"
00024 #include "mbedtls/platform_util.h"
00025 #if defined(MBEDTLS_AES_C)
00026 #include "mbedtls/aes.h"
00027 #endif
00028 #include "ssi_aes_defs.h"
00029 #include <string.h>
00030 
00031 static int init_cc( mbedtls_cmac_context_t *cmac_ctx )
00032 {
00033     int ret = 0;
00034     SaSiAesUserKeyData_t  CC_KeyData;
00035     if( SaSi_AesInit( &cmac_ctx->CC_Context, SASI_AES_ENCRYPT ,
00036                       SASI_AES_MODE_CMAC , SASI_AES_PADDING_NONE  ) != 0 )
00037     {
00038         return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
00039     }
00040 
00041     CC_KeyData.pKey  = cmac_ctx->CC_Key;
00042     CC_KeyData.keySize  = cmac_ctx->CC_keySizeInBytes;
00043 
00044     if( SaSi_AesSetKey( &cmac_ctx->CC_Context, SASI_AES_USER_KEY ,
00045                         &CC_KeyData, sizeof( CC_KeyData ) ) != 0 )
00046     {
00047         ret =  MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00048         goto exit;
00049     }
00050 
00051     cmac_ctx->is_cc_initiated = 1;
00052 
00053 exit:
00054     return( ret );
00055 }
00056 
00057 static int deinit_cc( mbedtls_cmac_context_t *cmac_ctx )
00058 {
00059     if( cmac_ctx->is_cc_initiated == 1  &&
00060         SaSi_AesFree( &cmac_ctx->CC_Context ) != 0 )
00061         return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
00062 
00063     return( 0 );
00064 }
00065 
00066 int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
00067                                 const unsigned char *key, size_t keybits )
00068 {
00069     mbedtls_cmac_context_t *cmac_ctx;
00070     mbedtls_cipher_type_t type;
00071 
00072     if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
00073         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00074 
00075     type = ctx->cipher_info->type;
00076 
00077     switch( type )
00078     {
00079         case MBEDTLS_CIPHER_AES_128_ECB:
00080             break;
00081         case MBEDTLS_CIPHER_AES_192_ECB:
00082         case MBEDTLS_CIPHER_AES_256_ECB:
00083         case MBEDTLS_CIPHER_DES_EDE3_ECB:
00084             return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00085         default:
00086             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00087     }
00088 
00089 
00090     switch( keybits )
00091     {
00092         case 128:
00093             /* Allocated and initialise in the cipher context memory for the CMAC
00094              * context
00095              */
00096             cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
00097             if( cmac_ctx == NULL )
00098                 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
00099             cmac_ctx->CC_keySizeInBytes = ( keybits / 8 );
00100             memcpy( cmac_ctx->CC_Key, key, cmac_ctx->CC_keySizeInBytes );
00101         break;
00102         case 192:
00103         case 256:
00104             return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00105         default:
00106             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00107     }
00108 
00109     ctx->cmac_ctx = cmac_ctx;
00110     return( init_cc( cmac_ctx ) );
00111 }
00112 
00113 int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
00114                                 const unsigned char *input, size_t ilen )
00115 {
00116     mbedtls_cmac_context_t *cmac_ctx;
00117     int ret = 0;
00118     size_t block_size;
00119 
00120     if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
00121         ctx->cmac_ctx == NULL )
00122         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00123 
00124     if( ctx == NULL || ctx->cipher_info == NULL )
00125         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00126 
00127     block_size = ctx->cipher_info->block_size;
00128     if( block_size != SASI_AES_BLOCK_SIZE_IN_BYTES )
00129         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00130 
00131     cmac_ctx = ctx->cmac_ctx;
00132 
00133     /* Is there data still to process from the last call?
00134      */
00135     if( cmac_ctx->unprocessed_len > 0  )
00136     {
00137         const size_t size_to_copy = ilen > ( block_size - cmac_ctx->unprocessed_len ) ?
00138                                     block_size - cmac_ctx->unprocessed_len : ilen;
00139         memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
00140                 input, size_to_copy );
00141         cmac_ctx->unprocessed_len += size_to_copy;
00142         input += size_to_copy;
00143         ilen -= size_to_copy;
00144 
00145         /*
00146          * Process the unproccessed data, in case it reached a full AES block,
00147          * and there is still input data.
00148          */
00149         if( cmac_ctx->unprocessed_len == SASI_AES_BLOCK_SIZE_IN_BYTES && ilen > 0 )
00150         {
00151             if( SaSi_AesBlock( &cmac_ctx->CC_Context, cmac_ctx->unprocessed_block,
00152                               SASI_AES_BLOCK_SIZE_IN_BYTES, NULL ) != 0 )
00153             {
00154                 ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00155                 goto exit;
00156             }
00157             cmac_ctx->unprocessed_len = 0;
00158         }
00159     }
00160 
00161     if( ilen > 0 )
00162     {
00163         const size_t size_to_store = ( ilen % SASI_AES_BLOCK_SIZE_IN_BYTES == 0 ) ?
00164                                      SASI_AES_BLOCK_SIZE_IN_BYTES : ilen % SASI_AES_BLOCK_SIZE_IN_BYTES;
00165         memcpy( cmac_ctx->unprocessed_block,
00166                 input + ilen - size_to_store,
00167                 size_to_store );
00168         cmac_ctx->unprocessed_len = size_to_store;
00169         ilen -= size_to_store;
00170         if( ilen > 0 )
00171         {
00172             if( SaSi_AesBlock( &cmac_ctx->CC_Context, (uint8_t *)input,
00173                                ilen, NULL ) != 0 )
00174             {
00175                 ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00176                 goto exit;
00177             }
00178         }
00179     }
00180 
00181 exit:
00182     if( ret != 0 )
00183     {
00184         deinit_cc( cmac_ctx );
00185         mbedtls_platform_zeroize( cmac_ctx, sizeof( *cmac_ctx ) );
00186         mbedtls_free( cmac_ctx );
00187     }
00188     return( ret );
00189 }
00190 
00191 int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
00192                                 unsigned char *output )
00193 {
00194     mbedtls_cmac_context_t *cmac_ctx;
00195     int ret = 0;
00196     size_t olen = SASI_AES_BLOCK_SIZE_IN_BYTES;
00197 
00198     if( ctx == NULL || ctx->cipher_info == NULL ||
00199         ctx->cmac_ctx == NULL || output == NULL )
00200         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00201 
00202     cmac_ctx = ctx->cmac_ctx;
00203 
00204     if( ( ret = SaSi_AesFinish( &cmac_ctx->CC_Context, cmac_ctx->unprocessed_len,
00205                                 cmac_ctx->unprocessed_block,
00206                                 cmac_ctx->unprocessed_len, output, &olen ) ) != 0 )
00207     {
00208         ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00209         goto exit;
00210     }
00211 
00212 exit:
00213     if( deinit_cc( cmac_ctx ) && ret == 0 )
00214     {
00215         ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00216     }
00217 
00218     return( ret );
00219 }
00220 
00221 int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
00222 {
00223     mbedtls_cmac_context_t *cmac_ctx;
00224 
00225     if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
00226         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00227 
00228     cmac_ctx = ctx->cmac_ctx;
00229 
00230     /* Reset the internal state */
00231     cmac_ctx->unprocessed_len = 0;
00232     mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
00233                               sizeof( cmac_ctx->unprocessed_block ) );
00234 
00235     if( deinit_cc( cmac_ctx ) != 0 )
00236         return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
00237 
00238     return( init_cc( cmac_ctx ) );
00239 }
00240 
00241 int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
00242                          const unsigned char *key, size_t keylen,
00243                          const unsigned char *input, size_t ilen,
00244                          unsigned char *output )
00245 {
00246     int ret = 0;
00247     mbedtls_cipher_context_t ctx;
00248     size_t olen = SASI_AES_BLOCK_SIZE_IN_BYTES;
00249 
00250     if( cipher_info == NULL || key == NULL ||
00251         input == NULL || output == NULL )
00252         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00253 
00254     mbedtls_cipher_init( &ctx );
00255 
00256     if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
00257         goto exit;
00258 
00259     ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
00260     if( ret != 0 )
00261         goto exit;
00262 
00263     if( SaSi_AesFinish( &ctx.cmac_ctx->CC_Context, ilen, ( uint8_t * ) input,
00264                         ilen, output, &olen ) != 0 )
00265    {
00266        ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00267        goto clear_cc;
00268    }
00269 
00270 clear_cc:
00271     if( deinit_cc( ctx.cmac_ctx ) != 0 && ret == 0 )
00272     {
00273         ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00274     }
00275 
00276 exit:
00277     mbedtls_cipher_free( &ctx );
00278 
00279     return( ret );
00280 
00281 }
00282 
00283 #if defined(MBEDTLS_AES_C)
00284 
00285 int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
00286                               const unsigned char *input, size_t in_len,
00287                               unsigned char output[16] )
00288 {
00289     return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00290 }
00291 #endif /* MBEDTLS_AES_C */
00292 
00293 
00294 #endif /* MBEDTLS_CMAC_ALT */