Added stricter rule on input for RSA private key operation (mathematically correct but out-of-range values are now rejected).
This commit is contained in:
parent
932fb89081
commit
f81a282878
5 changed files with 652 additions and 64 deletions
|
|
@ -27,24 +27,6 @@
|
|||
#define U (2 + ((BR_MAX_RSA_FACTOR + 14) / 15))
|
||||
#define TLEN (8 * U)
|
||||
|
||||
/* obsolete
|
||||
static void
|
||||
print_int(const char *name, const uint16_t *x)
|
||||
{
|
||||
extern int printf(const char *fmt, ...);
|
||||
unsigned char tmp[1000];
|
||||
size_t u, len;
|
||||
|
||||
len = (x[0] - (x[0] >> 4) + 7) >> 3;
|
||||
br_i15_encode(tmp, len, x);
|
||||
printf("%s = ", name);
|
||||
for (u = 0; u < len; u ++) {
|
||||
printf("%02X", tmp[u]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
/* see bearssl_rsa.h */
|
||||
uint32_t
|
||||
br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
||||
|
|
@ -53,7 +35,7 @@ br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
size_t plen, qlen;
|
||||
size_t fwlen;
|
||||
uint16_t p0i, q0i;
|
||||
size_t xlen;
|
||||
size_t xlen, u;
|
||||
uint16_t tmp[1 + TLEN];
|
||||
long z;
|
||||
uint16_t *mp, *mq, *s1, *s2, *t1, *t2, *t3;
|
||||
|
|
@ -116,20 +98,57 @@ br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
*/
|
||||
br_i15_decode(mq, q, qlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
t1 = mq + fwlen;
|
||||
br_i15_decode(t1, p, plen);
|
||||
|
||||
/*
|
||||
* Compute the modulus (product of the two factors), to compare
|
||||
* it with the source value. We use br_i15_mulacc(), since it's
|
||||
* already used later on.
|
||||
*/
|
||||
t2 = mq + 2 * fwlen;
|
||||
br_i15_zero(t2, mq[0]);
|
||||
br_i15_mulacc(t2, mq, t1);
|
||||
|
||||
/*
|
||||
* We encode the modulus into bytes, to perform the comparison
|
||||
* with bytes. We know that the product length, in bytes, is
|
||||
* exactly xlen.
|
||||
* The comparison actually computes the carry when subtracting
|
||||
* the modulus from the source value; that carry must be 1 for
|
||||
* a value in the correct range. We keep it in r, which is our
|
||||
* accumulator for the error code.
|
||||
*/
|
||||
t3 = mq + 4 * fwlen;
|
||||
br_i15_encode(t3, xlen, t2);
|
||||
u = xlen;
|
||||
r = 0;
|
||||
while (u > 0) {
|
||||
uint32_t wn, wx;
|
||||
|
||||
u --;
|
||||
wn = ((unsigned char *)t3)[u];
|
||||
wx = x[u];
|
||||
r = ((wx - (wn + r)) >> 8) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the decoded p to another temporary buffer.
|
||||
*/
|
||||
mp = mq + 2 * fwlen;
|
||||
memmove(mp, t1, fwlen * sizeof *t1);
|
||||
|
||||
/*
|
||||
* Compute s2 = x^dq mod q.
|
||||
*/
|
||||
q0i = br_i15_ninv15(mq[1]);
|
||||
s2 = mq + fwlen;
|
||||
br_i15_decode_reduce(s2, x, xlen, mq);
|
||||
r = br_i15_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
mq + 2 * fwlen, TLEN - 2 * fwlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
mp = mq + 2 * fwlen;
|
||||
br_i15_decode(mp, p, plen);
|
||||
r &= br_i15_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
mq + 3 * fwlen, TLEN - 3 * fwlen);
|
||||
|
||||
/*
|
||||
* Compute s1 = x^dq mod q.
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ br_rsa_i31_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
size_t plen, qlen;
|
||||
size_t fwlen;
|
||||
uint32_t p0i, q0i;
|
||||
size_t xlen;
|
||||
size_t xlen, u;
|
||||
uint32_t tmp[1 + TLEN];
|
||||
long z;
|
||||
uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3;
|
||||
|
|
@ -82,7 +82,7 @@ br_rsa_i31_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
}
|
||||
|
||||
/*
|
||||
* Compute signature length (in bytes).
|
||||
* Compute modulus length (in bytes).
|
||||
*/
|
||||
xlen = (sk->n_bitlen + 7) >> 3;
|
||||
|
||||
|
|
@ -92,20 +92,57 @@ br_rsa_i31_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
mq = tmp;
|
||||
br_i31_decode(mq, q, qlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
t1 = mq + fwlen;
|
||||
br_i31_decode(t1, p, plen);
|
||||
|
||||
/*
|
||||
* Compute the modulus (product of the two factors), to compare
|
||||
* it with the source value. We use br_i31_mulacc(), since it's
|
||||
* already used later on.
|
||||
*/
|
||||
t2 = mq + 2 * fwlen;
|
||||
br_i31_zero(t2, mq[0]);
|
||||
br_i31_mulacc(t2, mq, t1);
|
||||
|
||||
/*
|
||||
* We encode the modulus into bytes, to perform the comparison
|
||||
* with bytes. We know that the product length, in bytes, is
|
||||
* exactly xlen.
|
||||
* The comparison actually computes the carry when subtracting
|
||||
* the modulus from the source value; that carry must be 1 for
|
||||
* a value in the correct range. We keep it in r, which is our
|
||||
* accumulator for the error code.
|
||||
*/
|
||||
t3 = mq + 4 * fwlen;
|
||||
br_i31_encode(t3, xlen, t2);
|
||||
u = xlen;
|
||||
r = 0;
|
||||
while (u > 0) {
|
||||
uint32_t wn, wx;
|
||||
|
||||
u --;
|
||||
wn = ((unsigned char *)t3)[u];
|
||||
wx = x[u];
|
||||
r = ((wx - (wn + r)) >> 8) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the decoded p to another temporary buffer.
|
||||
*/
|
||||
mp = mq + 2 * fwlen;
|
||||
memmove(mp, t1, fwlen * sizeof *t1);
|
||||
|
||||
/*
|
||||
* Compute s2 = x^dq mod q.
|
||||
*/
|
||||
q0i = br_i31_ninv31(mq[1]);
|
||||
s2 = mq + fwlen;
|
||||
br_i31_decode_reduce(s2, x, xlen, mq);
|
||||
r = br_i31_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
mq + 2 * fwlen, TLEN - 2 * fwlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
mp = mq + 2 * fwlen;
|
||||
br_i31_decode(mp, p, plen);
|
||||
r &= br_i31_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
mq + 3 * fwlen, TLEN - 3 * fwlen);
|
||||
|
||||
/*
|
||||
* Compute s1 = x^dp mod p.
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ br_rsa_i32_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
uint32_t tmp[6 * U];
|
||||
uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3;
|
||||
uint32_t p0i, q0i;
|
||||
size_t xlen;
|
||||
size_t xlen, u;
|
||||
uint32_t r;
|
||||
|
||||
/*
|
||||
* All our temporary buffers are from the tmp[] array.
|
||||
|
|
@ -82,16 +83,22 @@ br_rsa_i32_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
br_i32_decode(mq, q, qlen);
|
||||
|
||||
/*
|
||||
* obsolete -- we do not compute the length of n, it is now
|
||||
* an input parameter.
|
||||
br_i32_zero(t3, mp[0]);
|
||||
br_i32_mulacc(t3, mp, mq);
|
||||
n_bitlen = br_i32_bit_length(t3 + 1, (t3[0] + 31) >> 5);
|
||||
if (xlen != ((n_bitlen + 7) >> 3)) {
|
||||
return 0;
|
||||
}
|
||||
* Recompute modulus, to compare with the source value.
|
||||
*/
|
||||
br_i32_zero(t2, mp[0]);
|
||||
br_i32_mulacc(t2, mp, mq);
|
||||
xlen = (sk->n_bitlen + 7) >> 3;
|
||||
br_i32_encode(t2 + 2 * U, xlen, t2);
|
||||
u = xlen;
|
||||
r = 0;
|
||||
while (u > 0) {
|
||||
uint32_t wn, wx;
|
||||
|
||||
u --;
|
||||
wn = ((unsigned char *)(t2 + 2 * U))[u];
|
||||
wx = x[u];
|
||||
r = ((wx - (wn + r)) >> 8) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute s1 = x^dp mod p.
|
||||
|
|
@ -149,5 +156,5 @@ br_rsa_i32_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
* The only error conditions remaining at that point are invalid
|
||||
* values for p and q (even integers).
|
||||
*/
|
||||
return p0i & q0i & 1;
|
||||
return p0i & q0i & r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ br_rsa_i62_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
size_t plen, qlen;
|
||||
size_t fwlen;
|
||||
uint32_t p0i, q0i;
|
||||
size_t xlen;
|
||||
size_t xlen, u;
|
||||
uint64_t tmp[TLEN];
|
||||
long z;
|
||||
uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3;
|
||||
|
|
@ -94,20 +94,57 @@ br_rsa_i62_private(unsigned char *x, const br_rsa_private_key *sk)
|
|||
mq = (uint32_t *)tmp;
|
||||
br_i31_decode(mq, q, qlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
t1 = (uint32_t *)(tmp + fwlen);
|
||||
br_i31_decode(t1, p, plen);
|
||||
|
||||
/*
|
||||
* Compute the modulus (product of the two factors), to compare
|
||||
* it with the source value. We use br_i31_mulacc(), since it's
|
||||
* already used later on.
|
||||
*/
|
||||
t2 = (uint32_t *)(tmp + 2 * fwlen);
|
||||
br_i31_zero(t2, mq[0]);
|
||||
br_i31_mulacc(t2, mq, t1);
|
||||
|
||||
/*
|
||||
* We encode the modulus into bytes, to perform the comparison
|
||||
* with bytes. We know that the product length, in bytes, is
|
||||
* exactly xlen.
|
||||
* The comparison actually computes the carry when subtracting
|
||||
* the modulus from the source value; that carry must be 1 for
|
||||
* a value in the correct range. We keep it in r, which is our
|
||||
* accumulator for the error code.
|
||||
*/
|
||||
t3 = (uint32_t *)(tmp + 4 * fwlen);
|
||||
br_i31_encode(t3, xlen, t2);
|
||||
u = xlen;
|
||||
r = 0;
|
||||
while (u > 0) {
|
||||
uint32_t wn, wx;
|
||||
|
||||
u --;
|
||||
wn = ((unsigned char *)t3)[u];
|
||||
wx = x[u];
|
||||
r = ((wx - (wn + r)) >> 8) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the decoded p to another temporary buffer.
|
||||
*/
|
||||
mp = (uint32_t *)(tmp + 2 * fwlen);
|
||||
memmove(mp, t1, 2 * fwlen * sizeof *t1);
|
||||
|
||||
/*
|
||||
* Compute s2 = x^dq mod q.
|
||||
*/
|
||||
q0i = br_i31_ninv31(mq[1]);
|
||||
s2 = (uint32_t *)(tmp + fwlen);
|
||||
br_i31_decode_reduce(s2, x, xlen, mq);
|
||||
r = br_i62_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
tmp + 2 * fwlen, TLEN - 2 * fwlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
mp = (uint32_t *)(tmp + 2 * fwlen);
|
||||
br_i31_decode(mp, p, plen);
|
||||
r &= br_i62_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
tmp + 3 * fwlen, TLEN - 3 * fwlen);
|
||||
|
||||
/*
|
||||
* Compute s1 = x^dp mod p.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue