Added ECC API's for using custom curves that are not in the "ecc_sets" list. Added wolfCrypt test to validate/demonstrate custom curve using BRAINPOOL256R1. Exposed "wc_ecc_make_key_ex" and added "wc_ecc_import_x963_ex" / "wc_ecc_import_raw_ex" API's that accept "const ecc_set_type*" for custom curve. Internally use "ECC_CUSTOM_IDX" (-1) to define custom curve is used. Added "--enable-ecccustcurves" option to configure.ac.

pull/415/head
David Garske 2016-06-16 10:09:41 -07:00
parent 69b6ac504f
commit d55663eaee
4 changed files with 265 additions and 158 deletions

View File

@ -768,6 +768,18 @@ fi
AM_CONDITIONAL([BUILD_ECC], [test "x$ENABLED_ECC" = "xyes"])
# ECC Custom Curves
AC_ARG_ENABLE([ecccustcurves],
[AS_HELP_STRING([--enable-ecccustcurves],[Enable ECC custom curves (default: disabled)])],
[ ENABLED_ECCCUSTCURVES=$enableval ],
[ ENABLED_ECCCUSTCURVES=no ]
)
if test "$ENABLED_ECCCUSTCURVES" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CUSTOM_CURVES"
fi
# for using memory optimization setting on both curve25519 and ed25519
ENABLED_CURVED25519_SMALL=no

View File

@ -1458,7 +1458,7 @@ int wc_ecc_is_valid_idx(int n)
;
/* -1 is a valid index --- indicating that the domain params
were supplied by the user */
if ((n >= -1) && (n < x)) {
if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
return 1;
}
return 0;
@ -1624,7 +1624,7 @@ int wc_ecc_point_is_at_infinity(ecc_point* p)
}
static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp)
int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp)
{
int err;
ecc_point* base = NULL;
@ -1647,7 +1647,7 @@ static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp)
return MEMORY_E;
#endif
key->idx = -1;
key->idx = ECC_CUSTOM_IDX;
key->dp = dp;
/*generate 8 extra bytes to mitigate bias from the modulo operation below*/
@ -2941,76 +2941,83 @@ int wc_ecc_check_key(ecc_key* key)
#ifdef HAVE_ECC_KEY_IMPORT
/* import public ECC key in ANSI X9.63 format */
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
const ecc_set_type* dp)
{
int x, err;
int compressed = 0;
int x, err;
int compressed = 0;
if (in == NULL || key == NULL)
return ECC_BAD_ARG_E;
if (in == NULL || key == NULL)
return ECC_BAD_ARG_E;
/* must be odd */
if ((inLen & 1) == 0) {
return ECC_BAD_ARG_E;
}
/* must be odd */
if ((inLen & 1) == 0) {
return ECC_BAD_ARG_E;
}
/* init key */
#ifdef ALT_ECC_SIZE
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
alt_fp_init(key->pubkey.x);
alt_fp_init(key->pubkey.y);
alt_fp_init(key->pubkey.z);
err = mp_init(&key->k);
#else
err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k,
NULL, NULL);
#endif
if (err != MP_OKAY)
return MEMORY_E;
/* init key */
#ifdef ALT_ECC_SIZE
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
alt_fp_init(key->pubkey.x);
alt_fp_init(key->pubkey.y);
alt_fp_init(key->pubkey.z);
err = mp_init(&key->k);
#else
err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k,
NULL, NULL);
#endif
if (err != MP_OKAY)
return MEMORY_E;
/* check for 4, 2, or 3 */
if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
err = ASN_PARSE_E;
}
/* check for 4, 2, or 3 */
if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
err = ASN_PARSE_E;
}
if (in[0] == 0x02 || in[0] == 0x03) {
#ifdef HAVE_COMP_KEY
compressed = 1;
#else
err = NOT_COMPILED_IN;
#endif
}
if (in[0] == 0x02 || in[0] == 0x03) {
#ifdef HAVE_COMP_KEY
compressed = 1;
#else
err = NOT_COMPILED_IN;
#endif
}
if (err == MP_OKAY) {
/* determine the idx */
if (err == MP_OKAY) {
/* determine the idx */
if (dp) {
/* set the idx */
key->idx = ECC_CUSTOM_IDX;
key->dp = dp;
key->type = ECC_PUBLICKEY;
}
else {
if (compressed)
inLen = (inLen-1)*2 + 1; /* used uncompressed len */
if (compressed)
inLen = (inLen-1)*2 + 1; /* used uncompressed len */
for (x = 0; ecc_sets[x].size != 0; x++) {
if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) {
break;
}
}
if (ecc_sets[x].size == 0) {
WOLFSSL_MSG("ecc_set size not found");
err = ASN_PARSE_E;
} else {
key->idx = x;
key->dp = &ecc_sets[x];
key->type = ECC_PUBLICKEY;
}
}
}
for (x = 0; ecc_sets[x].size != 0; x++) {
if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) {
break;
}
}
if (ecc_sets[x].size == 0) {
WOLFSSL_MSG("ecc_set size not found");
err = ASN_PARSE_E;
} else {
/* set the idx */
key->idx = x;
key->dp = &ecc_sets[x];
key->type = ECC_PUBLICKEY;
}
}
/* read data */
if (err == MP_OKAY)
err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
/* read data */
if (err == MP_OKAY)
err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
#ifdef HAVE_COMP_KEY
if (err == MP_OKAY && compressed == 1) { /* build y */
if (err == MP_OKAY && compressed == 1) { /* build y */
mp_int t1, t2, prime, a, b;
if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY)
@ -3047,7 +3054,7 @@ int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
/* adjust y */
if (err == MP_OKAY) {
if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) ||
(mp_isodd(&t2) == MP_NO && in[0] == 0x02)) {
(mp_isodd(&t2) == MP_NO && in[0] == 0x02)) {
err = mp_mod(&t2, &prime, &t2);
}
else {
@ -3061,28 +3068,33 @@ int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
mp_clear(&prime);
mp_clear(&t2);
mp_clear(&t1);
}
#endif
}
#endif /* HAVE_COMP_KEY */
if (err == MP_OKAY && compressed == 0)
err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
(inLen-1)>>1);
if (err == MP_OKAY)
mp_set(key->pubkey.z, 1);
if (err == MP_OKAY && compressed == 0)
err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
(inLen-1)>>1);
if (err == MP_OKAY)
mp_set(key->pubkey.z, 1);
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
if (err == MP_OKAY)
err = wc_ecc_check_key(key);
if (err == MP_OKAY)
err = wc_ecc_check_key(key);
#endif
if (err != MP_OKAY) {
mp_clear(key->pubkey.x);
mp_clear(key->pubkey.y);
mp_clear(key->pubkey.z);
mp_clear(&key->k);
}
if (err != MP_OKAY) {
mp_clear(key->pubkey.x);
mp_clear(key->pubkey.y);
mp_clear(key->pubkey.z);
mp_clear(&key->k);
}
return err;
return err;
}
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
{
return wc_ecc_import_x963_ex(in, inLen, key, NULL);
}
#endif /* HAVE_ECC_KEY_IMPORT */
@ -3091,24 +3103,26 @@ int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
return MP_OKAY on success */
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
{
word32 numlen;
word32 numlen;
if (key == NULL || out == NULL || outLen == NULL)
return ECC_BAD_ARG_E;
if (key == NULL || out == NULL || outLen == NULL) {
return BAD_FUNC_ARG;
}
if (wc_ecc_is_valid_idx(key->idx) == 0) {
return ECC_BAD_ARG_E;
}
numlen = key->dp->size;
if (wc_ecc_is_valid_idx(key->idx) == 0) {
return ECC_BAD_ARG_E;
}
numlen = key->dp->size;
if (*outLen < numlen) {
*outLen = numlen;
return BUFFER_E;
}
*outLen = numlen;
XMEMSET(out, 0, *outLen);
return mp_to_unsigned_bin(&key->k, out + (numlen -
mp_unsigned_bin_size(&key->k)));
if (*outLen < numlen) {
*outLen = numlen;
return BUFFER_E;
}
*outLen = numlen;
XMEMSET(out, 0, *outLen);
return mp_to_unsigned_bin(&key->k, out + (numlen -
mp_unsigned_bin_size(&key->k)));
}
#endif /* HAVE_ECC_KEY_EXPORT */
@ -3177,23 +3191,14 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
#endif /* !NO_ASN */
#ifdef HAVE_ECC_KEY_IMPORT
/**
Import raw ECC key
key The destination ecc_key structure
qx x component of the public key, as ASCII hex string
qy y component of the public key, as ASCII hex string
d private key, as ASCII hex string
curveName ECC curve name, from ecc_sets[]
return MP_OKAY on success
*/
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
const char* d, const char* curveName)
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
const char* qy, const char* d, int x, const ecc_set_type* dp)
{
int err, x;
int err;
if (key == NULL || qx == NULL || qy == NULL || d == NULL ||
curveName == NULL)
return ECC_BAD_ARG_E;
if (key == NULL || qx == NULL || qy == NULL || d == NULL || dp == NULL) {
return BAD_FUNC_ARG;
}
/* init key */
#ifdef ALT_ECC_SIZE
@ -3224,21 +3229,10 @@ int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
/* read and set the curve */
if (err == MP_OKAY) {
for (x = 0; ecc_sets[x].size != 0; x++) {
if (XSTRNCMP(ecc_sets[x].name, curveName,
XSTRLEN(curveName)) == 0) {
break;
}
}
if (ecc_sets[x].size == 0) {
WOLFSSL_MSG("ecc_set curve name not found");
err = ASN_PARSE_E;
} else {
/* set the curve */
key->idx = x;
key->dp = &ecc_sets[x];
key->type = ECC_PUBLICKEY;
}
/* set curve type and index */
key->idx = x;
key->dp = dp;
key->type = ECC_PUBLICKEY;
}
/* import private key */
@ -3261,6 +3255,59 @@ int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
return err;
}
/**
Import raw ECC key
key The destination ecc_key structure
qx x component of the public key, as ASCII hex string
qy y component of the public key, as ASCII hex string
d private key, as ASCII hex string
dp Custom ecc_set_type
return MP_OKAY on success
*/
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
const char* d, const ecc_set_type* dp)
{
return wc_ecc_import_raw_private(key, qx, qy, d, ECC_CUSTOM_IDX, dp);
}
/**
Import raw ECC key
key The destination ecc_key structure
qx x component of the public key, as ASCII hex string
qy y component of the public key, as ASCII hex string
d private key, as ASCII hex string
curveName ECC curve name, from ecc_sets[]
return MP_OKAY on success
*/
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
const char* d, const char* curveName)
{
int err, x;
if (key == NULL || qx == NULL || qy == NULL || d == NULL ||
curveName == NULL) {
return BAD_FUNC_ARG;
}
/* set curve type and index */
for (x = 0; ecc_sets[x].size != 0; x++) {
if (XSTRNCMP(ecc_sets[x].name, curveName,
XSTRLEN(curveName)) == 0) {
break;
}
}
if (ecc_sets[x].size == 0) {
WOLFSSL_MSG("ecc_set curve name not found");
err = ASN_PARSE_E;
} else {
return wc_ecc_import_raw_private(key, qx, qy, d, x, &ecc_sets[x]);
}
return err;
}
#endif /* HAVE_ECC_KEY_IMPORT */
/* key size in octets */

View File

@ -253,6 +253,9 @@ int idea_test(void);
#define FOURK_BUF 4096
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
static int err_sys(const char* msg, int es)
{
@ -6672,7 +6675,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize)
}
#endif /* WOLFSSL_KEY_GEN */
static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
int testCompressedKey)
int testCompressedKey, const ecc_set_type* dp)
{
#ifdef BENCH_EMBEDDED
byte sharedA[128]; /* Needs to be at least keySize */
@ -6700,34 +6703,44 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
wc_ecc_init(&userB);
wc_ecc_init(&pubKey);
ret = wc_ecc_make_key(rng, keySize, &userA);
if (dp) {
ret = wc_ecc_make_key_ex(rng, &userA, dp);
}
else {
ret = wc_ecc_make_key(rng, keySize, &userA);
}
if (ret != 0)
return -1014;
ERROR_OUT(-1014, done);
ret = wc_ecc_check_key(&userA);
if (ret != 0)
return -1023;
ERROR_OUT(-1023, done);
ret = wc_ecc_make_key(rng, keySize, &userB);
if (dp) {
ret = wc_ecc_make_key_ex(rng, &userB, dp);
}
else {
ret = wc_ecc_make_key(rng, keySize, &userB);
}
if (ret != 0)
return -1002;
ERROR_OUT(-1002, done);
#ifdef HAVE_ECC_DHE
x = sizeof(sharedA);
ret = wc_ecc_shared_secret(&userA, &userB, sharedA, &x);
if (ret != 0)
return -1015;
ERROR_OUT(-1015, done);
y = sizeof(sharedB);
ret = wc_ecc_shared_secret(&userB, &userA, sharedB, &y);
if (ret != 0)
return -1003;
ERROR_OUT(-1003, done);
if (y != x)
return -1004;
ERROR_OUT(-1004, done);
if (memcmp(sharedA, sharedB, x))
return -1005;
ERROR_OUT(-1005, done);
#endif /* HAVE_ECC_DHE */
#ifdef HAVE_ECC_KEY_EXPORT
@ -6735,21 +6748,21 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ret = wc_ecc_export_x963(&userA, exportBuf, &x);
if (ret != 0)
return -1006;
ERROR_OUT(-1006, done);
#ifdef HAVE_ECC_KEY_IMPORT
ret = wc_ecc_import_x963(exportBuf, x, &pubKey);
ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, dp);
if (ret != 0)
return -1007;
ERROR_OUT(-1007, done);
#ifdef HAVE_ECC_DHE
y = sizeof(sharedB);
ret = wc_ecc_shared_secret(&userB, &pubKey, sharedB, &y);
if (ret != 0)
return -1008;
ERROR_OUT(-1008, done);
if (memcmp(sharedA, sharedB, y))
return -1009;
ERROR_OUT(-1009, done);
#endif /* HAVE_ECC_DHE */
if (testCompressedKey) {
@ -6759,22 +6772,22 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ret = wc_ecc_export_x963_ex(&userA, exportBuf, &x, 1);
if (ret != 0)
return -1010;
ERROR_OUT(-1010, done);
wc_ecc_free(&pubKey);
wc_ecc_init(&pubKey);
ret = wc_ecc_import_x963(exportBuf, x, &pubKey);
if (ret != 0)
return -1011;
ERROR_OUT(-1011, done);
#ifdef HAVE_ECC_DHE
y = sizeof(sharedB);
ret = wc_ecc_shared_secret(&userB, &pubKey, sharedB, &y);
if (ret != 0)
return -1012;
ERROR_OUT(-1012, done);
if (memcmp(sharedA, sharedB, y))
return -1013;
ERROR_OUT(-1013, done);
#endif /* HAVE_ECC_DHE */
#endif /* HAVE_COMP_KEY */
}
@ -6792,16 +6805,16 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &x, rng, &userA);
if (ret != 0)
return -1014;
ERROR_OUT(-1014, done);
#ifdef HAVE_ECC_VERIFY
for (i=0; i<testVerifyCount; i++) {
verify = 0;
ret = wc_ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &userA);
if (ret != 0)
return -1015;
ERROR_OUT(-1015, done);
if (verify != 1)
return -1016;
ERROR_OUT(-1016, done);
}
#endif /* HAVE_ECC_VERIFY */
@ -6814,16 +6827,16 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &x, rng, &userA);
if (ret != 0)
return -1014;
ERROR_OUT(-1014, done);
#ifdef HAVE_ECC_VERIFY
for (i=0; i<testVerifyCount; i++) {
verify = 0;
ret = wc_ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &userA);
if (ret != 0)
return -1015;
ERROR_OUT(-1015, done);
if (verify != 1)
return -1016;
ERROR_OUT(-1016, done);
}
#endif /* HAVE_ECC_VERIFY */
#endif /* HAVE_ECC_SIGN */
@ -6832,14 +6845,15 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
x = sizeof(exportBuf);
ret = wc_ecc_export_private_only(&userA, exportBuf, &x);
if (ret != 0)
return -1017;
ERROR_OUT(-1017, done);
#endif /* HAVE_ECC_KEY_EXPORT */
done:
wc_ecc_free(&pubKey);
wc_ecc_free(&userB);
wc_ecc_free(&userA);
return 0;
return ret;
}
#undef ECC_TEST_VERIFY_COUNT
@ -6854,7 +6868,7 @@ static int ecc_test_curve(WC_RNG* rng, int keySize)
}
ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT,
testCompressedKey);
testCompressedKey, NULL);
if (ret < 0) {
printf("ecc_test_curve_size %d failed!: %d\n", keySize, ret);
return ret;
@ -6891,37 +6905,58 @@ int ecc_test(void)
#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
ret = ecc_test_curve(&rng, 24);
if (ret < 0) {
return ret;
goto done;
}
#endif /* HAVE_ECC192 */
#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
ret = ecc_test_curve(&rng, 28);
if (ret < 0) {
return ret;
goto done;
}
#endif /* HAVE_ECC224 */
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
ret = ecc_test_curve(&rng, 32);
if (ret < 0) {
return ret;
goto done;
}
#endif /* !NO_ECC256 */
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
ret = ecc_test_curve(&rng, 48);
if (ret < 0) {
return ret;
goto done;
}
#endif /* HAVE_ECC384 */
#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
ret = ecc_test_curve(&rng, 66);
if (ret < 0) {
return ret;
goto done;
}
#endif /* HAVE_ECC521 */
#if defined(WOLFSSL_CUSTOM_CURVES)
/* Test and demonstrate use of Brainpool256 curve */
const ecc_set_type ecc_cust_dp = {
32, /* size/bytes */
0, /* NID - not required */
"BRAINPOOLP256R1", /* curve name */
"A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */
"7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
"26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */
"8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */
"547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */
};
ret = ecc_test_curve_size(&rng, -1, ECC_TEST_VERIFY_COUNT, 0, &ecc_cust_dp);
if (ret < 0) {
printf("ecc_test_curve_size custom failed!: %d\n", ret);
goto done;
}
#endif
done:
wc_FreeRng(&rng);
return 0;
return ret;
}
#ifdef HAVE_ECC_ENCRYPT
@ -8293,6 +8328,9 @@ int pkcs7signed_test(void)
}
#endif /* HAVE_PKCS7 */
#undef ERROR_OUT
#else
#ifndef NO_MAIN_DRIVER
int main() { return 0; }

View File

@ -60,6 +60,8 @@ typedef struct {
const char* Gy; /* y coordinate of the base point on curve (hex) */
} ecc_set_type;
#define ECC_CUSTOM_IDX (-1)
/* Determine max ECC bits based on enabled curves */
#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
@ -177,6 +179,8 @@ extern const ecc_set_type ecc_sets[];
WOLFSSL_API
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key);
WOLFSSL_API
int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp);
WOLFSSL_API
int wc_ecc_check_key(ecc_key* key);
#ifdef HAVE_ECC_DHE
@ -251,6 +255,9 @@ int wc_ecc_export_x963_ex(ecc_key*, byte* out, word32* outLen, int compressed);
WOLFSSL_API
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key);
WOLFSSL_API
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
const ecc_set_type* dp);
WOLFSSL_API
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
word32 pubSz, ecc_key* key);
WOLFSSL_API
@ -258,6 +265,9 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen);
WOLFSSL_API
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
const char* d, const char* curveName);
WOLFSSL_API
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
const char* d, const ecc_set_type* dp);
#endif /* HAVE_ECC_KEY_IMPORT */
#ifdef HAVE_ECC_KEY_EXPORT