takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecdh_alt.c Source File

ecdh_alt.c

00001 /*
00002  *  ecdh_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/ecdh.h"
00022 #include <string.h>
00023 #include "crys_ecpki_dh.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_mont_api.h"
00029 #include "mbedtls/platform.h"
00030 #include "cc_internal.h"
00031 
00032 
00033 /* Implementation that should never be optimized out by the compiler */
00034 static void mbedtls_zeroize( void *v, size_t n ) {
00035     volatile unsigned char *p = (unsigned char*)v;
00036     while( n-- ) *p++ = 0;
00037 }
00038 
00039 #if defined (MBEDTLS_ECDH_GEN_PUBLIC_ALT)
00040 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
00041                      int ( *f_rng )( void *, unsigned char *, size_t ),
00042                      void *p_rng )
00043 {
00044       int ret = 0;
00045       void* pHeap = NULL;
00046       size_t   heapSize = 0;
00047 
00048       uint32_t public_key_size = (2 * MAX_KEY_SIZE_IN_BYTES + 1);
00049       const CRYS_ECPKI_Domain_t *  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id(  grp->id  ) );
00050       mbedtls_rand_func_container cc_rand = { f_rng, p_rng };
00051 
00052       if ( pDomain )
00053       {
00054           uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
00055           cc_ecc_ws_keygen_params_t* kgParams =  mbedtls_calloc( 1, sizeof( cc_ecc_ws_keygen_params_t ) );
00056 
00057           if ( kgParams == NULL )
00058               return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
00059           pHeap = kgParams;
00060           heapSize = sizeof( cc_ecc_ws_keygen_params_t );
00061 
00062           ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand,
00063                                        pDomain, &kgParams->privKey,
00064                                        &kgParams->pubKey,
00065                                        &kgParams->kgTempData, NULL ) );
00066           if( ret != 0 )
00067           {
00068               goto cleanup;
00069           }
00070 
00071           ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_ExportPublKey( &kgParams->pubKey,
00072                                          CRYS_EC_PointUncompressed ,temp_buf,  &public_key_size ) );
00073           if( ret != 0 )
00074           {
00075               goto cleanup;
00076           }
00077 
00078 
00079           MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( grp, Q, temp_buf, public_key_size ) );
00080           memset ( temp_buf, 0 , sizeof(temp_buf) );
00081 
00082           ret = convert_CrysError_to_mbedtls_err( CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (grp->nbits +7)/8,
00083                                                             kgParams->privKey.PrivKeyDbBuff,
00084                                                             4*((((grp->nbits +7)/8)+3)/4) ) );
00085           if( ret != 0 )
00086           {
00087               mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
00088               goto cleanup;
00089           }
00090 
00091           MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary( d, temp_buf, (grp->nbits +7)/8 ) );
00092           mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
00093       }
00094 
00095       /* if CRYS_ECPKI_GetEcDomain returns NULL, then the given curve is either Montgomery 25519
00096        * or another curve which is not supported by CC310*/
00097       else if ( grp->id  ==  MBEDTLS_ECP_DP_CURVE25519 )
00098       {
00099           size_t priv_key_size =  public_key_size = CURVE_25519_KEY_SIZE ;
00100 
00101           cc_ecc_25519_keygen_params_t* kgParams =  mbedtls_calloc( 1, sizeof(cc_ecc_25519_keygen_params_t) );
00102 
00103           if ( kgParams == NULL )
00104               return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
00105           pHeap = ( uint8_t* )kgParams;
00106           heapSize = sizeof(cc_ecc_25519_keygen_params_t);
00107 
00108           ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_KeyPair( kgParams->pubKey, ( size_t* )&public_key_size, kgParams->privKey,
00109                                     &priv_key_size, &cc_rand, convert_mbedtls_to_cc_rand,
00110                                     &kgParams->kgTempData ) );
00111           if( ret != 0 )
00112           {
00113               goto cleanup;
00114           }
00115 
00116           MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, kgParams->privKey, priv_key_size ) );
00117           MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(  &Q->X , kgParams->pubKey, public_key_size ) );
00118           MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Q->Z , 1 ) );
00119       }
00120       else
00121           ret =  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
00122 
00123 cleanup:
00124 
00125     if ( pHeap )
00126     {
00127         mbedtls_zeroize( pHeap, heapSize );
00128         mbedtls_free( pHeap );
00129     }
00130 
00131     return ( ret );
00132 }
00133 #endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
00134 
00135 /*
00136  * Compute shared secret (SEC1 3.3.1)
00137  */
00138 #if defined (MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
00139 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
00140                          const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
00141                          int (*f_rng)(void *, unsigned char *, size_t),
00142                          void *p_rng )
00143 {
00144     int ret;
00145     void* pHeap = NULL;
00146     size_t   heapSize = 0;
00147 
00148     size_t   public_key_size = (grp->nbits +7)/8 ;
00149     const CRYS_ECPKI_Domain_t *  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id  ) );
00150     uint32_t secret_size =  ( ( grp->nbits  + 7 ) / 8 ) ;
00151     const uint32_t secret_size_in_heap = secret_size;
00152     uint8_t* secret = mbedtls_calloc( 1, secret_size_in_heap );
00153     if ( secret == NULL )
00154         return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
00155 
00156     /*
00157      * Make sure Q is a valid pubkey before using it
00158      */
00159     MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
00160     if ( pDomain )
00161     {
00162         uint8_t  temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
00163         cc_ecc_ws_comp_shared_params_t* ecdhParams =  mbedtls_calloc( 1, sizeof(cc_ecc_ws_comp_shared_params_t) );
00164 
00165         if ( ecdhParams == NULL )
00166         {
00167             ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
00168             goto cleanup;
00169         }
00170 
00171         pHeap = ecdhParams;
00172         heapSize = sizeof(cc_ecc_ws_comp_shared_params_t);
00173 
00174 
00175         MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
00176                                                 &public_key_size, temp_buf, sizeof(temp_buf) ) );
00177 
00178         ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPublKey( pDomain, temp_buf, public_key_size,
00179                                                                          &ecdhParams->pubKey ) );
00180         if ( ret != 0 )
00181         {
00182             goto cleanup;
00183         }
00184 
00185         memset ( temp_buf, 0, sizeof(temp_buf)  );
00186 
00187         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) );
00188 
00189         ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPrivKey( pDomain,
00190                                                                          temp_buf,
00191                                                                          mbedtls_mpi_size( d ),
00192                                                                          &ecdhParams->privKey ) );
00193         mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
00194         if ( ret != 0 )
00195         {
00196             goto cleanup;
00197         }
00198 
00199         ret = convert_CrysError_to_mbedtls_err( CRYS_ECDH_SVDP_DH( &ecdhParams->pubKey, &ecdhParams->privKey,
00200                                                                    secret, &secret_size,
00201                                                                    &ecdhParams->ecdhTempData ) );
00202         if ( ret != 0 )
00203         {
00204             goto cleanup;
00205         }
00206     }
00207     else if ( grp->id  ==  MBEDTLS_ECP_DP_CURVE25519 )
00208     {
00209         cc_ecc_25519_comp_shared_params_t* ecdhParams =  mbedtls_calloc( 1, sizeof(cc_ecc_25519_comp_shared_params_t) );
00210         if ( ecdhParams == NULL )
00211         {
00212             ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
00213             goto cleanup;
00214         }
00215 
00216         pHeap = ecdhParams;
00217         heapSize = sizeof(cc_ecc_25519_comp_shared_params_t);
00218 
00219 
00220         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, ecdhParams->privKey, mbedtls_mpi_size( d ) ) ) ;
00221         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &Q->X , ecdhParams->pubKey, public_key_size ) );
00222 
00223         ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_Scalarmult( secret, ( size_t* )&secret_size,
00224                                                                         ecdhParams->privKey, CURVE_25519_KEY_SIZE ,
00225                                                                         ecdhParams->pubKey, CURVE_25519_KEY_SIZE ,
00226                                                                         &ecdhParams->kgTempData ) );
00227         if ( ret != 0 )
00228         {
00229             goto cleanup;
00230         }
00231     }
00232     else
00233     {
00234         ret =  MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
00235         goto cleanup;
00236     }
00237 
00238     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( z, secret, secret_size ) );
00239 
00240 cleanup:
00241 
00242     if ( pHeap )
00243     {
00244         mbedtls_zeroize( pHeap, heapSize );
00245         mbedtls_free ( pHeap );
00246     }
00247 
00248     if ( secret )
00249     {
00250         mbedtls_zeroize( secret, secret_size_in_heap );
00251         mbedtls_free ( secret );
00252     }
00253 
00254     return ( ret );
00255 }
00256 #endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */