Sync show log naming and behavior of FileDiffDlg, RepoBrowser, and GitStatusListCtrl...
[TortoiseGit.git] / src / TortoisePlink / SSHRAND.C
blobe53b4aa5cda212fb9b0dd325d772308832948b1b
1 /*\r
2  * sshrand.c: manage the global live PRNG instance.\r
3  */\r
4 \r
5 #include "putty.h"\r
6 #include "ssh.h"\r
7 #include "storage.h"\r
8 #include <assert.h>\r
9 \r
10 /* Collect environmental noise every 5 minutes */\r
11 #define NOISE_REGULAR_INTERVAL (5*60*TICKSPERSEC)\r
13 int random_active = 0;\r
15 #ifdef FUZZING\r
17 /*\r
18  * Special dummy version of the RNG for use when fuzzing.\r
19  */\r
20 void random_add_noise(NoiseSourceId source, const void *noise, int length) { }\r
21 void random_ref(void) { }\r
22 void random_setup_custom(const ssh_hashalg *hash) { }\r
23 void random_unref(void) { }\r
24 void random_read(void *out, size_t size)\r
25 {\r
26     memset(out, 0x45, size); /* Chosen by eight fair coin tosses */\r
27 }\r
28 void random_get_savedata(void **data, int *len) { }\r
30 #else /* !FUZZING */\r
32 /* Dummy structure for the sake of having something to expire_timer_context */\r
33 static struct random_timer_context { int dummy; } random_timer_ctx;\r
35 static prng *global_prng;\r
36 static unsigned long next_noise_collection;\r
38 void random_add_noise(NoiseSourceId source, const void *noise, int length)\r
39 {\r
40     if (!random_active)\r
41         return;\r
43     prng_add_entropy(global_prng, source, make_ptrlen(noise, length));\r
44 }\r
46 static void random_timer(void *ctx, unsigned long now)\r
47 {\r
48     if (random_active > 0 && now == next_noise_collection) {\r
49         noise_regular();\r
50         next_noise_collection =\r
51             schedule_timer(NOISE_REGULAR_INTERVAL, random_timer,\r
52                            &random_timer_ctx);\r
53     }\r
54 }\r
56 static void random_seed_callback(void *noise, int length)\r
57 {\r
58     put_data(global_prng, noise, length);\r
59 }\r
61 static void random_create(const ssh_hashalg *hashalg)\r
62 {\r
63     assert(!global_prng);\r
64     global_prng = prng_new(hashalg);\r
66     prng_seed_begin(global_prng);\r
67     noise_get_heavy(random_seed_callback);\r
68     prng_seed_finish(global_prng);\r
70     next_noise_collection =\r
71         schedule_timer(NOISE_REGULAR_INTERVAL, random_timer,\r
72                        &random_timer_ctx);\r
74     /* noise_get_heavy probably read our random seed file.\r
75      * Therefore (in fact, even if it didn't), we should write a\r
76      * fresh one, in case another instance of ourself starts up\r
77      * before we finish, and also in case an attacker gets hold of\r
78      * the seed data we used. */\r
79     random_save_seed();\r
80 }\r
82 void random_save_seed(void)\r
83 {\r
84     int len;\r
85     void *data;\r
87     if (random_active) {\r
88         random_get_savedata(&data, &len);\r
89         write_random_seed(data, len);\r
90         sfree(data);\r
91     }\r
92 }\r
94 void random_ref(void)\r
95 {\r
96     if (!random_active++)\r
97         random_create(&ssh_sha256);\r
98 }\r
100 void random_setup_custom(const ssh_hashalg *hash)\r
102     random_active++;\r
103     random_create(hash);\r
106 void random_reseed(ptrlen seed)\r
108     prng_seed_begin(global_prng);\r
109     put_datapl(global_prng, seed);\r
110     prng_seed_finish(global_prng);\r
113 void random_clear(void)\r
115     if (global_prng) {\r
116         random_save_seed();\r
117         expire_timer_context(&random_timer_ctx);\r
118         prng_free(global_prng);\r
119         global_prng = NULL;\r
120         random_active = 0;\r
121     }\r
124 void random_unref(void)\r
126     assert(random_active > 0);\r
127     if (--random_active == 0)\r
128         random_clear();\r
131 void random_read(void *buf, size_t size)\r
133     assert(random_active > 0);\r
134     prng_read(global_prng, buf, size);\r
137 void random_get_savedata(void **data, int *len)\r
139     void *buf = snewn(global_prng->savesize, char);\r
140     random_read(buf, global_prng->savesize);\r
141     *len = global_prng->savesize;\r
142     *data = buf;\r
145 size_t random_seed_bits(void)\r
147     assert(random_active > 0);\r
148     return prng_seed_bits(global_prng);\r
151 #endif /* FUZZING */\r