forked from wolfSSL/wolfssl
Fixes to reduce stack usage with ECC_CACHE_CURVE disabled (same as previous code). Added USE_ECC_B_PARAM macro (enabled with ECC_CACHE_CURVE or HAVE_COMP_KEY). Fixed bug with WOLFSSL_VALIDATE_ECC_KEYGEN defined and args to ecc_check_pubkey_order. Fixed counts for DECLARE_CURVE_SPECS(). Fixed wc_ecc_import_point_der to use curve cache. Enhance wc_ecc_check_key to support ECC_CACHE_CURVE for b or load using read_radix. Enhance to expose wc_ecc_is_point with all required mp_int* args directly.
This commit is contained in:
@ -46,6 +46,8 @@ Possible ECC enable options:
|
|||||||
* ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance
|
* ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance
|
||||||
default: off
|
default: off
|
||||||
* FP_ECC: ECC Fixed Point Cache default: off
|
* FP_ECC: ECC Fixed Point Cache default: off
|
||||||
|
* USE_ECC_B_PARAM: Enable ECC curve B param default: off
|
||||||
|
(on for HAVE_COMP_KEY)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -970,7 +972,9 @@ typedef struct ecc_curve_spec {
|
|||||||
|
|
||||||
mp_int* prime;
|
mp_int* prime;
|
||||||
mp_int* Af;
|
mp_int* Af;
|
||||||
mp_int* Bf;
|
#ifdef USE_ECC_B_PARAM
|
||||||
|
mp_int* Bf;
|
||||||
|
#endif
|
||||||
mp_int* order;
|
mp_int* order;
|
||||||
mp_int* Gx;
|
mp_int* Gx;
|
||||||
mp_int* Gy;
|
mp_int* Gy;
|
||||||
@ -978,7 +982,9 @@ typedef struct ecc_curve_spec {
|
|||||||
#ifdef ECC_CACHE_CURVE
|
#ifdef ECC_CACHE_CURVE
|
||||||
mp_int prime_lcl;
|
mp_int prime_lcl;
|
||||||
mp_int Af_lcl;
|
mp_int Af_lcl;
|
||||||
mp_int Bf_lcl;
|
#ifdef USE_ECC_B_PARAM
|
||||||
|
mp_int Bf_lcl;
|
||||||
|
#endif
|
||||||
mp_int order_lcl;
|
mp_int order_lcl;
|
||||||
mp_int Gx_lcl;
|
mp_int Gx_lcl;
|
||||||
mp_int Gy_lcl;
|
mp_int Gy_lcl;
|
||||||
@ -995,11 +1001,19 @@ enum ecc_curve_load_mask {
|
|||||||
ECC_CURVE_FIELD_NONE = 0x00,
|
ECC_CURVE_FIELD_NONE = 0x00,
|
||||||
ECC_CURVE_FIELD_PRIME = 0x01,
|
ECC_CURVE_FIELD_PRIME = 0x01,
|
||||||
ECC_CURVE_FIELD_AF = 0x02,
|
ECC_CURVE_FIELD_AF = 0x02,
|
||||||
|
#ifdef USE_ECC_B_PARAM
|
||||||
ECC_CURVE_FIELD_BF = 0x04,
|
ECC_CURVE_FIELD_BF = 0x04,
|
||||||
|
#endif
|
||||||
ECC_CURVE_FIELD_ORDER = 0x08,
|
ECC_CURVE_FIELD_ORDER = 0x08,
|
||||||
ECC_CURVE_FIELD_GX = 0x10,
|
ECC_CURVE_FIELD_GX = 0x10,
|
||||||
ECC_CURVE_FIELD_GY = 0x20,
|
ECC_CURVE_FIELD_GY = 0x20,
|
||||||
ECC_CURVE_FIELD_ALL = 0x3F
|
#ifdef USE_ECC_B_PARAM
|
||||||
|
ECC_CURVE_FIELD_ALL = 0x3F,
|
||||||
|
ECC_CURVE_FIELD_COUNT = 6,
|
||||||
|
#else
|
||||||
|
ECC_CURVE_FIELD_ALL = 0x3B,
|
||||||
|
ECC_CURVE_FIELD_COUNT = 5,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ECC_CACHE_CURVE
|
#ifdef ECC_CACHE_CURVE
|
||||||
@ -1029,8 +1043,10 @@ static void _wc_ecc_curve_free(ecc_curve_spec* curve)
|
|||||||
mp_clear(curve->prime);
|
mp_clear(curve->prime);
|
||||||
if (curve->load_mask & ECC_CURVE_FIELD_AF)
|
if (curve->load_mask & ECC_CURVE_FIELD_AF)
|
||||||
mp_clear(curve->Af);
|
mp_clear(curve->Af);
|
||||||
|
#ifdef USE_ECC_B_PARAM
|
||||||
if (curve->load_mask & ECC_CURVE_FIELD_BF)
|
if (curve->load_mask & ECC_CURVE_FIELD_BF)
|
||||||
mp_clear(curve->Bf);
|
mp_clear(curve->Bf);
|
||||||
|
#endif
|
||||||
if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
|
if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
|
||||||
mp_clear(curve->order);
|
mp_clear(curve->order);
|
||||||
if (curve->load_mask & ECC_CURVE_FIELD_GX)
|
if (curve->load_mask & ECC_CURVE_FIELD_GX)
|
||||||
@ -1114,7 +1130,9 @@ static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
|
|||||||
#ifdef ECC_CACHE_CURVE
|
#ifdef ECC_CACHE_CURVE
|
||||||
curve->prime = &curve->prime_lcl;
|
curve->prime = &curve->prime_lcl;
|
||||||
curve->Af = &curve->Af_lcl;
|
curve->Af = &curve->Af_lcl;
|
||||||
curve->Bf = &curve->Bf_lcl;
|
#ifdef USE_ECC_B_PARAM
|
||||||
|
curve->Bf = &curve->Bf_lcl;
|
||||||
|
#endif
|
||||||
curve->order = &curve->order_lcl;
|
curve->order = &curve->order_lcl;
|
||||||
curve->Gx = &curve->Gx_lcl;
|
curve->Gx = &curve->Gx_lcl;
|
||||||
curve->Gy = &curve->Gy_lcl;
|
curve->Gy = &curve->Gy_lcl;
|
||||||
@ -1133,9 +1151,11 @@ static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
|
|||||||
if (load_items & ECC_CURVE_FIELD_AF)
|
if (load_items & ECC_CURVE_FIELD_AF)
|
||||||
x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
|
x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
|
||||||
ECC_CURVE_FIELD_AF);
|
ECC_CURVE_FIELD_AF);
|
||||||
|
#ifdef USE_ECC_B_PARAM
|
||||||
if (load_items & ECC_CURVE_FIELD_BF)
|
if (load_items & ECC_CURVE_FIELD_BF)
|
||||||
x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
|
x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
|
||||||
ECC_CURVE_FIELD_BF);
|
ECC_CURVE_FIELD_BF);
|
||||||
|
#endif
|
||||||
if (load_items & ECC_CURVE_FIELD_ORDER)
|
if (load_items & ECC_CURVE_FIELD_ORDER)
|
||||||
x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
|
x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
|
||||||
ECC_CURVE_FIELD_ORDER);
|
ECC_CURVE_FIELD_ORDER);
|
||||||
@ -2713,7 +2733,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
|
|||||||
int err;
|
int err;
|
||||||
#ifndef WOLFSSL_ATECC508A
|
#ifndef WOLFSSL_ATECC508A
|
||||||
ecc_point* base = NULL;
|
ecc_point* base = NULL;
|
||||||
DECLARE_CURVE_SPECS(6)
|
DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (key == NULL || rng == NULL) {
|
if (key == NULL || rng == NULL) {
|
||||||
@ -2798,8 +2818,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
|
|||||||
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
|
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
|
||||||
/* validate the public key, order * pubkey = point at infinity */
|
/* validate the public key, order * pubkey = point at infinity */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = ecc_check_pubkey_order(key, curve->Af, curve->Bf, curve->prime,
|
err = ecc_check_pubkey_order(key, curve->Af, curve->prime, curve->order);
|
||||||
curve->order);
|
|
||||||
#endif /* WOLFSSL_VALIDATE_KEYGEN */
|
#endif /* WOLFSSL_VALIDATE_KEYGEN */
|
||||||
|
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
@ -3615,7 +3634,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
mp_int u1;
|
mp_int u1;
|
||||||
mp_int u2;
|
mp_int u2;
|
||||||
mp_int e;
|
mp_int e;
|
||||||
DECLARE_CURVE_SPECS(6)
|
DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
|
||||||
#else
|
#else
|
||||||
byte sigRS[ATECC_KEY_SIZE*2];
|
byte sigRS[ATECC_KEY_SIZE*2];
|
||||||
#endif
|
#endif
|
||||||
@ -3840,61 +3859,58 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
|
|||||||
|
|
||||||
#ifdef HAVE_COMP_KEY
|
#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;
|
mp_int t1, t2;
|
||||||
|
DECLARE_CURVE_SPECS(3)
|
||||||
|
|
||||||
int did_init = 0;
|
int did_init = 0;
|
||||||
|
|
||||||
if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY)
|
if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
|
||||||
err = MEMORY_E;
|
err = MEMORY_E;
|
||||||
else
|
else
|
||||||
did_init = 1;
|
did_init = 1;
|
||||||
|
|
||||||
/* read in the specs for this curve */
|
/* load curve info */
|
||||||
if (err == MP_OKAY)
|
err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
|
||||||
err = mp_read_radix(&prime, ecc_sets[curve_idx].prime, 16);
|
(ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_BF));
|
||||||
if (err == MP_OKAY)
|
|
||||||
err = mp_read_radix(&a, ecc_sets[curve_idx].Af, 16);
|
|
||||||
if (err == MP_OKAY)
|
|
||||||
err = mp_read_radix(&b, ecc_sets[curve_idx].Bf, 16);
|
|
||||||
|
|
||||||
/* compute x^3 */
|
/* compute x^3 */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_sqr(point->x, &t1);
|
err = mp_sqr(point->x, &t1);
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_mulmod(&t1, point->x, &prime, &t1);
|
err = mp_mulmod(&t1, point->x, curve->prime, &t1);
|
||||||
|
|
||||||
/* compute x^3 + a*x */
|
/* compute x^3 + a*x */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_mulmod(&a, point->x, &prime, &t2);
|
err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_add(&t1, &t2, &t1);
|
err = mp_add(&t1, &t2, &t1);
|
||||||
|
|
||||||
/* compute x^3 + a*x + b */
|
/* compute x^3 + a*x + b */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_add(&t1, &b, &t1);
|
err = mp_add(&t1, curve->Bf, &t1);
|
||||||
|
|
||||||
/* compute sqrt(x^3 + a*x + b) */
|
/* compute sqrt(x^3 + a*x + b) */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_sqrtmod_prime(&t1, &prime, &t2);
|
err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
|
||||||
|
|
||||||
/* adjust y */
|
/* adjust y */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) ||
|
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, point->y);
|
err = mp_mod(&t2, curve->prime, point->y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err = mp_submod(&prime, &t2, &prime, point->y);
|
err = mp_submod(curve->prime, &t2, curve->prime, point->y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (did_init) {
|
if (did_init) {
|
||||||
#ifndef USE_FAST_MATH
|
#ifndef USE_FAST_MATH
|
||||||
mp_clear(&a);
|
|
||||||
mp_clear(&b);
|
|
||||||
mp_clear(&prime);
|
|
||||||
mp_clear(&t2);
|
mp_clear(&t2);
|
||||||
mp_clear(&t1);
|
mp_clear(&t1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
wc_ecc_curve_free(curve);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4098,20 +4114,15 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
|
|||||||
#ifndef WOLFSSL_ATECC508A
|
#ifndef WOLFSSL_ATECC508A
|
||||||
|
|
||||||
/* is ecc point on curve described by dp ? */
|
/* is ecc point on curve described by dp ? */
|
||||||
static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
|
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
|
||||||
{
|
{
|
||||||
mp_int a, b, t1, t2;
|
|
||||||
int err;
|
int err;
|
||||||
|
mp_int t1, t2;
|
||||||
|
|
||||||
if ((err = mp_init_multi(&a, &b, &t1, &t2, NULL, NULL)) != MP_OKAY) {
|
if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read in the specs for this curve */
|
|
||||||
err = mp_read_radix(&a, dp->Af, 16);
|
|
||||||
if (err == MP_OKAY)
|
|
||||||
err = mp_read_radix(&b, dp->Bf, 16);
|
|
||||||
|
|
||||||
/* compute y^2 */
|
/* compute y^2 */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_sqr(ecp->y, &t1);
|
err = mp_sqr(ecp->y, &t1);
|
||||||
@ -4133,7 +4144,7 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
|
|||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
/* Use a and prime to determine if a == 3 */
|
/* Use a and prime to determine if a == 3 */
|
||||||
mp_set(&t2, 0);
|
mp_set(&t2, 0);
|
||||||
err = mp_submod(prime, &a, prime, &t2);
|
err = mp_submod(prime, a, prime, &t2);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) {
|
if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) {
|
||||||
/* compute y^2 - x^3 + a*x */
|
/* compute y^2 - x^3 + a*x */
|
||||||
@ -4169,7 +4180,7 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
|
|||||||
|
|
||||||
/* compare to b */
|
/* compare to b */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
if (mp_cmp(&t1, &b) != MP_EQ) {
|
if (mp_cmp(&t1, b) != MP_EQ) {
|
||||||
err = MP_VAL;
|
err = MP_VAL;
|
||||||
} else {
|
} else {
|
||||||
err = MP_OKAY;
|
err = MP_OKAY;
|
||||||
@ -4177,8 +4188,6 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_FAST_MATH
|
#ifndef USE_FAST_MATH
|
||||||
mp_clear(&a);
|
|
||||||
mp_clear(&b);
|
|
||||||
mp_clear(&t1);
|
mp_clear(&t1);
|
||||||
mp_clear(&t2);
|
mp_clear(&t2);
|
||||||
#endif
|
#endif
|
||||||
@ -4307,7 +4316,15 @@ int wc_ecc_check_key(ecc_key* key)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
#ifndef WOLFSSL_ATECC508A
|
#ifndef WOLFSSL_ATECC508A
|
||||||
|
mp_int* b;
|
||||||
|
#ifdef USE_ECC_B_PARAM
|
||||||
DECLARE_CURVE_SPECS(4)
|
DECLARE_CURVE_SPECS(4)
|
||||||
|
#else
|
||||||
|
mp_int b_lcl;
|
||||||
|
DECLARE_CURVE_SPECS(3)
|
||||||
|
b = &b_lcl;
|
||||||
|
XMEMSET(b, 0, sizeof(mp_int));
|
||||||
|
#endif
|
||||||
#endif /* WOLFSSL_ATECC508A */
|
#endif /* WOLFSSL_ATECC508A */
|
||||||
|
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
@ -4325,11 +4342,25 @@ int wc_ecc_check_key(ecc_key* key)
|
|||||||
|
|
||||||
/* load curve info */
|
/* load curve info */
|
||||||
err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
|
err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
|
||||||
ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_BF | ECC_CURVE_FIELD_ORDER));
|
ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
|
||||||
|
#ifdef USE_ECC_B_PARAM
|
||||||
|
| ECC_CURVE_FIELD_BF
|
||||||
|
#endif
|
||||||
|
));
|
||||||
|
|
||||||
|
#ifndef USE_ECC_B_PARAM
|
||||||
|
/* load curve b parameter */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_init(b);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_read_radix(b, key->dp->Bf, 16);
|
||||||
|
#else
|
||||||
|
b = curve->Bf;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* make sure point is actually on curve */
|
/* make sure point is actually on curve */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = ecc_is_point(key->dp, &key->pubkey, curve->prime);
|
err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
|
||||||
|
|
||||||
/* pubkey * order must be at infinity */
|
/* pubkey * order must be at infinity */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
@ -4341,6 +4372,10 @@ int wc_ecc_check_key(ecc_key* key)
|
|||||||
|
|
||||||
wc_ecc_curve_free(curve);
|
wc_ecc_curve_free(curve);
|
||||||
|
|
||||||
|
#ifndef USE_ECC_B_PARAM
|
||||||
|
mp_clear(b);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* WOLFSSL_ATECC508A */
|
#endif /* WOLFSSL_ATECC508A */
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -48,6 +48,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Enable curve B parameter if needed */
|
||||||
|
#if defined(HAVE_COMP_KEY) || defined(ECC_CACHE_CURVE)
|
||||||
|
#ifndef USE_ECC_B_PARAM /* Allow someone to force enable */
|
||||||
|
#define USE_ECC_B_PARAM
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Use this as the key->idx if a custom ecc_set is used for key->dp */
|
/* Use this as the key->idx if a custom ecc_set is used for key->dp */
|
||||||
#define ECC_CUSTOM_IDX (-1)
|
#define ECC_CUSTOM_IDX (-1)
|
||||||
|
|
||||||
@ -278,6 +286,8 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
|
|||||||
int curve_id);
|
int curve_id);
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
int wc_ecc_check_key(ecc_key* key);
|
int wc_ecc_check_key(ecc_key* key);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime);
|
||||||
|
|
||||||
#ifdef HAVE_ECC_DHE
|
#ifdef HAVE_ECC_DHE
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
|
Reference in New Issue
Block a user