1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-19 12:08:05 -05:00

Take the random number generator back out of Pageant: the `random'

numbers needed for RSA blinding are now done deterministically by
hashes of the private key, much the same way we do it for DSA.

[originally from svn r3149]
This commit is contained in:
Simon Tatham 2003-04-27 09:45:35 +00:00
parent 1f5780ad9f
commit dca1486602
3 changed files with 71 additions and 8 deletions

2
Recipe
View File

@ -146,7 +146,7 @@ psftp : [C] psftp console WINSSH be_none SFTP WINMISC scp.res LIBS1
pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234 pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234
+ misc sshaes sshsha pageantc sshdss sshsh512 winutils winmisc + misc sshaes sshsha pageantc sshdss sshsh512 winutils winmisc
+ sshrand noise winstore pageant.res LIBS + pageant.res LIBS
puttygen : [G] puttygen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version puttygen : [G] puttygen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
+ sshrand noise sshsha winstore misc winctrls sshrsa sshdss winmisc + sshrand noise sshsha winstore misc winctrls sshrsa sshdss winmisc

View File

@ -127,6 +127,24 @@ static void *make_keylist2(int *length);
static void *get_keylist1(void); static void *get_keylist1(void);
static void *get_keylist2(void); static void *get_keylist2(void);
/*
* We need this to link with the RSA code, because rsaencrypt()
* pads its data with random bytes. Since we only use rsadecrypt()
* and the signing functions, which are deterministic, this should
* never be called.
*
* If it _is_ called, there is a _serious_ problem, because it
* won't generate true random numbers. So we must scream, panic,
* and exit immediately if that should happen.
*/
int random_byte(void)
{
MessageBox(main_hwnd, "Internal Error", APPNAME, MB_OK | MB_ICONERROR);
exit(0);
/* this line can't be reached but it placates MSVC's warnings :-) */
return 0;
}
/* /*
* Blob structure for passing to the asymmetric SSH2 key compare * Blob structure for passing to the asymmetric SSH2 key compare
* function, prototyped here. * function, prototyped here.
@ -1929,11 +1947,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
} }
/*
* Initialise the random number generator.
*/
random_init();
/* /*
* Initialise storage for short-term passphrase cache. * Initialise storage for short-term passphrase cache.
*/ */

View File

@ -89,6 +89,20 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
freebn(b2); 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 * This function is a wrapper on modpow(). It has the same effect
* as modpow(), but employs RSA blinding to protect against timing * as modpow(), but employs RSA blinding to protect against timing
@ -100,6 +114,11 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
Bignum input_blinded, ret_blinded; Bignum input_blinded, ret_blinded;
Bignum ret; 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 * Start by inventing a random number chosen uniformly from the
* range 2..modulus-1. (We do this by preparing a random number * range 2..modulus-1. (We do this by preparing a random number
@ -110,6 +129,10 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
* There are timing implications to the potential retries, of * There are timing implications to the potential retries, of
* course, but all they tell you is the modulus, which you * course, but all they tell you is the modulus, which you
* already knew.) * 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) { while (1) {
int bits, byte, bitsleft, v; int bits, byte, bitsleft, v;
@ -123,8 +146,35 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
byte = 0; byte = 0;
bitsleft = 0; bitsleft = 0;
while (bits--) { while (bits--) {
if (bitsleft <= 0) if (bitsleft <= 0) {
bitsleft = 8, byte = random_byte(); 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; v = byte & 1;
byte >>= 1; byte >>= 1;
bitsleft--; bitsleft--;