forked from wolfSSL/wolfssl
better detection of invalid ecc keys
This commit is contained in:
@@ -1734,9 +1734,14 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
|||||||
|
|
||||||
/* make up a key and export the public copy */
|
/* make up a key and export the public copy */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
int loop_check = 0;
|
||||||
ecc_key pubkey;
|
ecc_key pubkey;
|
||||||
wc_ecc_init(&pubkey);
|
wc_ecc_init(&pubkey);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (++loop_check > 64) {
|
||||||
|
err = RNG_FAILURE_E;
|
||||||
|
break;
|
||||||
|
}
|
||||||
err = wc_ecc_make_key_ex(rng, &pubkey, key->dp);
|
err = wc_ecc_make_key_ex(rng, &pubkey, key->dp);
|
||||||
if (err != MP_OKAY) break;
|
if (err != MP_OKAY) break;
|
||||||
|
|
||||||
@@ -2311,6 +2316,72 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, int compresse
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* is pubkey point on curve ? */
|
||||||
|
static int ecc_is_point(ecc_key* key)
|
||||||
|
{
|
||||||
|
mp_int prime, b, t1, t2;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL, NULL)) != MP_OKAY) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* load prime and b */
|
||||||
|
err = mp_read_radix(&prime, key->dp->prime, 16);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_read_radix(&b, key->dp->Bf, 16);
|
||||||
|
|
||||||
|
/* compute y^2 */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_sqr(key->pubkey.y, &t1);
|
||||||
|
|
||||||
|
/* compute x^3 */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_sqr(key->pubkey.x, &t2);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_mod(&t2, &prime, &t2);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_mul(key->pubkey.x, &t2, &t2);
|
||||||
|
|
||||||
|
/* compute y^2 - x^3 */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_sub(&t1, &t2, &t1);
|
||||||
|
|
||||||
|
/* compute y^2 - x^3 + 3x */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_add(&t1, key->pubkey.x, &t1);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_add(&t1, key->pubkey.x, &t1);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_add(&t1, key->pubkey.x, &t1);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_mod(&t1, &prime, &t1);
|
||||||
|
|
||||||
|
while (err == MP_OKAY && mp_cmp_d(&t1, 0) == MP_LT) {
|
||||||
|
err = mp_add(&t1, &prime, &t1);
|
||||||
|
}
|
||||||
|
while (err == MP_OKAY && mp_cmp(&t1, &prime) != MP_LT) {
|
||||||
|
err = mp_sub(&t1, &prime, &t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compare to b */
|
||||||
|
if (err == MP_OKAY) {
|
||||||
|
if (mp_cmp(&t1, &b) != MP_EQ) {
|
||||||
|
err = MP_VAL;
|
||||||
|
} else {
|
||||||
|
err = MP_OKAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_clear(&prime);
|
||||||
|
mp_clear(&b);
|
||||||
|
mp_clear(&t1);
|
||||||
|
mp_clear(&t2);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* import public ECC key in ANSI X9.63 format */
|
/* 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(const byte* in, word32 inLen, ecc_key* key)
|
||||||
{
|
{
|
||||||
@@ -2445,6 +2516,12 @@ int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
|
|||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
mp_set(key->pubkey.z, 1);
|
mp_set(key->pubkey.z, 1);
|
||||||
|
|
||||||
|
if (err == MP_OKAY) {
|
||||||
|
err = ecc_is_point(key);
|
||||||
|
if (err != MP_OKAY)
|
||||||
|
err = IS_POINT_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (err != MP_OKAY) {
|
if (err != MP_OKAY) {
|
||||||
mp_clear(key->pubkey.x);
|
mp_clear(key->pubkey.x);
|
||||||
mp_clear(key->pubkey.y);
|
mp_clear(key->pubkey.y);
|
||||||
|
@@ -319,6 +319,9 @@ const char* wc_GetErrorString(int error)
|
|||||||
case MAC_CMP_FAILED_E:
|
case MAC_CMP_FAILED_E:
|
||||||
return "MAC comparison failed";
|
return "MAC comparison failed";
|
||||||
|
|
||||||
|
case IS_POINT_E:
|
||||||
|
return "ECC is point on curve failed";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
|
|
||||||
|
@@ -866,7 +866,7 @@ int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
|||||||
int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||||
{
|
{
|
||||||
mp_int x, y, u, v, B, D;
|
mp_int x, y, u, v, B, D;
|
||||||
int res, neg;
|
int res, neg, loop_check = 0;
|
||||||
|
|
||||||
/* 2. [modified] b must be odd */
|
/* 2. [modified] b must be odd */
|
||||||
if (mp_iseven (b) == 1) {
|
if (mp_iseven (b) == 1) {
|
||||||
@@ -958,6 +958,10 @@ top:
|
|||||||
|
|
||||||
/* if not zero goto step 4 */
|
/* if not zero goto step 4 */
|
||||||
if (mp_iszero (&u) == 0) {
|
if (mp_iszero (&u) == 0) {
|
||||||
|
if (++loop_check > 1024) {
|
||||||
|
res = MP_VAL;
|
||||||
|
goto LBL_ERR;
|
||||||
|
}
|
||||||
goto top;
|
goto top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -863,11 +863,12 @@ top:
|
|||||||
return FP_OKAY;
|
return FP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* c = 1/a (mod b) for odd b only */
|
/* c = 1/a (mod b) for odd b only */
|
||||||
int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
|
int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
|
||||||
{
|
{
|
||||||
fp_int x, y, u, v, B, D;
|
fp_int x, y, u, v, B, D;
|
||||||
int neg;
|
int neg, loop_check = 0;
|
||||||
|
|
||||||
/* 2. [modified] b must be odd */
|
/* 2. [modified] b must be odd */
|
||||||
if (fp_iseven (b) == FP_YES) {
|
if (fp_iseven (b) == FP_YES) {
|
||||||
@@ -931,6 +932,8 @@ top:
|
|||||||
|
|
||||||
/* if not zero goto step 4 */
|
/* if not zero goto step 4 */
|
||||||
if (fp_iszero (&u) == FP_NO) {
|
if (fp_iszero (&u) == FP_NO) {
|
||||||
|
if (++loop_check > 1024) /* bad input */
|
||||||
|
return FP_VAL;
|
||||||
goto top;
|
goto top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -147,6 +147,7 @@ enum {
|
|||||||
THREAD_STORE_SET_E = -212, /* Thread local storage key set failure */
|
THREAD_STORE_SET_E = -212, /* Thread local storage key set failure */
|
||||||
|
|
||||||
MAC_CMP_FAILED_E = -213, /* MAC comparison failed */
|
MAC_CMP_FAILED_E = -213, /* MAC comparison failed */
|
||||||
|
IS_POINT_E = -214, /* ECC is point on curve failed */
|
||||||
|
|
||||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||||
};
|
};
|
||||||
|
@@ -366,7 +366,7 @@ typedef struct {
|
|||||||
|
|
||||||
/* zero/even/odd ? */
|
/* zero/even/odd ? */
|
||||||
#define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO)
|
#define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO)
|
||||||
#define fp_iseven(a) (((a)->used >= 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO)
|
#define fp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO)
|
||||||
#define fp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO)
|
#define fp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO)
|
||||||
|
|
||||||
/* set to a small digit */
|
/* set to a small digit */
|
||||||
|
Reference in New Issue
Block a user