Merge pull request #1048 from dgarske/fix_custcurve

Fixes for using custom curves with `wc_ecc_set_custom_curve`
This commit is contained in:
toddouska
2017-07-25 10:59:58 -07:00
committed by GitHub
3 changed files with 127 additions and 40 deletions

View File

@@ -929,6 +929,15 @@ const ecc_set_type ecc_sets[] = {
},
#endif /* !NO_ECC_SECP */
#endif /* ECC521 */
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
/* place holder for custom curve index for cache */
{
1, /* non-zero */
ECC_CURVE_CUSTOM,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, 0, 0, 0
},
#endif
{
0, -1,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1233,7 +1242,7 @@ const char* wc_ecc_get_name(int curve_id)
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
{
if (keysize <= 0 && curve_id <= 0) {
if (keysize <= 0 && curve_id < 0) {
return BAD_FUNC_ARG;
}
@@ -1245,6 +1254,10 @@ int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
if (key->idx != ECC_CUSTOM_IDX) {
int x;
/* default values */
key->idx = 0;
key->dp = NULL;
/* find ecc_set based on curve_id or key size */
for (x = 0; ecc_sets[x].size != 0; x++) {
if (curve_id > ECC_CURVE_DEF) {
@@ -2502,7 +2515,8 @@ int wc_ecc_get_curve_idx_from_name(const char* curveName)
len = (word32)XSTRLEN(curveName);
for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
if (XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) {
if (ecc_sets[curve_idx].name &&
XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) {
break;
}
}
@@ -2969,6 +2983,12 @@ static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
}
#endif /* !WOLFSSL_ATECC508A */
static INLINE void wc_ecc_reset(ecc_key* key)
{
/* make sure required key variables are reset */
key->state = ECC_STATE_NONE;
}
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
{
int err;
@@ -2981,10 +3001,8 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
return BAD_FUNC_ARG;
}
/* make sure required key variables are reset */
key->state = ECC_STATE_NONE;
key->idx = 0;
key->dp = NULL;
/* make sure required variables are reset */
wc_ecc_reset(key);
err = wc_ecc_set_curve(key, keysize, curve_id);
if (err != 0) {
@@ -3530,6 +3548,13 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
/* don't use async for key, since we don't support async return here */
if (wc_ecc_init_ex(&pubkey, key->heap, INVALID_DEVID) == MP_OKAY) {
#ifdef WOLFSSL_CUSTOM_CURVES
/* if custom curve, apply params to pubkey */
if (key->idx == ECC_CUSTOM_IDX) {
wc_ecc_set_custom_curve(&pubkey, key->dp);
}
#endif
for (;;) {
if (++loop_check > 64) {
err = RNG_FAILURE_E;
@@ -4777,7 +4802,6 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
#ifndef WOLFSSL_ATECC508A
int compressed = 0;
#endif /* !WOLFSSL_ATECC508A */
void* heap;
if (in == NULL || key == NULL)
return BAD_FUNC_ARG;
@@ -4787,9 +4811,8 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
return ECC_BAD_ARG_E;
}
heap = key->heap; /* save heap */
XMEMSET(key, 0, sizeof(ecc_key));
key->heap = heap; /* restore heap */
/* make sure required variables are reset */
wc_ecc_reset(key);
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
@@ -5086,18 +5109,14 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
/* public optional, NULL if only importing private */
if (pub != NULL) {
ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
} else {
}
else {
if (key == NULL || priv == NULL)
return BAD_FUNC_ARG;
/* make sure required key variables are reset */
key->state = ECC_STATE_NONE;
key->idx = 0;
key->dp = NULL;
/* make sure required variables are reset */
wc_ecc_reset(key);
/* set key size */
ret = wc_ecc_set_curve(key, privSz, curve_id);
@@ -5236,16 +5255,14 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
const char* qy, const char* d, int curve_id)
{
int err = MP_OKAY;
void* heap;
/* if d is NULL, only import as public key using Qx,Qy */
if (key == NULL || qx == NULL || qy == NULL) {
return BAD_FUNC_ARG;
}
heap = key->heap; /* save heap */
XMEMSET(key, 0, sizeof(ecc_key));
key->heap = heap; /* restore heap */
/* make sure required variables are reset */
wc_ecc_reset(key);
/* set curve type and index */
err = wc_ecc_set_curve(key, 0, curve_id);

View File

@@ -10205,7 +10205,7 @@ done:
#endif /* WOLFSSL_KEY_GEN */
static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
int curve_id)
int curve_id, const ecc_set_type* dp)
{
DECLARE_VAR(sharedA, byte, ECC_SHARED_SIZE, HEAP_HINT);
DECLARE_VAR(sharedB, byte, ECC_SHARED_SIZE, HEAP_HINT);
@@ -10225,6 +10225,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
ecc_key userA, userB, pubKey;
(void)testVerifyCount;
(void)dp;
XMEMSET(&userA, 0, sizeof(ecc_key));
XMEMSET(&userB, 0, sizeof(ecc_key));
@@ -10240,6 +10241,17 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
if (ret != 0)
goto done;
#ifdef WOLFSSL_CUSTOM_CURVES
if (dp != NULL) {
ret = wc_ecc_set_custom_curve(&userA, dp);
if (ret != 0)
goto done;
ret = wc_ecc_set_custom_curve(&userB, dp);
if (ret != 0)
goto done;
}
#endif
ret = wc_ecc_make_key_ex(rng, keySize, &userA, curve_id);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &userA.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
@@ -10323,6 +10335,12 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
goto done;
#ifdef HAVE_ECC_KEY_IMPORT
#ifdef WOLFSSL_CUSTOM_CURVES
if (dp != NULL) {
ret = wc_ecc_set_custom_curve(&pubKey, dp);
if (ret != 0) goto done;
}
#endif
ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, curve_id);
if (ret != 0)
goto done;
@@ -10350,10 +10368,16 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
if (ret != 0)
goto done;
wc_ecc_free(&pubKey);
ret = wc_ecc_init_ex(&pubKey, HEAP_HINT, devId);
if (ret != 0)
goto done;
#ifdef WOLFSSL_CUSTOM_CURVES
if (dp != NULL) {
ret = wc_ecc_set_custom_curve(&pubKey, dp);
if (ret != 0) goto done;
}
#endif
ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, curve_id);
if (ret != 0)
goto done;
@@ -10482,7 +10506,7 @@ static int ecc_test_curve(WC_RNG* rng, int keySize)
{
int ret;
ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, ECC_CURVE_DEF);
ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, ECC_CURVE_DEF, NULL);
if (ret < 0) {
if (ret == ECC_CURVE_OID_E) {
/* ignore error for curves not found */
@@ -11079,6 +11103,60 @@ done:
}
#endif /* WOLFSSL_CERT_EXT */
#ifdef WOLFSSL_CUSTOM_CURVES
static int ecc_test_custom_curves(WC_RNG* rng)
{
int ret;
/* test use of custom curve - using BRAINPOOLP256R1 for test */
const word32 ecc_oid_brainpoolp256r1_sum = 104;
const ecc_oid_t ecc_oid_brainpoolp256r1[] = {
0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07
};
const ecc_set_type ecc_dp_brainpool256r1 = {
32, /* size/bytes */
ECC_CURVE_CUSTOM, /* ID */
"BRAINPOOLP256R1", /* curve name */
"A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */
"7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
"26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */
"8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */
"547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */
ecc_oid_brainpoolp256r1, /* oid/oidSz */
sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t),
ecc_oid_brainpoolp256r1_sum, /* oid sum */
1, /* cofactor */
};
ret = ecc_test_curve_size(rng, 0, ECC_TEST_VERIFY_COUNT, ECC_CURVE_DEF,
&ecc_dp_brainpool256r1);
if (ret != 0) {
printf("ECC test for custom curve failed! %d\n", ret);
return ret;
}
#if defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)
{
int curve_id;
#ifdef HAVE_ECC_BRAINPOOL
curve_id = ECC_BRAINPOOLP256R1;
#else
curve_id = ECC_SECP256K1;
#endif
/* Test and demonstrate use of non-SECP curve */
ret = ecc_test_curve_size(rng, 0, ECC_TEST_VERIFY_COUNT, curve_id, NULL);
if (ret < 0) {
printf("ECC test for curve_id %d failed! %d\n", curve_id, ret);
return ret;
}
}
#endif
return ret;
}
#endif /* WOLFSSL_CUSTOM_CURVES */
int ecc_test(void)
{
int ret;
@@ -11177,22 +11255,10 @@ int ecc_test(void)
#endif /* HAVE_ECC521 */
#if defined(WOLFSSL_CUSTOM_CURVES)
#if defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)
{
int curve_id;
#ifdef HAVE_ECC_BRAINPOOL
curve_id = ECC_BRAINPOOLP256R1;
#else
curve_id = ECC_SECP256K1;
#endif
/* Test and demonstrate use of non-SECP curve */
ret = ecc_test_curve_size(&rng, 0, ECC_TEST_VERIFY_COUNT, curve_id);
if (ret < 0) {
printf("ecc_test_curve_size: type %d: failed!: %d\n", curve_id, ret);
goto done;
}
ret = ecc_test_custom_curves(&rng);
if (ret != 0) {
goto done;
}
#endif
#endif
#ifdef HAVE_ECC_CDH

View File

@@ -158,6 +158,10 @@ typedef enum ecc_curve_id {
#ifdef HAVE_X448
ECC_X448,
#endif
#ifdef WOLFSSL_CUSTOM_CURVES
ECC_CURVE_CUSTOM,
#endif
} ecc_curve_id;
#ifdef HAVE_OID_ENCODING