Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ccm_alt.c Source File

ccm_alt.c

00001 /*
00002  *  ccm_alt.c
00003  *
00004  *  Copyright (C) 2018, 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/ccm.h"
00022 #if defined(MBEDTLS_CCM_ALT)
00023 #include <string.h>
00024 #include "mbedtls/platform.h"
00025 #include "mbedtls/aes.h"
00026 
00027 /* Implementation that should never be optimized out by the compiler */
00028 static void mbedtls_zeroize( void *v, size_t n ) {
00029     volatile unsigned char *p = (unsigned char*)v;
00030     while( n-- ) *p++ = 0;
00031 }
00032 
00033 void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
00034 {
00035     memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
00036 }
00037 
00038 void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
00039 {
00040     mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
00041 }
00042 
00043 int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
00044                         mbedtls_cipher_id_t cipher,
00045                         const unsigned char *key,
00046                         unsigned int keybits )
00047 {
00048     if( ctx == NULL )
00049         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00050 
00051     if( cipher != MBEDTLS_CIPHER_ID_AES ||
00052          keybits != 128 )
00053     {
00054         return ( MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE );
00055     }
00056 
00057     memcpy( ctx->cipher_key  , key, keybits / 8 );
00058     ctx->keySize_ID = CRYS_AES_Key128BitSize ;
00059 
00060     return ( 0 );
00061 
00062 }
00063 
00064 /*
00065  * Authenticated encryption or decryption
00066  */
00067 
00068 int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
00069                          const unsigned char *iv, size_t iv_len,
00070                          const unsigned char *add, size_t add_len,
00071                          const unsigned char *input, unsigned char *output,
00072                          unsigned char *tag, size_t tag_len )
00073 
00074 {
00075     CRYSError_t  CrysRet = CRYS_OK;
00076     /*
00077      * Check length requirements: SP800-38C A.1
00078      * Additional requirement: a < 2^16 - 2^8 to simplify the code.
00079      * 'length' checked later (when writing it to the first block)
00080      */
00081     if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
00082         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00083 
00084     /* Also implies q is within bounds */
00085     if( iv_len < 7 || iv_len > 13 )
00086         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00087 
00088 #if SIZE_MAX > UINT_MAX
00089     if( length > 0xFFFFFFFF || add_len > 0xFFFFFFFF )
00090         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00091 #endif
00092 
00093     CrysRet =  CRYS_AESCCM( SASI_AES_ENCRYPT , ctx->cipher_key , ctx->keySize_ID,(uint8_t*)iv, iv_len,
00094                             (uint8_t*)add, add_len,  (uint8_t*)input, length, output, tag_len, tag );
00095     if( CrysRet != CRYS_OK )
00096         return ( MBEDTLS_ERR_CCM_HW_ACCEL_FAILED );
00097 
00098     return ( 0 );
00099 
00100 }
00101 
00102 /*
00103  * Authenticated decryption
00104  */
00105 int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
00106                       const unsigned char *iv, size_t iv_len,
00107                       const unsigned char *add, size_t add_len,
00108                       const unsigned char *input, unsigned char *output,
00109                       const unsigned char *tag, size_t tag_len )
00110 
00111 {
00112     CRYSError_t  CrysRet = CRYS_OK;
00113     /*
00114      * Check length requirements: SP800-38C A.1
00115      * Additional requirement: a < 2^16 - 2^8 to simplify the code.
00116      * 'length' checked later (when writing it to the first block)
00117      */
00118     if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
00119         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00120 
00121     /* Also implies q is within bounds */
00122     if( iv_len < 7 || iv_len > 13 )
00123         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00124 
00125 #if SIZE_MAX > UINT_MAX
00126     if( length > 0xFFFFFFFF || add_len > 0xFFFFFFFF )
00127         return ( MBEDTLS_ERR_CCM_BAD_INPUT );
00128 #endif
00129 
00130     CrysRet =  CRYS_AESCCM( SASI_AES_DECRYPT , ctx->cipher_key , ctx->keySize_ID,(uint8_t*)iv, iv_len,
00131                             (uint8_t*)add, add_len,  (uint8_t*)input, length, output, tag_len, (uint8_t*)tag );
00132     if ( CrysRet != CRYS_OK )
00133         return ( MBEDTLS_ERR_CCM_HW_ACCEL_FAILED );
00134 
00135     return ( 0 );
00136 
00137 }
00138 
00139 #endif