forked from wolfSSL/wolfssl
ECDSA signatures need a zero padding for the ASN.1 storage of the R and S values
This commit is contained in:
@@ -4390,6 +4390,9 @@ int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
|
|||||||
word32 sSz;
|
word32 sSz;
|
||||||
word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */
|
word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */
|
||||||
|
|
||||||
|
/* If the leading bit on the INTEGER is a 1, add a leading zero */
|
||||||
|
int rLeadingZero = mp_leading_bit(r);
|
||||||
|
int sLeadingZero = mp_leading_bit(s);
|
||||||
int rLen = mp_unsigned_bin_size(r); /* big int size */
|
int rLen = mp_unsigned_bin_size(r); /* big int size */
|
||||||
int sLen = mp_unsigned_bin_size(s);
|
int sLen = mp_unsigned_bin_size(s);
|
||||||
int err;
|
int err;
|
||||||
@@ -4397,20 +4400,24 @@ int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
|
|||||||
if (*outLen < (rLen + sLen + headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */
|
if (*outLen < (rLen + sLen + headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
idx = SetSequence(rLen + sLen + headerSz, out);
|
idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out);
|
||||||
|
|
||||||
/* store r */
|
/* store r */
|
||||||
out[idx++] = ASN_INTEGER;
|
out[idx++] = ASN_INTEGER;
|
||||||
rSz = SetLength(rLen, &out[idx]);
|
rSz = SetLength(rLen + rLeadingZero, &out[idx]);
|
||||||
idx += rSz;
|
idx += rSz;
|
||||||
|
if (rLeadingZero)
|
||||||
|
out[idx++] = 0;
|
||||||
err = mp_to_unsigned_bin(r, &out[idx]);
|
err = mp_to_unsigned_bin(r, &out[idx]);
|
||||||
if (err != MP_OKAY) return err;
|
if (err != MP_OKAY) return err;
|
||||||
idx += rLen;
|
idx += rLen;
|
||||||
|
|
||||||
/* store s */
|
/* store s */
|
||||||
out[idx++] = ASN_INTEGER;
|
out[idx++] = ASN_INTEGER;
|
||||||
sSz = SetLength(sLen, &out[idx]);
|
sSz = SetLength(sLen + sLeadingZero, &out[idx]);
|
||||||
idx += sSz;
|
idx += sSz;
|
||||||
|
if (sLeadingZero)
|
||||||
|
out[idx++] = 0;
|
||||||
err = mp_to_unsigned_bin(s, &out[idx]);
|
err = mp_to_unsigned_bin(s, &out[idx]);
|
||||||
if (err != MP_OKAY) return err;
|
if (err != MP_OKAY) return err;
|
||||||
idx += sLen;
|
idx += sLen;
|
||||||
|
@@ -179,6 +179,28 @@ mp_count_bits (mp_int * a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mp_leading_bit (mp_int * a)
|
||||||
|
{
|
||||||
|
int bit = 0;
|
||||||
|
mp_int t;
|
||||||
|
|
||||||
|
if (mp_init_copy(&t, a) != MP_OKAY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (mp_iszero(&t) == 0) {
|
||||||
|
#ifndef MP_8BIT
|
||||||
|
bit = (t.dp[0] & 0x80) != 0;
|
||||||
|
#else
|
||||||
|
bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0;
|
||||||
|
#endif
|
||||||
|
if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mp_clear(&t);
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* store in unsigned [big endian] format */
|
/* store in unsigned [big endian] format */
|
||||||
int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
|
int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
|
||||||
{
|
{
|
||||||
|
@@ -1706,6 +1706,25 @@ int fp_count_bits (fp_int * a)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fp_leading_bit(fp_int *a)
|
||||||
|
{
|
||||||
|
int bit = 0;
|
||||||
|
|
||||||
|
if (a->used != 0) {
|
||||||
|
fp_digit q = a->dp[a->used - 1];
|
||||||
|
int qSz = sizeof(fp_digit);
|
||||||
|
|
||||||
|
while (qSz > 0) {
|
||||||
|
if ((unsigned char)q != 0)
|
||||||
|
bit = (q & 0x80) != 0;
|
||||||
|
q >>= 8;
|
||||||
|
qSz--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
void fp_lshd(fp_int *a, int x)
|
void fp_lshd(fp_int *a, int x)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
@@ -1968,6 +1987,12 @@ int mp_count_bits (mp_int* a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mp_leading_bit (mp_int* a)
|
||||||
|
{
|
||||||
|
return fp_leading_bit(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fast math conversion */
|
/* fast math conversion */
|
||||||
void mp_rshb (mp_int* a, int x)
|
void mp_rshb (mp_int* a, int x)
|
||||||
{
|
{
|
||||||
|
@@ -225,6 +225,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
|
|||||||
|
|
||||||
/* functions added to support above needed, removed TOOM and KARATSUBA */
|
/* functions added to support above needed, removed TOOM and KARATSUBA */
|
||||||
int mp_count_bits (mp_int * a);
|
int mp_count_bits (mp_int * a);
|
||||||
|
int mp_leading_bit (mp_int * a);
|
||||||
int mp_init_copy (mp_int * a, mp_int * b);
|
int mp_init_copy (mp_int * a, mp_int * b);
|
||||||
int mp_copy (mp_int * a, mp_int * b);
|
int mp_copy (mp_int * a, mp_int * b);
|
||||||
int mp_grow (mp_int * a, int size);
|
int mp_grow (mp_int * a, int size);
|
||||||
|
@@ -490,6 +490,7 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);
|
|||||||
|
|
||||||
/* radix conersions */
|
/* radix conersions */
|
||||||
int fp_count_bits(fp_int *a);
|
int fp_count_bits(fp_int *a);
|
||||||
|
int fp_leading_bit(fp_int *a);
|
||||||
|
|
||||||
int fp_unsigned_bin_size(fp_int *a);
|
int fp_unsigned_bin_size(fp_int *a);
|
||||||
void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c);
|
void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c);
|
||||||
@@ -655,6 +656,7 @@ int mp_copy(fp_int* a, fp_int* b);
|
|||||||
int mp_isodd(mp_int* a);
|
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_leading_bit(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);
|
void mp_rshb(mp_int *a, int x);
|
||||||
|
|
||||||
|
@@ -8433,7 +8433,7 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
|
ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
|
||||||
&dsaKey, ssl->buffers.key.length);
|
&dsaKey, ssl->buffers.key.length);
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) return ret;
|
||||||
sigSz = ecc_sig_size(&dsaKey) + 2; /* worst case estimate */
|
sigSz = ecc_sig_size(&dsaKey) + 4; /* worst case estimate */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
|
Reference in New Issue
Block a user