mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-16 02:27:32 -05:00
Replace PuTTY's PRNG with a Fortuna-like system.
This tears out the entire previous random-pool system in sshrand.c. In its place is a system pretty close to Ferguson and Schneier's 'Fortuna' generator, with the main difference being that I use SHA-256 instead of AES for the generation side of the system (rationale given in comment). The PRNG implementation lives in sshprng.c, and defines a self- contained data type with no state stored outside the object, so you can instantiate however many of them you like. The old sshrand.c still exists, but in place of the previous random pool system, it's just become a client of sshprng.c, whose job is to hold a single global instance of the PRNG type, and manage its reference count, save file, noise-collection timers and similar administrative business. Advantages of this change include: - Fortuna is designed with a more varied threat model in mind than my old home-grown random pool. For example, after any request for random numbers, it automatically re-seeds itself, so that if the state of the PRNG should be leaked, it won't give enough information to find out what past outputs _were_. - The PRNG type can be instantiated with any hash function; the instance used by the main tools is based on SHA-256, an improvement on the old pool's use of SHA-1. - The new PRNG only uses the completely standard interface to the hash function API, instead of having to have privileged access to the internal SHA-1 block transform function. This will make it easier to revamp the hash code in general, and also it means that hardware-accelerated versions of SHA-256 will automatically be used for the PRNG as well as for everything else. - The new PRNG can be _tested_! Because it has an actual (if not quite explicit) specification for exactly what the output numbers _ought_ to be derived from the hashes of, I can (and have) put tests in cryptsuite that ensure the output really is being derived in the way I think it is. The old pool could have been returning any old nonsense and it would have been very hard to tell for sure.
This commit is contained in:
32
ssh.h
32
ssh.h
@ -867,8 +867,6 @@ extern const char sshver[];
|
||||
*/
|
||||
extern bool ssh_fallback_cmd(Backend *backend);
|
||||
|
||||
void SHATransform(uint32_t *digest, uint32_t *data);
|
||||
|
||||
/*
|
||||
* Check of compiler version
|
||||
*/
|
||||
@ -892,9 +890,35 @@ void SHATransform(uint32_t *digest, uint32_t *data);
|
||||
# undef COMPILER_SUPPORTS_SHA_NI
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The PRNG type, defined in sshprng.c. Visible data fields are
|
||||
* 'savesize', which suggests how many random bytes you should request
|
||||
* from a particular PRNG instance to write to putty.rnd, and a
|
||||
* BinarySink implementation which you can use to write seed data in
|
||||
* between calling prng_seed_{begin,finish}.
|
||||
*/
|
||||
struct prng {
|
||||
size_t savesize;
|
||||
BinarySink_IMPLEMENTATION;
|
||||
/* (also there's a surrounding implementation struct in sshprng.c) */
|
||||
};
|
||||
prng *prng_new(const ssh_hashalg *hashalg);
|
||||
void prng_free(prng *p);
|
||||
void prng_seed_begin(prng *p);
|
||||
void prng_seed_finish(prng *p);
|
||||
void prng_read(prng *p, void *vout, size_t size);
|
||||
void prng_add_entropy(prng *p, unsigned source_id, ptrlen data);
|
||||
|
||||
/* This function must be implemented by the platform, and returns a
|
||||
* timer in milliseconds that the PRNG can use to know whether it's
|
||||
* been reseeded too recently to do it again.
|
||||
*
|
||||
* The PRNG system has its own special timing function not because its
|
||||
* timing needs are unusual in the real applications, but simply so
|
||||
* that testcrypt can mock it to keep the tests deterministic. */
|
||||
uint64_t prng_reseed_time_ms(void);
|
||||
|
||||
void random_read(void *out, size_t size);
|
||||
void random_add_noise(void *noise, int length);
|
||||
void random_add_heavynoise(void *noise, int length);
|
||||
|
||||
/* Exports from x11fwd.c */
|
||||
enum {
|
||||
|
Reference in New Issue
Block a user