int main( int argc, char *argv[] ) { int ret; mbedtls_ecdh_context ctx_cli, ctx_srv; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char cli_to_srv[32], srv_to_cli[32]; const char pers[] = "ecdh"; ((void) argc); ((void) argv); mbedtls_ecdh_init( &ctx_cli ); mbedtls_ecdh_init( &ctx_srv ); mbedtls_ctr_drbg_init( &ctr_drbg ); /* * Initialize random number generation */ mbedtls_printf( " . Seeding the random number generator..." ); fflush( stdout ); mbedtls_entropy_init( &entropy ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, sizeof pers ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Client: inialize context and generate keypair */ mbedtls_printf( " . Setting up client context..." ); fflush( stdout ); ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Server: initialize context and generate keypair */ mbedtls_printf( " . Setting up server context..." ); fflush( stdout ); ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Server: read peer's key and generate shared secret */ mbedtls_printf( " . Server reading client key and computing secret..." ); fflush( stdout ); ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z, &ctx_srv.Qp, &ctx_srv.d, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Client: read peer's key and generate shared secret */ mbedtls_printf( " . Client reading server key and computing secret..." ); fflush( stdout ); ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z, &ctx_cli.Qp, &ctx_cli.d, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Verification: are the computed secret equal? */ mbedtls_printf( " . Checking if both computed secrets are equal..." ); fflush( stdout ); ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); exit: #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif mbedtls_ecdh_free( &ctx_srv ); mbedtls_ecdh_free( &ctx_cli ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); return( ret != 0 ); }
/* * Deterministic signature wrapper */ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, mbedtls_md_type_t md_alg, mbedtls_ecdsa_restart_ctx *rs_ctx ) { int ret; mbedtls_hmac_drbg_context rng_ctx; mbedtls_hmac_drbg_context *p_rng = &rng_ctx; unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; size_t grp_len = ( grp->nbits + 7 ) / 8; const mbedtls_md_info_t *md_info; mbedtls_mpi h; if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); mbedtls_mpi_init( &h ); mbedtls_hmac_drbg_init( &rng_ctx ); ECDSA_RS_ENTER( det ); #if defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && rs_ctx->det != NULL ) { /* redirect to our context */ p_rng = &rs_ctx->det->rng_ctx; /* jump to current step */ if( rs_ctx->det->state == ecdsa_det_sign ) goto sign; } #endif /* MBEDTLS_ECP_RESTARTABLE */ /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len ); #if defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && rs_ctx->det != NULL ) rs_ctx->det->state = ecdsa_det_sign; sign: #endif #if defined(MBEDTLS_ECDSA_SIGN_ALT) ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng ); #else ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng, rs_ctx ); #endif /* MBEDTLS_ECDSA_SIGN_ALT */ cleanup: mbedtls_hmac_drbg_free( &rng_ctx ); mbedtls_mpi_free( &h ); ECDSA_RS_LEAVE( det ); return( ret ); }
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret = 0; CRYSError_t CrysRet = CRYS_OK; void* pHeap = NULL; size_t heapSize = 0; uint8_t* pSignature = NULL; CRYS_ECPKI_HASH_OpMode_t hash_mode = message_size_to_hash_mode( blen ); uint32_t signature_size = ( ( grp->nbits + 7 ) / 8 ) *2; const uint32_t signature_size_for_heap = signature_size; mbedtls_rand_func_container cc_rand = { f_rng, p_rng }; const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) ); #if SIZE_MAX > UINT_MAX if( blen > 0xFFFFFFFF ) { return ( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); } #endif if ( pDomain != NULL ) { uint8_t temp_buf[ MAX_KEY_SIZE_IN_BYTES ] = {0}; cc_ecc_ws_sign_params_t* signParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_sign_params_t) ); if ( signParams == NULL) return ( MBEDTLS_ERR_ECP_ALLOC_FAILED ); pHeap = signParams; heapSize = sizeof(cc_ecc_ws_sign_params_t); pSignature = mbedtls_calloc( 1, signature_size_for_heap ); if ( pSignature == NULL) { ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) ); CrysRet = CRYS_ECPKI_BuildPrivKey( pDomain, temp_buf, mbedtls_mpi_size( d ), &signParams->privKey); if( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); mbedtls_zeroize( temp_buf, sizeof(temp_buf) ); goto cleanup; } CrysRet = CRYS_ECDSA_Sign( &cc_rand, convert_mbedtls_to_cc_rand, &signParams->signContext, &signParams->privKey, hash_mode, (uint8_t*)buf, blen, pSignature, &signature_size ); mbedtls_zeroize( temp_buf, sizeof(temp_buf) ); if( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); goto cleanup; } } else { ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( r, pSignature, ( ( grp->nbits + 7 ) / 8 ) ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( s, pSignature + ( ( grp->nbits + 7 ) / 8 ), ( ( grp->nbits + 7 ) / 8 ) ) ); cleanup: if ( pHeap ) { mbedtls_zeroize( pHeap, heapSize ); mbedtls_free( pHeap ); } if( pSignature ) { mbedtls_zeroize( pSignature, signature_size_for_heap ); mbedtls_free( pSignature ); } return ( ret ) ; }
//need to normalize the coordinates int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, const unsigned char *buf, size_t blen, const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s) { int ret = 0; CRYSError_t CrysRet = CRYS_OK; void* pHeap = NULL; size_t heapSize = 0; uint8_t * pSignature = NULL; CRYS_ECPKI_HASH_OpMode_t hash_mode = message_size_to_hash_mode( blen ); size_t temp_size = 0; uint32_t signature_size = ( ( grp->nbits + 7 ) / 8 ) * 2; const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) ); #if SIZE_MAX > UINT_MAX if( blen > 0xFFFFFFFF ) { return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); } #endif if ( pDomain ) { uint8_t temp_buf[ 2*MAX_KEY_SIZE_IN_BYTES + 1 ] = {0}; cc_ecc_ws_verify_params_t* verifyParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_verify_params_t) ); if ( verifyParams == NULL) return ( MBEDTLS_ERR_ECP_ALLOC_FAILED ); pHeap = verifyParams; heapSize = sizeof(cc_ecc_ws_verify_params_t); pSignature = mbedtls_calloc( 1, signature_size ); if ( pSignature == NULL) { ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &temp_size, temp_buf, sizeof(temp_buf) ) ); CrysRet = CRYS_ECPKI_BuildPublKey(pDomain, temp_buf, temp_size, &verifyParams->pubKey); if( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( r, pSignature, ( ( grp->nbits + 7 ) / 8 ) ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( s, pSignature + ( ( grp->nbits + 7 ) / 8 ), ( ( grp->nbits + 7 ) / 8 ) ) ); CrysRet = CRYS_ECDSA_Verify ( &verifyParams->verifyContext, &verifyParams->pubKey, hash_mode, pSignature, signature_size, (uint8_t*)buf, blen ); if( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); goto cleanup; } } else ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; cleanup: if( pHeap ) { mbedtls_zeroize( pHeap, heapSize ); mbedtls_free( pHeap ); } if( pSignature ) { mbedtls_zeroize( pSignature, signature_size ); mbedtls_free( pSignature ); } return ret; }
/* * Do an RSA private key operation */ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, const unsigned char *input, unsigned char *output ) { int ret; size_t olen; mbedtls_mpi T, T1, T2; /* Make sure we have private key info, prevent possible misuse */ if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) { ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; goto cleanup; } if( f_rng != NULL ) { /* * Blinding * T = T * Vi mod N */ MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); } #if defined(MBEDTLS_RSA_NO_CRT) MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); #else /* * faster decryption using the CRT * * T1 = input ^ dP mod P * T2 = input ^ dQ mod Q */ MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) ); /* * T = (T1 - T2) * (Q^-1 mod P) mod P */ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) ); /* * T = T2 + T * Q */ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) ); #endif /* MBEDTLS_RSA_NO_CRT */ if( f_rng != NULL ) { /* * Unblind * T = T * Vf mod N */ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); } olen = ctx->len; MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); cleanup: #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); if( ret != 0 ) return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); return( 0 ); }
bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { #if defined(MBEDTLS_ECDSA_DETERMINISTIC) byte rgbDigest[MBEDTLS_MD_MAX_SIZE]; uint8_t * pbSig = NULL; cn_cbor_errback cbor_error; int cbR; mbedtls_md_type_t mdType; const mbedtls_md_info_t *pmdInfo; mbedtls_ecp_keypair keypair; mbedtls_mpi r; mbedtls_mpi s; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pSigner->m_allocContext; #endif cn_cbor * p = NULL; bool result = false; mbedtls_ecp_keypair_init(&keypair); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn; CHECK_CONDITION(keypair.d.n != 0, COSE_ERR_INVALID_PARAMETER); switch(cbitDigest) { case 256: mdType = MBEDTLS_MD_SHA256; break; case 384: mdType = MBEDTLS_MD_SHA384; break; case 512: mdType = MBEDTLS_MD_SHA512; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } pmdInfo = mbedtls_md_info_from_type(mdType); CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_ecdsa_sign_det(&keypair.grp, &r, &s, &keypair.d, rgbDigest, mbedtls_md_get_size(pmdInfo), mdType) == 0, COSE_ERR_CRYPTO_FAIL); cbR = (keypair.grp.nbits + 7) / 8; pbSig = COSE_CALLOC(cbR, 2, context); CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_mpi_write_binary(&r, pbSig, cbR) == 0, COSE_ERR_INTERNAL); CHECK_CONDITION(mbedtls_mpi_write_binary(&s, pbSig + cbR, cbR) == 0, COSE_ERR_INTERNAL); p = cn_cbor_data_create(pbSig, cbR*2, CBOR_CONTEXT_PARAM_COMMA &cbor_error); CHECK_CONDITION_CBOR(p != NULL, cbor_error); CHECK_CONDITION(_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR); p = NULL; pbSig = NULL; result = true; errorReturn: cn_cbor_free(p CBOR_CONTEXT_PARAM); COSE_FREE(pbSig, context); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecp_keypair_free(&keypair); return result; #else return false; #endif }
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, const mbedtls_ecp_point *Q, const mbedtls_mpi *d, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; void* pHeap = NULL; size_t heapSize = 0; size_t public_key_size = (grp->nbits+7)/8 ; const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) ); uint32_t secret_size = ( ( grp->nbits + 7 ) / 8 ) ; const uint32_t secret_size_in_heap = secret_size; uint8_t* secret = mbedtls_calloc( 1, secret_size_in_heap ); if ( secret == NULL ) return ( MBEDTLS_ERR_ECP_ALLOC_FAILED ); /* * Make sure Q is a valid pubkey before using it */ MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); if ( pDomain ) { uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0}; cc_ecc_ws_comp_shared_params_t* ecdhParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_comp_shared_params_t) ); if ( ecdhParams == NULL ) { ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; goto cleanup; } pHeap = ecdhParams; heapSize = sizeof(cc_ecc_ws_comp_shared_params_t); MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &public_key_size, temp_buf, sizeof(temp_buf) ) ); ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPublKey( pDomain, temp_buf, public_key_size, &ecdhParams->pubKey ) ); if ( ret != 0 ) { goto cleanup; } memset ( temp_buf, 0, sizeof(temp_buf) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) ); ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPrivKey( pDomain, temp_buf, mbedtls_mpi_size( d ), &ecdhParams->privKey ) ); mbedtls_zeroize( temp_buf, sizeof( temp_buf ) ); if ( ret != 0 ) { goto cleanup; } ret = convert_CrysError_to_mbedtls_err( CRYS_ECDH_SVDP_DH( &ecdhParams->pubKey, &ecdhParams->privKey, secret, &secret_size, &ecdhParams->ecdhTempData ) ); if ( ret != 0 ) { goto cleanup; } } else if ( grp->id == MBEDTLS_ECP_DP_CURVE25519 ) { cc_ecc_25519_comp_shared_params_t* ecdhParams = mbedtls_calloc( 1, sizeof(cc_ecc_25519_comp_shared_params_t) ); if ( ecdhParams == NULL ) { ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; goto cleanup; } pHeap = ecdhParams; heapSize = sizeof(cc_ecc_25519_comp_shared_params_t); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, ecdhParams->privKey, mbedtls_mpi_size( d ) ) ) ; MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &Q->X, ecdhParams->pubKey, public_key_size ) ); ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_Scalarmult( secret, ( size_t* )&secret_size, ecdhParams->privKey, CURVE_25519_KEY_SIZE , ecdhParams->pubKey, CURVE_25519_KEY_SIZE , &ecdhParams->kgTempData ) ); if ( ret != 0 ) { goto cleanup; } } else { ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( z, secret, secret_size ) ); cleanup: if ( pHeap ) { mbedtls_zeroize( pHeap, heapSize ); mbedtls_free ( pHeap ); } if ( secret ) { mbedtls_zeroize( secret, secret_size_in_heap ); mbedtls_free ( secret ); } return ( ret ); }