Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 */
Generated on Tue Jul 12 2022 13:54:10 by
1.7.2