mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
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 */
|
||||
if (err == MP_OKAY) {
|
||||
int loop_check = 0;
|
||||
ecc_key pubkey;
|
||||
wc_ecc_init(&pubkey);
|
||||
for (;;) {
|
||||
if (++loop_check > 64) {
|
||||
err = RNG_FAILURE_E;
|
||||
break;
|
||||
}
|
||||
err = wc_ecc_make_key_ex(rng, &pubkey, key->dp);
|
||||
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 */
|
||||
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)
|
||||
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) {
|
||||
mp_clear(key->pubkey.x);
|
||||
mp_clear(key->pubkey.y);
|
||||
|
@@ -319,6 +319,9 @@ const char* wc_GetErrorString(int error)
|
||||
case MAC_CMP_FAILED_E:
|
||||
return "MAC comparison failed";
|
||||
|
||||
case IS_POINT_E:
|
||||
return "ECC is point on curve failed";
|
||||
|
||||
default:
|
||||
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)
|
||||
{
|
||||
mp_int x, y, u, v, B, D;
|
||||
int res, neg;
|
||||
int res, neg, loop_check = 0;
|
||||
|
||||
/* 2. [modified] b must be odd */
|
||||
if (mp_iseven (b) == 1) {
|
||||
@@ -958,6 +958,10 @@ top:
|
||||
|
||||
/* if not zero goto step 4 */
|
||||
if (mp_iszero (&u) == 0) {
|
||||
if (++loop_check > 1024) {
|
||||
res = MP_VAL;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
goto top;
|
||||
}
|
||||
|
||||
|
@@ -863,11 +863,12 @@ top:
|
||||
return FP_OKAY;
|
||||
}
|
||||
|
||||
|
||||
/* c = 1/a (mod b) for odd b only */
|
||||
int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
|
||||
{
|
||||
fp_int x, y, u, v, B, D;
|
||||
int neg;
|
||||
int neg, loop_check = 0;
|
||||
|
||||
/* 2. [modified] b must be odd */
|
||||
if (fp_iseven (b) == FP_YES) {
|
||||
@@ -931,6 +932,8 @@ top:
|
||||
|
||||
/* if not zero goto step 4 */
|
||||
if (fp_iszero (&u) == FP_NO) {
|
||||
if (++loop_check > 1024) /* bad input */
|
||||
return FP_VAL;
|
||||
goto top;
|
||||
}
|
||||
|
||||
|
@@ -147,6 +147,7 @@ enum {
|
||||
THREAD_STORE_SET_E = -212, /* Thread local storage key set failure */
|
||||
|
||||
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 */
|
||||
};
|
||||
|
@@ -366,7 +366,7 @@ typedef struct {
|
||||
|
||||
/* zero/even/odd ? */
|
||||
#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)
|
||||
|
||||
/* set to a small digit */
|
||||
|
Reference in New Issue
Block a user