takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecdsa_alt.c Source File

ecdsa_alt.c

00001 /*
00002  *  ecdsa_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/ecdsa.h"
00022 #include <string.h>
00023 #include "crys_ecpki_ecdsa.h"
00024 #include "crys_ecpki_build.h"
00025 #include "crys_common.h"
00026 #include "crys_ecpki_kg.h"
00027 #include "crys_ecpki_domain.h"
00028 #include "crys_ec_edw_api.h"
00029 #include "mbedtls/platform.h"
00030 #include "cc_internal.h"
00031 
00032 /* Implementation that should never be optimized out by the compiler */
00033 static void mbedtls_zeroize( void *v, size_t n ) {
00034     volatile unsigned char *p = (unsigned char*)v;
00035     while( n-- ) *p++ = 0;
00036 }
00037 
00038 static CRYS_ECPKI_HASH_OpMode_t  message_size_to_hash_mode( size_t blen )
00039 {
00040     CRYS_ECPKI_HASH_OpMode_t  hash_mode;
00041     switch( blen )
00042     {
00043     case CRYS_HASH_SHA1_DIGEST_SIZE_IN_WORDS*sizeof(uint32_t):
00044             hash_mode = CRYS_ECPKI_AFTER_HASH_SHA1_mode ;
00045     break;
00046     case CRYS_HASH_SHA224_DIGEST_SIZE_IN_WORDS*sizeof(uint32_t):
00047             hash_mode = CRYS_ECPKI_AFTER_HASH_SHA224_mode ;
00048     break;
00049     case CRYS_HASH_SHA256_DIGEST_SIZE_IN_WORDS*sizeof(uint32_t):
00050             hash_mode = CRYS_ECPKI_AFTER_HASH_SHA256_mode ;
00051     break;
00052     case CRYS_HASH_SHA384_DIGEST_SIZE_IN_WORDS*sizeof(uint32_t):
00053             hash_mode = CRYS_ECPKI_AFTER_HASH_SHA384_mode ;
00054     break;
00055     case CRYS_HASH_SHA512_DIGEST_SIZE_IN_WORDS*sizeof(uint32_t):
00056             hash_mode = CRYS_ECPKI_AFTER_HASH_SHA512_mode ;
00057     break;
00058     default:
00059         hash_mode = CRYS_ECPKI_HASH_OpModeLast ;
00060     }
00061 
00062     return hash_mode;
00063 }
00064 
00065 #if defined(MBEDTLS_ECDSA_SIGN_ALT)
00066 int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
00067                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
00068                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
00069 {
00070     int ret = 0;
00071     CRYSError_t  CrysRet = CRYS_OK;
00072     void* pHeap = NULL;
00073     size_t heapSize = 0;
00074     uint8_t* pSignature = NULL;
00075     CRYS_ECPKI_HASH_OpMode_t  hash_mode = message_size_to_hash_mode( blen );
00076     uint32_t signature_size =  ( ( grp->nbits  + 7 ) / 8 ) *2;
00077     const uint32_t signature_size_for_heap = signature_size;
00078     mbedtls_rand_func_container cc_rand = { f_rng, p_rng };
00079     const CRYS_ECPKI_Domain_t *  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id  ) );
00080 
00081 #if SIZE_MAX > UINT_MAX
00082     if( blen > 0xFFFFFFFF )
00083     {
00084         return ( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
00085     }
00086 #endif
00087 
00088     if ( pDomain != NULL )
00089     {
00090         uint8_t temp_buf[ MAX_KEY_SIZE_IN_BYTES ] = {0};
00091         cc_ecc_ws_sign_params_t* signParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_sign_params_t) );
00092         if ( signParams == NULL)
00093             return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
00094         pHeap = signParams;
00095         heapSize = sizeof(cc_ecc_ws_sign_params_t);
00096 
00097         pSignature = mbedtls_calloc( 1, signature_size_for_heap );
00098         if ( pSignature == NULL)
00099         {
00100             ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
00101             goto cleanup;
00102         }
00103 
00104         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) );
00105 
00106         CrysRet = CRYS_ECPKI_BuildPrivKey( pDomain,
00107                                        temp_buf,
00108                                        mbedtls_mpi_size( d ),
00109                                        &signParams->privKey);
00110         if( CrysRet != CRYS_OK )
00111         {
00112             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00113             mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
00114             goto cleanup;
00115         }
00116 
00117         CrysRet =  CRYS_ECDSA_Sign( &cc_rand,
00118                                 convert_mbedtls_to_cc_rand,
00119                                 &signParams->signContext,
00120                                 &signParams->privKey,
00121                                 hash_mode,
00122                                 (uint8_t*)buf,
00123                                 blen,
00124                                 pSignature,
00125                                 &signature_size );
00126         mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
00127         if( CrysRet != CRYS_OK )
00128         {
00129             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00130             goto cleanup;
00131         }
00132     }
00133     else
00134     {
00135         ret =  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
00136         goto cleanup;
00137     }
00138 
00139     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( r, pSignature, ( ( grp->nbits  + 7 ) / 8 ) ) );
00140 
00141     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( s, pSignature + ( ( grp->nbits  + 7 ) / 8 ), ( ( grp->nbits  + 7 ) / 8 ) ) );
00142 
00143 
00144 cleanup:
00145 
00146     if ( pHeap )
00147     {
00148         mbedtls_zeroize( pHeap, heapSize );
00149         mbedtls_free( pHeap );
00150     }
00151 
00152     if( pSignature )
00153     {
00154         mbedtls_zeroize( pSignature, signature_size_for_heap );
00155         mbedtls_free( pSignature );
00156 
00157     }
00158 
00159     return ( ret ) ;
00160 }
00161 #endif /* MBEDTLS_ECDSA_SIGN_ALT*/
00162 
00163 #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
00164 //need to normalize the coordinates
00165 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
00166                   const unsigned char *buf, size_t blen,
00167                   const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
00168 {
00169     int ret = 0;
00170     CRYSError_t  CrysRet = CRYS_OK;
00171     void* pHeap = NULL;
00172     size_t heapSize = 0;
00173     uint8_t * pSignature = NULL;
00174     CRYS_ECPKI_HASH_OpMode_t  hash_mode = message_size_to_hash_mode( blen );
00175     size_t temp_size = 0;
00176     uint32_t signature_size = ( ( grp->nbits  + 7 ) / 8 ) * 2;
00177     const CRYS_ECPKI_Domain_t *  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id  ) );
00178 
00179 #if SIZE_MAX > UINT_MAX
00180     if( blen > 0xFFFFFFFF )
00181     {
00182         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
00183     }
00184 #endif
00185 
00186     if ( pDomain )
00187     {
00188         uint8_t temp_buf[ 2*MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
00189 
00190         cc_ecc_ws_verify_params_t* verifyParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_verify_params_t) );
00191         if ( verifyParams == NULL)
00192             return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
00193         pHeap = verifyParams;
00194         heapSize = sizeof(cc_ecc_ws_verify_params_t);
00195 
00196         pSignature = mbedtls_calloc( 1, signature_size );
00197         if ( pSignature == NULL)
00198         {
00199             ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
00200             goto cleanup;
00201         }
00202 
00203         MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
00204                                         &temp_size, temp_buf, sizeof(temp_buf) ) );
00205 
00206         CrysRet = CRYS_ECPKI_BuildPublKey(pDomain, temp_buf, temp_size, &verifyParams->pubKey);
00207         if( CrysRet != CRYS_OK )
00208         {
00209             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00210             goto cleanup;
00211         }
00212 
00213         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( r, pSignature, ( ( grp->nbits  + 7 ) / 8 )  ) );
00214         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( s, pSignature + ( ( grp->nbits  + 7 ) / 8 ), ( ( grp->nbits  + 7 ) / 8 ) ) );
00215         CrysRet =  CRYS_ECDSA_Verify ( &verifyParams->verifyContext,
00216                                        &verifyParams->pubKey,
00217                                        hash_mode,
00218                                        pSignature,
00219                                        signature_size,
00220                                        (uint8_t*)buf,
00221                                        blen );
00222         if( CrysRet != CRYS_OK )
00223         {
00224             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00225             goto cleanup;
00226         }
00227     }
00228     else
00229         ret =  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
00230 
00231 cleanup:
00232 
00233     if( pHeap )
00234     {
00235         mbedtls_zeroize( pHeap, heapSize );
00236         mbedtls_free( pHeap );
00237     }
00238 
00239     if( pSignature )
00240     {
00241         mbedtls_zeroize( pSignature, signature_size );
00242         mbedtls_free( pSignature );
00243 
00244     }
00245 
00246     return ret;
00247 }
00248 #endif /* MBEDTLS_ECDSA_VERIFY_ALT */
00249 
00250 #if defined(MBEDTLS_ECDSA_GENKEY_ALT)
00251 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
00252                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
00253 {
00254     int ret = 0;
00255     CRYSError_t  CrysRet = CRYS_OK;
00256     void* pHeap = NULL;
00257     size_t heapSize = 0;
00258     uint32_t key_size = 2*MAX_KEY_SIZE_IN_BYTES + 1;
00259     const CRYS_ECPKI_Domain_t *  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( gid ) );
00260     mbedtls_rand_func_container cc_rand = { f_rng, p_rng };
00261 
00262 
00263     if ( pDomain )
00264     {
00265         uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
00266 
00267         cc_ecc_ws_keygen_params_t* kgParams =  mbedtls_calloc( 1, sizeof(cc_ecc_ws_keygen_params_t) );
00268         if ( kgParams == NULL )
00269             return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
00270 
00271         pHeap = kgParams;
00272         heapSize = sizeof(cc_ecc_ws_keygen_params_t);
00273 
00274         CrysRet =  CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand, pDomain,
00275                                           &kgParams->privKey, &kgParams->pubKey,
00276                                           &kgParams->kgTempData, NULL );
00277         if ( CrysRet != CRYS_OK )
00278         {
00279             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00280             goto cleanup;
00281         }
00282 
00283         MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp , gid ) );
00284 
00285         CrysRet = CRYS_ECPKI_ExportPublKey( &kgParams->pubKey, CRYS_EC_PointUncompressed , temp_buf,  &key_size );
00286         if ( CrysRet != CRYS_OK )
00287         {
00288             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00289             goto cleanup;
00290         }
00291 
00292         ret = mbedtls_ecp_point_read_binary( &ctx->grp , &ctx->Q , temp_buf, key_size );
00293         if ( ret != 0 )
00294             goto cleanup;
00295 
00296         memset ( temp_buf, 0 , sizeof(temp_buf) );
00297 
00298         CrysRet = CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (ctx->grp .nbits +7)/8,
00299                                                                kgParams->privKey.PrivKeyDbBuff,
00300                                                                4*((((ctx->grp .nbits +7)/8)+3)/4) );
00301         if ( CrysRet != CRYS_OK )
00302         {
00303             ret = convert_CrysError_to_mbedtls_err( CrysRet );
00304             mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
00305             goto cleanup;
00306         }
00307 
00308         ret = mbedtls_mpi_read_binary( &ctx->d , temp_buf, (ctx->grp .nbits +7)/8 );
00309         mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
00310         if ( ret != 0 )
00311         {
00312             goto cleanup;
00313         }
00314     }
00315     else
00316         ret =  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
00317 
00318 
00319 cleanup:
00320     if ( pHeap )
00321     {
00322         mbedtls_zeroize( pHeap, heapSize );
00323         mbedtls_free ( pHeap );
00324     }
00325     return ( ret );
00326 }
00327 #endif /* MBEDTLS_ECDSA_GENKEY_ALT */