Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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/platform_util.h"
00026 #include "mbedtls/aes.h"
00027 #include "crys_aesccm_error.h"
00028 
00029 void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
00030 {
00031     memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
00032 }
00033 
00034 void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
00035 {
00036     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
00037 }
00038 
00039 int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
00040                         mbedtls_cipher_id_t cipher,
00041                         const unsigned char *key,
00042                         unsigned int keybits )
00043 {
00044     if( ctx == NULL )
00045         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00046 
00047     if( cipher != MBEDTLS_CIPHER_ID_AES )
00048     {
00049         return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00050     }
00051 
00052     switch( keybits )
00053     {
00054         case 128:
00055         {
00056             memcpy( ctx->cipher_key  , key, keybits / 8 );
00057             ctx->key_size = CRYS_AES_Key128BitSize ;
00058         }
00059         break;
00060         case 192:
00061         case 256:
00062             return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00063         default:
00064             return( MBEDTLS_ERR_CCM_BAD_INPUT );
00065     }
00066 
00067 
00068     return( 0 );
00069 
00070 }
00071 
00072 /*
00073  * Authenticated encryption or decryption
00074  */
00075 
00076 int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
00077                                  const unsigned char *iv, size_t iv_len,
00078                                  const unsigned char *add, size_t add_len,
00079                                  const unsigned char *input,
00080                                  unsigned char *output,
00081                                  unsigned char *tag, size_t tag_len )
00082 
00083 {
00084     CRYSError_t  crys_ret = CRYS_OK;
00085     CRYS_AESCCM_Mac_Res_t  cc_mac_res = { 0 };
00086     int ret = 0;
00087     /*
00088      * Check length requirements: SP800-38C A.1
00089      * Additional requirement: a < 2^16 - 2^8 to simplify the code.
00090      * 'length' checked later (when writing it to the first block)
00091      */
00092     if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
00093         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00094 
00095     if( tag_len > sizeof( cc_mac_res ) )
00096         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00097 
00098     /* Also implies q is within bounds */
00099     if( iv_len < 7 || iv_len > 13 )
00100         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00101 
00102 #if SIZE_MAX > UINT_MAX
00103     if( length > 0xFFFFFFFF || add_len > 0xFFFFFFFF )
00104         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00105 #endif
00106 
00107     crys_ret =  CRYS_AESCCM( SASI_AES_ENCRYPT , ctx->cipher_key , ctx->key_size,
00108                              (uint8_t*)iv, iv_len, (uint8_t*)add, add_len,
00109                              (uint8_t*)input, length, output, tag_len,
00110                              cc_mac_res );
00111     if( crys_ret == CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR )
00112     {
00113         ret = MBEDTLS_ERR_CCM_BAD_INPUT;
00114         goto exit;
00115     }
00116     else if( crys_ret != CRYS_OK )
00117     {
00118         ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00119         goto exit;
00120     }
00121 
00122     memcpy( tag, cc_mac_res, tag_len );
00123 
00124 exit:
00125     return( ret );
00126 
00127 }
00128 
00129 /*
00130  * Authenticated decryption
00131  */
00132 int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
00133                       const unsigned char *iv, size_t iv_len,
00134                       const unsigned char *add, size_t add_len,
00135                       const unsigned char *input, unsigned char *output,
00136                       const unsigned char *tag, size_t tag_len )
00137 
00138 {
00139     CRYSError_t  crys_ret = CRYS_OK;
00140     int ret = 0;
00141     /*
00142      * Check length requirements: SP800-38C A.1
00143      * Additional requirement: a < 2^16 - 2^8 to simplify the code.
00144      * 'length' checked later (when writing it to the first block)
00145      */
00146     if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
00147         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00148 
00149     /* Also implies q is within bounds */
00150     if( iv_len < 7 || iv_len > 13 )
00151         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00152 
00153 #if SIZE_MAX > UINT_MAX
00154     if( length > 0xFFFFFFFF || add_len > 0xFFFFFFFF )
00155         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00156 #endif
00157 
00158     crys_ret =  CRYS_AESCCM( SASI_AES_DECRYPT , ctx->cipher_key , ctx->key_size,
00159                              (uint8_t*)iv, iv_len, (uint8_t*)add, add_len,
00160                              (uint8_t*)input, length, output, tag_len,
00161                              (uint8_t*)tag );
00162     if( crys_ret == CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR )
00163     {
00164        /*
00165         * When CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR is returned,
00166         * no operation has occured, and no need to zeroize output.
00167         * In addition, it could be that the message length is too big,
00168         * returning this error code, and we don't want to overflow
00169         * the output buffer.
00170         */
00171         return( MBEDTLS_ERR_CCM_BAD_INPUT );
00172     }
00173     else if( crys_ret == CRYS_FATAL_ERROR )
00174     {
00175         /*
00176          * Unfortunately, Crys AESCCM returns CRYS_FATAL_ERROR when
00177          * MAC isn't as expected.
00178          */
00179         ret = MBEDTLS_ERR_CCM_AUTH_FAILED;
00180         goto exit;
00181     }
00182     else if( crys_ret != CRYS_OK )
00183     {
00184         ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
00185         goto exit;
00186     }
00187 
00188 exit:
00189     if( ret != 0 )
00190         mbedtls_platform_zeroize( output, length );
00191     return( ret );
00192 
00193 }
00194 
00195 int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
00196                                       const unsigned char *iv, size_t iv_len,
00197                                       const unsigned char *add, size_t add_len,
00198                                       const unsigned char *input,
00199                                       unsigned char *output,
00200                                       unsigned char *tag, size_t tag_len )
00201 {
00202     return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00203 }
00204 
00205 int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
00206                                    const unsigned char *iv, size_t iv_len,
00207                                    const unsigned char *add, size_t add_len,
00208                                    const unsigned char *input,
00209                                    unsigned char *output,
00210                                    const unsigned char *tag, size_t tag_len )
00211 {
00212     return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
00213 }
00214 
00215 #endif