Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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