mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +02:00
fix ecc sign/hash truncation with odd bit sizes when hash length is longer than key size
This commit is contained in:
@@ -1144,10 +1144,17 @@ int ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
|||||||
err = mp_read_radix(&p, (char *)key->dp->order, 16);
|
err = mp_read_radix(&p, (char *)key->dp->order, 16);
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
int truncLen = (int)inlen;
|
/* we may need to truncate if hash is longer than key size */
|
||||||
if (truncLen > ecc_size(key))
|
word32 orderBits = mp_count_bits(&p);
|
||||||
truncLen = ecc_size(key);
|
|
||||||
err = mp_read_unsigned_bin(&e, (byte*)in, truncLen);
|
/* truncate down to byte size, may be all that's needed */
|
||||||
|
if ( (CYASSL_BIT_SIZE * inlen) > orderBits)
|
||||||
|
inlen = (orderBits + CYASSL_BIT_SIZE - 1)/CYASSL_BIT_SIZE;
|
||||||
|
err = mp_read_unsigned_bin(&e, (byte*)in, inlen);
|
||||||
|
|
||||||
|
/* may still need bit truncation too */
|
||||||
|
if (err == MP_OKAY && (CYASSL_BIT_SIZE * inlen) > orderBits)
|
||||||
|
mp_rshb(&e, CYASSL_BIT_SIZE - (orderBits & 0x7));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make up a key and export the public copy */
|
/* make up a key and export the public copy */
|
||||||
@@ -1311,10 +1318,17 @@ int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen,
|
|||||||
}
|
}
|
||||||
/* read hash */
|
/* read hash */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
int truncLen = (int)hashlen;
|
/* we may need to truncate if hash is longer than key size */
|
||||||
if (truncLen > ecc_size(key))
|
unsigned int orderBits = mp_count_bits(&p);
|
||||||
truncLen = ecc_size(key);
|
|
||||||
err = mp_read_unsigned_bin(&e, (byte*)hash, truncLen);
|
/* truncate down to byte size, may be all that's needed */
|
||||||
|
if ( (CYASSL_BIT_SIZE * hashlen) > orderBits)
|
||||||
|
hashlen = (orderBits + CYASSL_BIT_SIZE - 1)/CYASSL_BIT_SIZE;
|
||||||
|
err = mp_read_unsigned_bin(&e, (byte*)hash, hashlen);
|
||||||
|
|
||||||
|
/* may still need bit truncation too */
|
||||||
|
if (err == MP_OKAY && (CYASSL_BIT_SIZE * hashlen) > orderBits)
|
||||||
|
mp_rshb(&e, CYASSL_BIT_SIZE - (orderBits & 0x7));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* w = s^-1 mod n */
|
/* w = s^-1 mod n */
|
||||||
|
@@ -328,8 +328,7 @@ bn_reverse (unsigned char *s, int len)
|
|||||||
remainder in d) */
|
remainder in d) */
|
||||||
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
||||||
{
|
{
|
||||||
mp_digit D, r, rr;
|
int D, res;
|
||||||
int x, res;
|
|
||||||
mp_int t;
|
mp_int t;
|
||||||
|
|
||||||
|
|
||||||
@@ -366,33 +365,9 @@ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* shift any bit count < DIGIT_BIT */
|
/* shift any bit count < DIGIT_BIT */
|
||||||
D = (mp_digit) (b % DIGIT_BIT);
|
D = (b % DIGIT_BIT);
|
||||||
if (D != 0) {
|
if (D != 0) {
|
||||||
register mp_digit *tmpc, mask, shift;
|
mp_rshb(c, D);
|
||||||
|
|
||||||
/* mask */
|
|
||||||
mask = (((mp_digit)1) << D) - 1;
|
|
||||||
|
|
||||||
/* shift for lsb */
|
|
||||||
shift = DIGIT_BIT - D;
|
|
||||||
|
|
||||||
/* alias */
|
|
||||||
tmpc = c->dp + (c->used - 1);
|
|
||||||
|
|
||||||
/* carry */
|
|
||||||
r = 0;
|
|
||||||
for (x = c->used - 1; x >= 0; x--) {
|
|
||||||
/* get the lower bits of this word in a temp */
|
|
||||||
rr = *tmpc & mask;
|
|
||||||
|
|
||||||
/* shift the current word and mix in the carry bits from the previous
|
|
||||||
word */
|
|
||||||
*tmpc = (*tmpc >> D) | (r << shift);
|
|
||||||
--tmpc;
|
|
||||||
|
|
||||||
/* set the carry to the carry bits of the current word found above */
|
|
||||||
r = rr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mp_clamp (c);
|
mp_clamp (c);
|
||||||
if (d != NULL) {
|
if (d != NULL) {
|
||||||
@@ -457,6 +432,38 @@ mp_exch (mp_int * a, mp_int * b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* shift right a certain number of bits */
|
||||||
|
void mp_rshb (mp_int *c, int x)
|
||||||
|
{
|
||||||
|
register mp_digit *tmpc, mask, shift;
|
||||||
|
mp_digit r, rr;
|
||||||
|
mp_digit D = x;
|
||||||
|
|
||||||
|
/* mask */
|
||||||
|
mask = (((mp_digit)1) << D) - 1;
|
||||||
|
|
||||||
|
/* shift for lsb */
|
||||||
|
shift = DIGIT_BIT - D;
|
||||||
|
|
||||||
|
/* alias */
|
||||||
|
tmpc = c->dp + (c->used - 1);
|
||||||
|
|
||||||
|
/* carry */
|
||||||
|
r = 0;
|
||||||
|
for (x = c->used - 1; x >= 0; x--) {
|
||||||
|
/* get the lower bits of this word in a temp */
|
||||||
|
rr = *tmpc & mask;
|
||||||
|
|
||||||
|
/* shift the current word and mix in the carry bits from previous word */
|
||||||
|
*tmpc = (*tmpc >> D) | (r << shift);
|
||||||
|
--tmpc;
|
||||||
|
|
||||||
|
/* set the carry to the carry bits of the current word found above */
|
||||||
|
r = rr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* shift right a certain amount of digits */
|
/* shift right a certain amount of digits */
|
||||||
void mp_rshd (mp_int * a, int b)
|
void mp_rshd (mp_int * a, int b)
|
||||||
{
|
{
|
||||||
|
@@ -641,8 +641,7 @@ void fp_div_2(fp_int * a, fp_int * b)
|
|||||||
/* c = a / 2**b */
|
/* c = a / 2**b */
|
||||||
void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
|
void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
|
||||||
{
|
{
|
||||||
fp_digit D, r, rr;
|
int D;
|
||||||
int x;
|
|
||||||
fp_int t;
|
fp_int t;
|
||||||
|
|
||||||
/* if the shift count is <= 0 then we do no work */
|
/* if the shift count is <= 0 then we do no work */
|
||||||
@@ -670,32 +669,9 @@ void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* shift any bit count < DIGIT_BIT */
|
/* shift any bit count < DIGIT_BIT */
|
||||||
D = (fp_digit) (b % DIGIT_BIT);
|
D = (b % DIGIT_BIT);
|
||||||
if (D != 0) {
|
if (D != 0) {
|
||||||
register fp_digit *tmpc, mask, shift;
|
fp_rshb(c, D);
|
||||||
|
|
||||||
/* mask */
|
|
||||||
mask = (((fp_digit)1) << D) - 1;
|
|
||||||
|
|
||||||
/* shift for lsb */
|
|
||||||
shift = DIGIT_BIT - D;
|
|
||||||
|
|
||||||
/* alias */
|
|
||||||
tmpc = c->dp + (c->used - 1);
|
|
||||||
|
|
||||||
/* carry */
|
|
||||||
r = 0;
|
|
||||||
for (x = c->used - 1; x >= 0; x--) {
|
|
||||||
/* get the lower bits of this word in a temp */
|
|
||||||
rr = *tmpc & mask;
|
|
||||||
|
|
||||||
/* shift the current word and mix in the carry bits from the previous word */
|
|
||||||
*tmpc = (*tmpc >> D) | (r << shift);
|
|
||||||
--tmpc;
|
|
||||||
|
|
||||||
/* set the carry to the carry bits of the current word found above */
|
|
||||||
r = rr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fp_clamp (c);
|
fp_clamp (c);
|
||||||
if (d != NULL) {
|
if (d != NULL) {
|
||||||
@@ -1754,6 +1730,39 @@ void fp_lshd(fp_int *a, int x)
|
|||||||
fp_clamp(a);
|
fp_clamp(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* right shift by bit count */
|
||||||
|
void fp_rshb(fp_int *c, int x)
|
||||||
|
{
|
||||||
|
register fp_digit *tmpc, mask, shift;
|
||||||
|
fp_digit r, rr;
|
||||||
|
fp_digit D = x;
|
||||||
|
|
||||||
|
/* mask */
|
||||||
|
mask = (((fp_digit)1) << D) - 1;
|
||||||
|
|
||||||
|
/* shift for lsb */
|
||||||
|
shift = DIGIT_BIT - D;
|
||||||
|
|
||||||
|
/* alias */
|
||||||
|
tmpc = c->dp + (c->used - 1);
|
||||||
|
|
||||||
|
/* carry */
|
||||||
|
r = 0;
|
||||||
|
for (x = c->used - 1; x >= 0; x--) {
|
||||||
|
/* get the lower bits of this word in a temp */
|
||||||
|
rr = *tmpc & mask;
|
||||||
|
|
||||||
|
/* shift the current word and mix in the carry bits from previous word */
|
||||||
|
*tmpc = (*tmpc >> D) | (r << shift);
|
||||||
|
--tmpc;
|
||||||
|
|
||||||
|
/* set the carry to the carry bits of the current word found above */
|
||||||
|
r = rr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void fp_rshd(fp_int *a, int x)
|
void fp_rshd(fp_int *a, int x)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
@@ -1959,6 +1968,13 @@ int mp_count_bits (mp_int* a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fast math conversion */
|
||||||
|
void mp_rshb (mp_int* a, int x)
|
||||||
|
{
|
||||||
|
fp_rshb(a, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fast math wrappers */
|
/* fast math wrappers */
|
||||||
int mp_set_int(fp_int *a, fp_digit b)
|
int mp_set_int(fp_int *a, fp_digit b)
|
||||||
{
|
{
|
||||||
|
@@ -233,6 +233,7 @@ void mp_zero (mp_int * a);
|
|||||||
void mp_clamp (mp_int * a);
|
void mp_clamp (mp_int * a);
|
||||||
void mp_exch (mp_int * a, mp_int * b);
|
void mp_exch (mp_int * a, mp_int * b);
|
||||||
void mp_rshd (mp_int * a, int b);
|
void mp_rshd (mp_int * a, int b);
|
||||||
|
void mp_rshb (mp_int * a, int b);
|
||||||
int mp_mod_2d (mp_int * a, int b, mp_int * c);
|
int mp_mod_2d (mp_int * a, int b, mp_int * c);
|
||||||
int mp_mul_2d (mp_int * a, int b, mp_int * c);
|
int mp_mul_2d (mp_int * a, int b, mp_int * c);
|
||||||
int mp_lshd (mp_int * a, int b);
|
int mp_lshd (mp_int * a, int b);
|
||||||
|
@@ -372,6 +372,9 @@ void fp_set(fp_int *a, fp_digit b);
|
|||||||
/* right shift x digits */
|
/* right shift x digits */
|
||||||
void fp_rshd(fp_int *a, int x);
|
void fp_rshd(fp_int *a, int x);
|
||||||
|
|
||||||
|
/* right shift x bits */
|
||||||
|
void fp_rshb(fp_int *a, int x);
|
||||||
|
|
||||||
/* left shift x digits */
|
/* left shift x digits */
|
||||||
void fp_lshd(fp_int *a, int x);
|
void fp_lshd(fp_int *a, int x);
|
||||||
|
|
||||||
@@ -653,6 +656,7 @@ int mp_isodd(mp_int* a);
|
|||||||
int mp_iszero(mp_int* a);
|
int mp_iszero(mp_int* a);
|
||||||
int mp_count_bits(mp_int *a);
|
int mp_count_bits(mp_int *a);
|
||||||
int mp_set_int(fp_int *a, fp_digit b);
|
int mp_set_int(fp_int *a, fp_digit b);
|
||||||
|
void mp_rshb(mp_int *a, int x);
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
int mp_read_radix(mp_int* a, const char* str, int radix);
|
int mp_read_radix(mp_int* a, const char* str, int radix);
|
||||||
|
Reference in New Issue
Block a user