mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-19 03:58: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:
parent
1f5780ad9f
commit
dca1486602
2
Recipe
2
Recipe
@ -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
|
||||||
|
23
pageant.c
23
pageant.c
@ -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.
|
||||||
*/
|
*/
|
||||||
|
54
sshrsa.c
54
sshrsa.c
@ -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--;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user