const bool FrostIdentity::FromPublicKey(const std::string &publickey) { std::vector<std::string> keyparts; std::vector<unsigned char> edata; std::vector<unsigned char> ndata; mbedtls_rsa_free(&m_rsa); mbedtls_rsa_init(&m_rsa,MBEDTLS_RSA_PKCS_V21,MBEDTLS_MD_SHA1); StringFunctions::Split(publickey,":",keyparts); if(keyparts.size()==2) { Base64::Decode(keyparts[0],edata); Base64::Decode(keyparts[1],ndata); mbedtls_mpi_init(&m_rsa.N); mbedtls_mpi_init(&m_rsa.E); mbedtls_mpi_read_binary(&m_rsa.N,&ndata[0],ndata.size()); mbedtls_mpi_read_binary(&m_rsa.E,&edata[0],edata.size()); m_publickey=publickey; return true; } else { return false; } }
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { mbedtls_ecp_keypair keypair; mbedtls_mpi r; mbedtls_mpi s; mbedtls_md_type_t mdType; const mbedtls_md_info_t *pmdInfo; byte rgbDigest[MBEDTLS_MD_MAX_SIZE]; cn_cbor * pSig; bool result = false; mbedtls_ecp_keypair_init(&keypair); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn; 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); pSig = _COSE_arrayget_int(pSigner, index); CHECK_CONDITION((pSig != NULL) && (pSig->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_mpi_read_binary( &r, pSig->v.bytes, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_mpi_read_binary( &s, pSig->v.bytes + pSig->length / 2, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_ecdsa_verify(&keypair.grp, rgbDigest, mbedtls_md_get_size(pmdInfo), &keypair.Q, &r, &s) == 0, COSE_ERR_CRYPTO_FAIL); result = true; errorReturn: mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecp_keypair_free(&keypair); return result; }
result_t X509Cert::get_serial(exlib::string &retVal) { mbedtls_x509_crt *crt = get_crt(); if (!crt) return CHECK_ERROR(CALL_E_INVALID_CALL); int32_t ret; mbedtls_mpi serial; mbedtls_mpi_init(&serial); ret = mbedtls_mpi_read_binary(&serial, crt->serial.p, crt->serial.len); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(8192); size_t sz = retVal.length(); ret = mbedtls_mpi_write_string(&serial, 10, &retVal[0], sz, &sz); mbedtls_mpi_free(&serial); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(sz - 1); return 0; }
int dslink_handshake_read_key_pair(mbedtls_ecdh_context *ctx, char *buf) { mbedtls_ecdh_init(ctx); dslink_handshake_get_group(&ctx->grp); char *q = strchr(buf, ' '); if (!q || *(q + 1) == '\0') { errno = 0; return DSLINK_CRYPT_KEY_DECODE_ERR; } size_t len = (q - buf); unsigned char dec[90]; size_t decLen = 0; if (dslink_base64_url_decode(dec, sizeof(dec), &decLen, (unsigned char *) buf, len) != 0) { return DSLINK_CRYPT_BASE64_URL_DECODE_ERR; } if ((errno = mbedtls_mpi_read_binary(&ctx->d, dec, decLen)) != 0) { return DSLINK_CRYPT_KEY_DECODE_ERR; } len = strlen(buf) - len - 1; if (dslink_base64_url_decode(dec, sizeof(dec), &decLen, (unsigned char *) (q + 1), len) != 0) { return DSLINK_CRYPT_BASE64_URL_DECODE_ERR; } if ((errno = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, dec, decLen)) != 0) { return DSLINK_CRYPT_KEY_DECODE_ERR; } return 0; }
/* read */ static int unsigned_read(void *a, unsigned char *b, unsigned long len) { int res = mbedtls_mpi_read_binary(a, b, len); if (res == MBEDTLS_ERR_MPI_ALLOC_FAILED) return CRYPT_MEM; if (res) return CRYPT_ERROR; return CRYPT_OK; }
int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n) { mbedtls_rsa_context *rsa = NULL; const mbedtls_pk_info_t *pk_info = NULL; int rc; key->rsa = malloc(sizeof(mbedtls_pk_context)); if (key->rsa == NULL) { return SSH_ERROR; } mbedtls_pk_init(key->rsa); pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); mbedtls_pk_setup(key->rsa, pk_info); rc = mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA); if (rc == 0) { goto fail; } rsa = mbedtls_pk_rsa(*key->rsa); rc = mbedtls_mpi_read_binary(&rsa->N, ssh_string_data(n), ssh_string_len(n)); if (rc != 0) { goto fail; } rc = mbedtls_mpi_read_binary(&rsa->E, ssh_string_data(e), ssh_string_len(e)); if (rc != 0) { goto fail; } rsa->len = (mbedtls_mpi_bitlen(&rsa->N) + 7) >> 3; return SSH_OK; fail: mbedtls_pk_free(key->rsa); SAFE_FREE(key->rsa); return SSH_ERROR; }
/* * Import the peer's public value G^Y */ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, const unsigned char *input, size_t ilen ) { int ret; if( ctx == NULL || ilen < 1 || ilen > ctx->len ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret ); return( 0 ); }
int mbedtls_asn1_get_mpi( unsigned char **p, const unsigned char *end, mbedtls_mpi *X ) { int ret; size_t len; if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) return( ret ); ret = mbedtls_mpi_read_binary( X, *p, len ); *p += len; return( ret ); }
/* * Derive a suitable integer for group grp from a buffer of length len * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 */ static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x, const unsigned char *buf, size_t blen ) { int ret; size_t n_size = ( grp->nbits + 7 ) / 8; size_t use_size = blen > n_size ? n_size : blen; MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) ); if( use_size * 8 > grp->nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) ); /* While at it, reduce modulo N */ if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) ); cleanup: return( ret ); }
TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt *dest, const uint8_t *buffer, uint32_t bufferLen, int32_t sign) { TEE_Result res; mbedtls_mpi mpi_dest; get_mpi(&mpi_dest, dest); if (mbedtls_mpi_read_binary(&mpi_dest, buffer, bufferLen)) res = TEE_ERROR_OVERFLOW; else res = TEE_SUCCESS; if (sign < 0) mpi_dest.s = -1; put_mpi(&mpi_dest); return res; }
/* * Do an RSA public key operation */ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output ) { int ret; size_t olen; mbedtls_mpi T; mbedtls_mpi_init( &T ); #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; } olen = ctx->len; MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); 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 ); if( ret != 0 ) return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret ); return( 0 ); }
/* * helper to validate the mbedtls_mpi size and import it */ static int dhm_read_bignum( mbedtls_mpi *X, unsigned char **p, const unsigned char *end ) { int ret, n; if( end - *p < 2 ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); n = ( (*p)[0] << 8 ) | (*p)[1]; (*p) += 2; if( (int)( end - *p ) < n ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 ) return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret ); (*p) += n; return( 0 ); }
TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, struct ecc_public_key *public_key, void *secret, unsigned long *secret_len) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; uint8_t one[1] = { 1 }; mbedtls_ecdh_context ecdh; size_t out_len = 0; memset(&ecdh, 0, sizeof(ecdh)); mbedtls_ecdh_init(&ecdh); lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve); if (lmd_res != 0) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } ecdh.d = *(mbedtls_mpi *)private_key->d; ecdh.Qp.X = *(mbedtls_mpi *)public_key->x; ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y; mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one)); lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret, *secret_len, mbd_rand, NULL); if (lmd_res != 0) { res = get_tee_result(lmd_res); goto out; } *secret_len = out_len; out: /* Reset mpi to skip freeing here, those mpis will be freed with key */ mbedtls_mpi_init(&ecdh.d); mbedtls_mpi_init(&ecdh.Qp.X); mbedtls_mpi_init(&ecdh.Qp.Y); mbedtls_ecdh_free(&ecdh); return res; }
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, 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; uint32_t key_size = 2*MAX_KEY_SIZE_IN_BYTES + 1; const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( gid ) ); mbedtls_rand_func_container cc_rand = { f_rng, p_rng }; if ( pDomain ) { uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0}; cc_ecc_ws_keygen_params_t* kgParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_keygen_params_t) ); if ( kgParams == NULL ) return ( MBEDTLS_ERR_ECP_ALLOC_FAILED ); pHeap = kgParams; heapSize = sizeof(cc_ecc_ws_keygen_params_t); CrysRet = CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand, pDomain, &kgParams->privKey, &kgParams->pubKey, &kgParams->kgTempData, NULL ); if ( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, gid ) ); CrysRet = CRYS_ECPKI_ExportPublKey( &kgParams->pubKey, CRYS_EC_PointUncompressed, temp_buf, &key_size ); if ( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); goto cleanup; } ret = mbedtls_ecp_point_read_binary( &ctx->grp, &ctx->Q, temp_buf, key_size ); if ( ret != 0 ) goto cleanup; memset ( temp_buf, 0 , sizeof(temp_buf) ); CrysRet = CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (ctx->grp.nbits+7)/8, kgParams->privKey.PrivKeyDbBuff, 4*((((ctx->grp.nbits+7)/8)+3)/4) ); if ( CrysRet != CRYS_OK ) { ret = convert_CrysError_to_mbedtls_err( CrysRet ); mbedtls_zeroize( temp_buf, sizeof(temp_buf) ); goto cleanup; } ret = mbedtls_mpi_read_binary( &ctx->d, temp_buf, (ctx->grp.nbits+7)/8 ); mbedtls_zeroize( temp_buf, sizeof(temp_buf) ); if ( ret != 0 ) { goto cleanup; } } else ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; cleanup: if ( pHeap ) { mbedtls_zeroize( pHeap, heapSize ); mbedtls_free ( pHeap ); } return ( ret ); }
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 ); }
TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, const uint8_t *msg, size_t msg_len, const uint8_t *sig, size_t sig_len) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; mbedtls_ecdsa_context ecdsa; size_t key_size_bytes, key_size_bits = 0; uint8_t one[1] = { 1 }; mbedtls_mpi r; mbedtls_mpi s; memset(&ecdsa, 0, sizeof(ecdsa)); memset(&r, 0, sizeof(r)); memset(&s, 0, sizeof(s)); if (algo == 0) return TEE_ERROR_BAD_PARAMETERS; mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); mbedtls_ecdsa_init(&ecdsa); lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve); if (lmd_res != 0) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } ecdsa.Q.X = *(mbedtls_mpi *)key->x; ecdsa.Q.Y = *(mbedtls_mpi *)key->y; mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one)); res = ecc_get_keysize(key->curve, algo, &key_size_bytes, &key_size_bits); if (res != TEE_SUCCESS) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } /* check keysize vs sig_len */ if ((key_size_bytes * 2) != sig_len) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } mbedtls_mpi_read_binary(&r, sig, sig_len / 2); mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2); lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q, &r, &s); if (lmd_res != 0) { FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res); res = get_tee_result(lmd_res); } out: mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); /* Reset mpi to skip freeing here, those mpis will be freed with key */ mbedtls_mpi_init(&ecdsa.Q.X); mbedtls_mpi_init(&ecdsa.Q.Y); mbedtls_ecdsa_free(&ecdsa); return res; }
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, int ( *f_rng )( void *, unsigned char *, size_t ), void *p_rng ) { int ret = 0; void* pHeap = NULL; size_t heapSize = 0; uint32_t public_key_size = (2 * MAX_KEY_SIZE_IN_BYTES + 1); const CRYS_ECPKI_Domain_t* pDomain = CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) ); mbedtls_rand_func_container cc_rand = { f_rng, p_rng }; if ( pDomain ) { uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0}; cc_ecc_ws_keygen_params_t* kgParams = mbedtls_calloc( 1, sizeof( cc_ecc_ws_keygen_params_t ) ); if ( kgParams == NULL ) return ( MBEDTLS_ERR_ECP_ALLOC_FAILED ); pHeap = kgParams; heapSize = sizeof( cc_ecc_ws_keygen_params_t ); ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand, pDomain, &kgParams->privKey, &kgParams->pubKey, &kgParams->kgTempData, NULL ) ); if( ret != 0 ) { goto cleanup; } ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_ExportPublKey( &kgParams->pubKey, CRYS_EC_PointUncompressed,temp_buf, &public_key_size ) ); if( ret != 0 ) { goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( grp, Q, temp_buf, public_key_size ) ); memset ( temp_buf, 0 , sizeof(temp_buf) ); ret = convert_CrysError_to_mbedtls_err( CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (grp->nbits+7)/8, kgParams->privKey.PrivKeyDbBuff, 4*((((grp->nbits+7)/8)+3)/4) ) ); if( ret != 0 ) { mbedtls_zeroize( temp_buf, sizeof( temp_buf ) ); goto cleanup; } MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary( d, temp_buf, (grp->nbits+7)/8 ) ); mbedtls_zeroize( temp_buf, sizeof( temp_buf ) ); } /* if CRYS_ECPKI_GetEcDomain returns NULL, then the given curve is either Montgomery 25519 * or another curve which is not supported by CC310*/ else if ( grp->id == MBEDTLS_ECP_DP_CURVE25519 ) { size_t priv_key_size = public_key_size = CURVE_25519_KEY_SIZE ; cc_ecc_25519_keygen_params_t* kgParams = mbedtls_calloc( 1, sizeof(cc_ecc_25519_keygen_params_t) ); if ( kgParams == NULL ) return ( MBEDTLS_ERR_ECP_ALLOC_FAILED ); pHeap = ( uint8_t* )kgParams; heapSize = sizeof(cc_ecc_25519_keygen_params_t); ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_KeyPair( kgParams->pubKey, ( size_t* )&public_key_size, kgParams->privKey, &priv_key_size, &cc_rand, convert_mbedtls_to_cc_rand, &kgParams->kgTempData ) ); if( ret != 0 ) { goto cleanup; } MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, kgParams->privKey, priv_key_size ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Q->X, kgParams->pubKey, public_key_size ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Q->Z, 1 ) ); } else ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; cleanup: if ( pHeap ) { mbedtls_zeroize( pHeap, heapSize ); mbedtls_free( pHeap ); } return ( ret ); }
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 ); }
bool ECKey_From(const cn_cbor * pKey, mbedtls_ecp_keypair *keypair, cose_errback * perr) { byte rgbKey[MBEDTLS_ECP_MAX_PT_LEN]; int cbKey; int cbGroup; const cn_cbor * p; mbedtls_ecp_group_id groupId; p = cn_cbor_mapget_int(pKey, COSE_Key_Type); CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER); if(p->type == CN_CBOR_UINT) { CHECK_CONDITION(p->v.uint == COSE_Key_Type_EC2, COSE_ERR_INVALID_PARAMETER); } else { FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Curve); CHECK_CONDITION((p != NULL) && (p->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER); switch (p->v.uint) { case 1: // P-256 groupId = MBEDTLS_ECP_DP_SECP256R1; break; case 2: // P-384 groupId = MBEDTLS_ECP_DP_SECP384R1; break; case 3: // P-521 groupId = MBEDTLS_ECP_DP_SECP521R1; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } CHECK_CONDITION(mbedtls_ecp_group_load(&keypair->grp, groupId) == 0, COSE_ERR_INVALID_PARAMETER); cbGroup = (keypair->grp.nbits + 7) / 8; p = cn_cbor_mapget_int(pKey, COSE_Key_EC_X); CHECK_CONDITION((p != NULL) && (p->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(p->length == cbGroup, COSE_ERR_INVALID_PARAMETER); memcpy(rgbKey+1, p->v.str, p->length); p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Y); CHECK_CONDITION((p != NULL), COSE_ERR_INVALID_PARAMETER); if (p->type == CN_CBOR_BYTES) { rgbKey[0] = 0x04; cbKey = cbGroup * 2 + 1; CHECK_CONDITION(p->length == cbGroup, COSE_ERR_INVALID_PARAMETER); memcpy(rgbKey + p->length + 1, p->v.str, p->length); } else if (p->type == CN_CBOR_TRUE) { cbKey = cbGroup + 1; rgbKey[0] = 0x03; } else if (p->type == CN_CBOR_FALSE) { cbKey = cbGroup + 1; rgbKey[0] = 0x02; } else FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, rgbKey, cbKey) == 0, COSE_ERR_INVALID_PARAMETER); p = cn_cbor_mapget_int(pKey, COSE_Key_EC_d); if (p != NULL) { CHECK_CONDITION(p->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_mpi_read_binary( &keypair->d, p->v.bytes, p->length) == 0, COSE_ERR_CRYPTO_FAIL); } return true; errorReturn: return false; }
/* * 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 ); }
/* * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. * WARNING: the resulting group should only be used with * pk_group_id_from_specified(), since its base point may not be set correctly * if it was encoded compressed. * * SpecifiedECDomain ::= SEQUENCE { * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), * fieldID FieldID {{FieldTypes}}, * curve Curve, * base ECPoint, * order INTEGER, * cofactor INTEGER OPTIONAL, * hash HashAlgorithm OPTIONAL, * ... * } * * We only support prime-field as field type, and ignore hash and cofactor. */ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) { int ret; unsigned char *p = params->p; const unsigned char * const end = params->p + params->len; const unsigned char *end_field, *end_curve; size_t len; int ver; /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); if( ver < 1 || ver > 3 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); /* * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field * fieldType FIELD-ID.&id({IOSet}), * parameters FIELD-ID.&Type({IOSet}{@fieldType}) * } */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( ret ); end_field = p + len; /* * FIELD-ID ::= TYPE-IDENTIFIER * FieldTypes FIELD-ID ::= { * { Prime-p IDENTIFIED BY prime-field } | * { Characteristic-two IDENTIFIED BY characteristic-two-field } * } * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } */ if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 ) return( ret ); if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) { return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); } p += len; /* Prime-p ::= INTEGER -- Field of size p. */ if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); grp->pbits = mbedtls_mpi_bitlen( &grp->P ); if( p != end_field ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); /* * Curve ::= SEQUENCE { * a FieldElement, * b FieldElement, * seed BIT STRING OPTIONAL * -- Shall be present if used in SpecifiedECDomain * -- with version equal to ecdpVer2 or ecdpVer3 * } */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( ret ); end_curve = p + len; /* * FieldElement ::= OCTET STRING * containing an integer in the case of a prime field */ if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } p += len; if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } p += len; /* Ignore seed BIT STRING OPTIONAL */ if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 ) p += len; if( p != end_curve ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); /* * ECPoint ::= OCTET STRING */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G, ( const unsigned char *) p, len ) ) != 0 ) { /* * If we can't read the point because it's compressed, cheat by * reading only the X coordinate and the parity bit of Y. */ if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || ( p[0] != 0x02 && p[0] != 0x03 ) || len != mbedtls_mpi_size( &grp->P ) + 1 || mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); } } p += len; /* * order INTEGER */ if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); grp->nbits = mbedtls_mpi_bitlen( &grp->N ); /* * Allow optional elements by purposefully not enforcing p == end here. */ return( 0 ); }
/* * Parse a SEC1 encoded private EC key */ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, const unsigned char *key, size_t keylen ) { int ret; int version, pubkey_done; size_t len; mbedtls_asn1_buf params; unsigned char *p = (unsigned char *) key; unsigned char *end = p + keylen; unsigned char *end2; /* * RFC 5915, or SEC1 Appendix C.4 * * ECPrivateKey ::= SEQUENCE { * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), * privateKey OCTET STRING, * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, * publicKey [1] BIT STRING OPTIONAL * } */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } end = p + len; if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); if( version != 1 ) return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 ) { mbedtls_ecp_keypair_free( eck ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } p += len; pubkey_done = 0; if( p != end ) { /* * Is 'parameters' present? */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) { if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) { mbedtls_ecp_keypair_free( eck ); return( ret ); } } else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) { mbedtls_ecp_keypair_free( eck ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } /* * Is 'publickey' present? If not, or if we can't read it (eg because it * is compressed), create it from the private key. */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) { end2 = p + len; if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); if( p + len != end2 ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) pubkey_done = 1; else { /* * The only acceptable failure mode of pk_get_ecpubkey() above * is if the point format is not recognized. */ if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ) return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); } } else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) { mbedtls_ecp_keypair_free( eck ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } } if( ! pubkey_done && ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, NULL, NULL ) ) != 0 ) { mbedtls_ecp_keypair_free( eck ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) { mbedtls_ecp_keypair_free( eck ); return( ret ); } return( 0 ); }
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 ) ; }