freebn(b2);
}
+static void sha512_mpint(SHA512_State * s, Bignum b)
+{
+ unsigned char lenbuf[4];
+ int len;
+ len = (bignum_bitcount(b) + 8) / 8;
+ PUT_32BIT(lenbuf, len);
+ SHA512_Bytes(s, lenbuf, 4);
+ while (len-- > 0) {
+ lenbuf[0] = bignum_byte(b, len);
+ SHA512_Bytes(s, lenbuf, 1);
+ }
+ memset(lenbuf, 0, sizeof(lenbuf));
+}
+
/*
* This function is a wrapper on modpow(). It has the same effect
* as modpow(), but employs RSA blinding to protect against timing
Bignum input_blinded, ret_blinded;
Bignum ret;
+ SHA512_State ss;
+ unsigned char digest512[64];
+ int digestused = lenof(digest512);
+ int hashseq = 0;
+
/*
* Start by inventing a random number chosen uniformly from the
* range 2..modulus-1. (We do this by preparing a random number
* There are timing implications to the potential retries, of
* course, but all they tell you is the modulus, which you
* already knew.)
+ *
+ * To preserve determinism and avoid Pageant needing to share
+ * the random number pool, we actually generate this `random'
+ * number by hashing stuff with the private key.
*/
while (1) {
int bits, byte, bitsleft, v;
byte = 0;
bitsleft = 0;
while (bits--) {
- if (bitsleft <= 0)
- bitsleft = 8, byte = random_byte();
+ if (bitsleft <= 0) {
+ bitsleft = 8;
+ /*
+ * Conceptually the following few lines are equivalent to
+ * byte = random_byte();
+ */
+ if (digestused >= lenof(digest512)) {
+ unsigned char seqbuf[4];
+ PUT_32BIT(seqbuf, hashseq);
+ SHA512_Init(&ss);
+ SHA512_Bytes(&ss, "RSA deterministic blinding", 26);
+ SHA512_Bytes(&ss, seqbuf, sizeof(seqbuf));
+ sha512_mpint(&ss, key->private_exponent);
+ SHA512_Final(&ss, digest512);
+ hashseq++;
+
+ /*
+ * Now hash that digest plus the signature
+ * input.
+ */
+ SHA512_Init(&ss);
+ SHA512_Bytes(&ss, digest512, sizeof(digest512));
+ sha512_mpint(&ss, input);
+ SHA512_Final(&ss, digest512);
+
+ digestused = 0;
+ }
+ byte = digest512[digestused++];
+ }
v = byte & 1;
byte >>= 1;
bitsleft--;
length = (ssh1_bignum_length(key->modulus) +
ssh1_bignum_length(key->exponent) + 4);
- ret = smalloc(length);
+ ret = snewn(length, unsigned char);
PUT_32BIT(ret, bignum_bitcount(key->modulus));
pos = 4;
int slen;
struct RSAKey *rsa;
- rsa = smalloc(sizeof(struct RSAKey));
+ rsa = snew(struct RSAKey);
if (!rsa)
return NULL;
getstring(&data, &len, &p, &slen);
int len;
len = rsastr_len(rsa);
- p = smalloc(len);
+ p = snewn(len, char);
rsastr_fmt(p, rsa);
return p;
}
* (three length fields, 12+7=19).
*/
bloblen = 19 + elen + mlen;
- blob = smalloc(bloblen);
+ blob = snewn(bloblen, unsigned char);
p = blob;
PUT_32BIT(p, 7);
p += 4;
* sum of lengths.
*/
bloblen = 16 + dlen + plen + qlen + ulen;
- blob = smalloc(bloblen);
+ blob = snewn(bloblen, unsigned char);
p = blob;
PUT_32BIT(p, dlen);
p += 4;
char **b = (char **) blob;
struct RSAKey *rsa;
- rsa = smalloc(sizeof(struct RSAKey));
+ rsa = snew(struct RSAKey);
if (!rsa)
return NULL;
rsa->comment = NULL;
for (i = 0; i < 16; i++)
sprintf(buffer + strlen(buffer), "%s%02x", i ? ":" : "",
digest[i]);
- ret = smalloc(strlen(buffer) + 1);
+ ret = snewn(strlen(buffer) + 1, char);
if (ret)
strcpy(ret, buffer);
return ret;
if (bignum_byte(out, i) != hash[j])
ret = 0;
}
+ freebn(out);
return ret;
}
SHA_Simple(data, datalen, hash);
nbytes = (bignum_bitcount(rsa->modulus) - 1) / 8;
- bytes = smalloc(nbytes);
+ bytes = snewn(nbytes, unsigned char);
bytes[0] = 1;
for (i = 1; i < nbytes - 20 - ASN1_LEN; i++)
freebn(in);
nbytes = (bignum_bitcount(out) + 7) / 8;
- bytes = smalloc(4 + 7 + 4 + nbytes);
+ bytes = snewn(4 + 7 + 4 + nbytes, unsigned char);
PUT_32BIT(bytes, 7);
memcpy(bytes + 4, "ssh-rsa", 7);
PUT_32BIT(bytes + 4 + 7, nbytes);