takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * ecdh_alt.c
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * Copyright (C) 2018, Arm Limited, All Rights Reserved
kadonotakashi 0:8fdf9a60065b 5 * SPDX-License-Identifier: Apache-2.0
kadonotakashi 0:8fdf9a60065b 6 *
kadonotakashi 0:8fdf9a60065b 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kadonotakashi 0:8fdf9a60065b 8 * not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 9 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 12 *
kadonotakashi 0:8fdf9a60065b 13 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kadonotakashi 0:8fdf9a60065b 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 16 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 17 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 */
kadonotakashi 0:8fdf9a60065b 20
kadonotakashi 0:8fdf9a60065b 21 #include "mbedtls/ecdh.h"
kadonotakashi 0:8fdf9a60065b 22 #include <string.h>
kadonotakashi 0:8fdf9a60065b 23 #include "crys_ecpki_dh.h"
kadonotakashi 0:8fdf9a60065b 24 #include "crys_ecpki_build.h"
kadonotakashi 0:8fdf9a60065b 25 #include "crys_common.h"
kadonotakashi 0:8fdf9a60065b 26 #include "crys_ecpki_kg.h"
kadonotakashi 0:8fdf9a60065b 27 #include "crys_ecpki_domain.h"
kadonotakashi 0:8fdf9a60065b 28 #include "crys_ec_mont_api.h"
kadonotakashi 0:8fdf9a60065b 29 #include "mbedtls/platform.h"
kadonotakashi 0:8fdf9a60065b 30 #include "cc_internal.h"
kadonotakashi 0:8fdf9a60065b 31
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 /* Implementation that should never be optimized out by the compiler */
kadonotakashi 0:8fdf9a60065b 34 static void mbedtls_zeroize( void *v, size_t n ) {
kadonotakashi 0:8fdf9a60065b 35 volatile unsigned char *p = (unsigned char*)v;
kadonotakashi 0:8fdf9a60065b 36 while( n-- ) *p++ = 0;
kadonotakashi 0:8fdf9a60065b 37 }
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 #if defined (MBEDTLS_ECDH_GEN_PUBLIC_ALT)
kadonotakashi 0:8fdf9a60065b 40 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
kadonotakashi 0:8fdf9a60065b 41 int ( *f_rng )( void *, unsigned char *, size_t ),
kadonotakashi 0:8fdf9a60065b 42 void *p_rng )
kadonotakashi 0:8fdf9a60065b 43 {
kadonotakashi 0:8fdf9a60065b 44 int ret = 0;
kadonotakashi 0:8fdf9a60065b 45 void* pHeap = NULL;
kadonotakashi 0:8fdf9a60065b 46 size_t heapSize = 0;
kadonotakashi 0:8fdf9a60065b 47
kadonotakashi 0:8fdf9a60065b 48 uint32_t public_key_size = (2 * MAX_KEY_SIZE_IN_BYTES + 1);
kadonotakashi 0:8fdf9a60065b 49 const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) );
kadonotakashi 0:8fdf9a60065b 50 mbedtls_rand_func_container cc_rand = { f_rng, p_rng };
kadonotakashi 0:8fdf9a60065b 51
kadonotakashi 0:8fdf9a60065b 52 if ( pDomain )
kadonotakashi 0:8fdf9a60065b 53 {
kadonotakashi 0:8fdf9a60065b 54 uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
kadonotakashi 0:8fdf9a60065b 55 cc_ecc_ws_keygen_params_t* kgParams = mbedtls_calloc( 1, sizeof( cc_ecc_ws_keygen_params_t ) );
kadonotakashi 0:8fdf9a60065b 56
kadonotakashi 0:8fdf9a60065b 57 if ( kgParams == NULL )
kadonotakashi 0:8fdf9a60065b 58 return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
kadonotakashi 0:8fdf9a60065b 59 pHeap = kgParams;
kadonotakashi 0:8fdf9a60065b 60 heapSize = sizeof( cc_ecc_ws_keygen_params_t );
kadonotakashi 0:8fdf9a60065b 61
kadonotakashi 0:8fdf9a60065b 62 ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand,
kadonotakashi 0:8fdf9a60065b 63 pDomain, &kgParams->privKey,
kadonotakashi 0:8fdf9a60065b 64 &kgParams->pubKey,
kadonotakashi 0:8fdf9a60065b 65 &kgParams->kgTempData, NULL ) );
kadonotakashi 0:8fdf9a60065b 66 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 67 {
kadonotakashi 0:8fdf9a60065b 68 goto cleanup;
kadonotakashi 0:8fdf9a60065b 69 }
kadonotakashi 0:8fdf9a60065b 70
kadonotakashi 0:8fdf9a60065b 71 ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_ExportPublKey( &kgParams->pubKey,
kadonotakashi 0:8fdf9a60065b 72 CRYS_EC_PointUncompressed,temp_buf, &public_key_size ) );
kadonotakashi 0:8fdf9a60065b 73 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 74 {
kadonotakashi 0:8fdf9a60065b 75 goto cleanup;
kadonotakashi 0:8fdf9a60065b 76 }
kadonotakashi 0:8fdf9a60065b 77
kadonotakashi 0:8fdf9a60065b 78
kadonotakashi 0:8fdf9a60065b 79 MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( grp, Q, temp_buf, public_key_size ) );
kadonotakashi 0:8fdf9a60065b 80 memset ( temp_buf, 0 , sizeof(temp_buf) );
kadonotakashi 0:8fdf9a60065b 81
kadonotakashi 0:8fdf9a60065b 82 ret = convert_CrysError_to_mbedtls_err( CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (grp->nbits+7)/8,
kadonotakashi 0:8fdf9a60065b 83 kgParams->privKey.PrivKeyDbBuff,
kadonotakashi 0:8fdf9a60065b 84 4*((((grp->nbits+7)/8)+3)/4) ) );
kadonotakashi 0:8fdf9a60065b 85 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 86 {
kadonotakashi 0:8fdf9a60065b 87 mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
kadonotakashi 0:8fdf9a60065b 88 goto cleanup;
kadonotakashi 0:8fdf9a60065b 89 }
kadonotakashi 0:8fdf9a60065b 90
kadonotakashi 0:8fdf9a60065b 91 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary( d, temp_buf, (grp->nbits+7)/8 ) );
kadonotakashi 0:8fdf9a60065b 92 mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
kadonotakashi 0:8fdf9a60065b 93 }
kadonotakashi 0:8fdf9a60065b 94
kadonotakashi 0:8fdf9a60065b 95 /* if CRYS_ECPKI_GetEcDomain returns NULL, then the given curve is either Montgomery 25519
kadonotakashi 0:8fdf9a60065b 96 * or another curve which is not supported by CC310*/
kadonotakashi 0:8fdf9a60065b 97 else if ( grp->id == MBEDTLS_ECP_DP_CURVE25519 )
kadonotakashi 0:8fdf9a60065b 98 {
kadonotakashi 0:8fdf9a60065b 99 size_t priv_key_size = public_key_size = CURVE_25519_KEY_SIZE ;
kadonotakashi 0:8fdf9a60065b 100
kadonotakashi 0:8fdf9a60065b 101 cc_ecc_25519_keygen_params_t* kgParams = mbedtls_calloc( 1, sizeof(cc_ecc_25519_keygen_params_t) );
kadonotakashi 0:8fdf9a60065b 102
kadonotakashi 0:8fdf9a60065b 103 if ( kgParams == NULL )
kadonotakashi 0:8fdf9a60065b 104 return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
kadonotakashi 0:8fdf9a60065b 105 pHeap = ( uint8_t* )kgParams;
kadonotakashi 0:8fdf9a60065b 106 heapSize = sizeof(cc_ecc_25519_keygen_params_t);
kadonotakashi 0:8fdf9a60065b 107
kadonotakashi 0:8fdf9a60065b 108 ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_KeyPair( kgParams->pubKey, ( size_t* )&public_key_size, kgParams->privKey,
kadonotakashi 0:8fdf9a60065b 109 &priv_key_size, &cc_rand, convert_mbedtls_to_cc_rand,
kadonotakashi 0:8fdf9a60065b 110 &kgParams->kgTempData ) );
kadonotakashi 0:8fdf9a60065b 111 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 112 {
kadonotakashi 0:8fdf9a60065b 113 goto cleanup;
kadonotakashi 0:8fdf9a60065b 114 }
kadonotakashi 0:8fdf9a60065b 115
kadonotakashi 0:8fdf9a60065b 116 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, kgParams->privKey, priv_key_size ) );
kadonotakashi 0:8fdf9a60065b 117 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Q->X, kgParams->pubKey, public_key_size ) );
kadonotakashi 0:8fdf9a60065b 118 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Q->Z, 1 ) );
kadonotakashi 0:8fdf9a60065b 119 }
kadonotakashi 0:8fdf9a60065b 120 else
kadonotakashi 0:8fdf9a60065b 121 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
kadonotakashi 0:8fdf9a60065b 122
kadonotakashi 0:8fdf9a60065b 123 cleanup:
kadonotakashi 0:8fdf9a60065b 124
kadonotakashi 0:8fdf9a60065b 125 if ( pHeap )
kadonotakashi 0:8fdf9a60065b 126 {
kadonotakashi 0:8fdf9a60065b 127 mbedtls_zeroize( pHeap, heapSize );
kadonotakashi 0:8fdf9a60065b 128 mbedtls_free( pHeap );
kadonotakashi 0:8fdf9a60065b 129 }
kadonotakashi 0:8fdf9a60065b 130
kadonotakashi 0:8fdf9a60065b 131 return ( ret );
kadonotakashi 0:8fdf9a60065b 132 }
kadonotakashi 0:8fdf9a60065b 133 #endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
kadonotakashi 0:8fdf9a60065b 134
kadonotakashi 0:8fdf9a60065b 135 /*
kadonotakashi 0:8fdf9a60065b 136 * Compute shared secret (SEC1 3.3.1)
kadonotakashi 0:8fdf9a60065b 137 */
kadonotakashi 0:8fdf9a60065b 138 #if defined (MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
kadonotakashi 0:8fdf9a60065b 139 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
kadonotakashi 0:8fdf9a60065b 140 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
kadonotakashi 0:8fdf9a60065b 141 int (*f_rng)(void *, unsigned char *, size_t),
kadonotakashi 0:8fdf9a60065b 142 void *p_rng )
kadonotakashi 0:8fdf9a60065b 143 {
kadonotakashi 0:8fdf9a60065b 144 int ret;
kadonotakashi 0:8fdf9a60065b 145 void* pHeap = NULL;
kadonotakashi 0:8fdf9a60065b 146 size_t heapSize = 0;
kadonotakashi 0:8fdf9a60065b 147
kadonotakashi 0:8fdf9a60065b 148 size_t public_key_size = (grp->nbits+7)/8 ;
kadonotakashi 0:8fdf9a60065b 149 const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) );
kadonotakashi 0:8fdf9a60065b 150 uint32_t secret_size = ( ( grp->nbits + 7 ) / 8 ) ;
kadonotakashi 0:8fdf9a60065b 151 const uint32_t secret_size_in_heap = secret_size;
kadonotakashi 0:8fdf9a60065b 152 uint8_t* secret = mbedtls_calloc( 1, secret_size_in_heap );
kadonotakashi 0:8fdf9a60065b 153 if ( secret == NULL )
kadonotakashi 0:8fdf9a60065b 154 return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
kadonotakashi 0:8fdf9a60065b 155
kadonotakashi 0:8fdf9a60065b 156 /*
kadonotakashi 0:8fdf9a60065b 157 * Make sure Q is a valid pubkey before using it
kadonotakashi 0:8fdf9a60065b 158 */
kadonotakashi 0:8fdf9a60065b 159 MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
kadonotakashi 0:8fdf9a60065b 160 if ( pDomain )
kadonotakashi 0:8fdf9a60065b 161 {
kadonotakashi 0:8fdf9a60065b 162 uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
kadonotakashi 0:8fdf9a60065b 163 cc_ecc_ws_comp_shared_params_t* ecdhParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_comp_shared_params_t) );
kadonotakashi 0:8fdf9a60065b 164
kadonotakashi 0:8fdf9a60065b 165 if ( ecdhParams == NULL )
kadonotakashi 0:8fdf9a60065b 166 {
kadonotakashi 0:8fdf9a60065b 167 ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
kadonotakashi 0:8fdf9a60065b 168 goto cleanup;
kadonotakashi 0:8fdf9a60065b 169 }
kadonotakashi 0:8fdf9a60065b 170
kadonotakashi 0:8fdf9a60065b 171 pHeap = ecdhParams;
kadonotakashi 0:8fdf9a60065b 172 heapSize = sizeof(cc_ecc_ws_comp_shared_params_t);
kadonotakashi 0:8fdf9a60065b 173
kadonotakashi 0:8fdf9a60065b 174
kadonotakashi 0:8fdf9a60065b 175 MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
kadonotakashi 0:8fdf9a60065b 176 &public_key_size, temp_buf, sizeof(temp_buf) ) );
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPublKey( pDomain, temp_buf, public_key_size,
kadonotakashi 0:8fdf9a60065b 179 &ecdhParams->pubKey ) );
kadonotakashi 0:8fdf9a60065b 180 if ( ret != 0 )
kadonotakashi 0:8fdf9a60065b 181 {
kadonotakashi 0:8fdf9a60065b 182 goto cleanup;
kadonotakashi 0:8fdf9a60065b 183 }
kadonotakashi 0:8fdf9a60065b 184
kadonotakashi 0:8fdf9a60065b 185 memset ( temp_buf, 0, sizeof(temp_buf) );
kadonotakashi 0:8fdf9a60065b 186
kadonotakashi 0:8fdf9a60065b 187 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) );
kadonotakashi 0:8fdf9a60065b 188
kadonotakashi 0:8fdf9a60065b 189 ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPrivKey( pDomain,
kadonotakashi 0:8fdf9a60065b 190 temp_buf,
kadonotakashi 0:8fdf9a60065b 191 mbedtls_mpi_size( d ),
kadonotakashi 0:8fdf9a60065b 192 &ecdhParams->privKey ) );
kadonotakashi 0:8fdf9a60065b 193 mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
kadonotakashi 0:8fdf9a60065b 194 if ( ret != 0 )
kadonotakashi 0:8fdf9a60065b 195 {
kadonotakashi 0:8fdf9a60065b 196 goto cleanup;
kadonotakashi 0:8fdf9a60065b 197 }
kadonotakashi 0:8fdf9a60065b 198
kadonotakashi 0:8fdf9a60065b 199 ret = convert_CrysError_to_mbedtls_err( CRYS_ECDH_SVDP_DH( &ecdhParams->pubKey, &ecdhParams->privKey,
kadonotakashi 0:8fdf9a60065b 200 secret, &secret_size,
kadonotakashi 0:8fdf9a60065b 201 &ecdhParams->ecdhTempData ) );
kadonotakashi 0:8fdf9a60065b 202 if ( ret != 0 )
kadonotakashi 0:8fdf9a60065b 203 {
kadonotakashi 0:8fdf9a60065b 204 goto cleanup;
kadonotakashi 0:8fdf9a60065b 205 }
kadonotakashi 0:8fdf9a60065b 206 }
kadonotakashi 0:8fdf9a60065b 207 else if ( grp->id == MBEDTLS_ECP_DP_CURVE25519 )
kadonotakashi 0:8fdf9a60065b 208 {
kadonotakashi 0:8fdf9a60065b 209 cc_ecc_25519_comp_shared_params_t* ecdhParams = mbedtls_calloc( 1, sizeof(cc_ecc_25519_comp_shared_params_t) );
kadonotakashi 0:8fdf9a60065b 210 if ( ecdhParams == NULL )
kadonotakashi 0:8fdf9a60065b 211 {
kadonotakashi 0:8fdf9a60065b 212 ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
kadonotakashi 0:8fdf9a60065b 213 goto cleanup;
kadonotakashi 0:8fdf9a60065b 214 }
kadonotakashi 0:8fdf9a60065b 215
kadonotakashi 0:8fdf9a60065b 216 pHeap = ecdhParams;
kadonotakashi 0:8fdf9a60065b 217 heapSize = sizeof(cc_ecc_25519_comp_shared_params_t);
kadonotakashi 0:8fdf9a60065b 218
kadonotakashi 0:8fdf9a60065b 219
kadonotakashi 0:8fdf9a60065b 220 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, ecdhParams->privKey, mbedtls_mpi_size( d ) ) ) ;
kadonotakashi 0:8fdf9a60065b 221 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &Q->X, ecdhParams->pubKey, public_key_size ) );
kadonotakashi 0:8fdf9a60065b 222
kadonotakashi 0:8fdf9a60065b 223 ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_Scalarmult( secret, ( size_t* )&secret_size,
kadonotakashi 0:8fdf9a60065b 224 ecdhParams->privKey, CURVE_25519_KEY_SIZE ,
kadonotakashi 0:8fdf9a60065b 225 ecdhParams->pubKey, CURVE_25519_KEY_SIZE ,
kadonotakashi 0:8fdf9a60065b 226 &ecdhParams->kgTempData ) );
kadonotakashi 0:8fdf9a60065b 227 if ( ret != 0 )
kadonotakashi 0:8fdf9a60065b 228 {
kadonotakashi 0:8fdf9a60065b 229 goto cleanup;
kadonotakashi 0:8fdf9a60065b 230 }
kadonotakashi 0:8fdf9a60065b 231 }
kadonotakashi 0:8fdf9a60065b 232 else
kadonotakashi 0:8fdf9a60065b 233 {
kadonotakashi 0:8fdf9a60065b 234 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
kadonotakashi 0:8fdf9a60065b 235 goto cleanup;
kadonotakashi 0:8fdf9a60065b 236 }
kadonotakashi 0:8fdf9a60065b 237
kadonotakashi 0:8fdf9a60065b 238 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( z, secret, secret_size ) );
kadonotakashi 0:8fdf9a60065b 239
kadonotakashi 0:8fdf9a60065b 240 cleanup:
kadonotakashi 0:8fdf9a60065b 241
kadonotakashi 0:8fdf9a60065b 242 if ( pHeap )
kadonotakashi 0:8fdf9a60065b 243 {
kadonotakashi 0:8fdf9a60065b 244 mbedtls_zeroize( pHeap, heapSize );
kadonotakashi 0:8fdf9a60065b 245 mbedtls_free ( pHeap );
kadonotakashi 0:8fdf9a60065b 246 }
kadonotakashi 0:8fdf9a60065b 247
kadonotakashi 0:8fdf9a60065b 248 if ( secret )
kadonotakashi 0:8fdf9a60065b 249 {
kadonotakashi 0:8fdf9a60065b 250 mbedtls_zeroize( secret, secret_size_in_heap );
kadonotakashi 0:8fdf9a60065b 251 mbedtls_free ( secret );
kadonotakashi 0:8fdf9a60065b 252 }
kadonotakashi 0:8fdf9a60065b 253
kadonotakashi 0:8fdf9a60065b 254 return ( ret );
kadonotakashi 0:8fdf9a60065b 255 }
kadonotakashi 0:8fdf9a60065b 256 #endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */