diff options
Diffstat (limited to 'src/util/crypto_random.c')
-rw-r--r-- | src/util/crypto_random.c | 199 |
1 files changed, 99 insertions, 100 deletions
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index 7fb2d1428..c74d60f4f 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c | |||
@@ -65,37 +65,37 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i) | |||
65 | GNUNET_assert (i > 0); | 65 | GNUNET_assert (i > 0); |
66 | 66 | ||
67 | switch (mode) | 67 | switch (mode) |
68 | { | 68 | { |
69 | case GNUNET_CRYPTO_QUALITY_STRONG: | 69 | case GNUNET_CRYPTO_QUALITY_STRONG: |
70 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ | 70 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ |
71 | #ifdef gcry_fast_random_poll | 71 | #ifdef gcry_fast_random_poll |
72 | if ((invokeCount++ % 256) == 0) | 72 | if ((invokeCount++ % 256) == 0) |
73 | gcry_fast_random_poll (); | 73 | gcry_fast_random_poll (); |
74 | #endif | 74 | #endif |
75 | ul = UINT32_MAX - (UINT32_MAX % i); | 75 | ul = UINT32_MAX - (UINT32_MAX % i); |
76 | do | 76 | do |
77 | { | 77 | { |
78 | gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t), | 78 | gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t), |
79 | GCRY_STRONG_RANDOM); | 79 | GCRY_STRONG_RANDOM); |
80 | } | 80 | } |
81 | while (ret >= ul); | 81 | while (ret >= ul); |
82 | return ret % i; | 82 | return ret % i; |
83 | case GNUNET_CRYPTO_QUALITY_NONCE: | 83 | case GNUNET_CRYPTO_QUALITY_NONCE: |
84 | ul = UINT32_MAX - (UINT32_MAX % i); | 84 | ul = UINT32_MAX - (UINT32_MAX % i); |
85 | do | 85 | do |
86 | { | 86 | { |
87 | gcry_create_nonce (&ret, sizeof (ret)); | 87 | gcry_create_nonce (&ret, sizeof (ret)); |
88 | } | ||
89 | while (ret >= ul); | ||
90 | return ret % i; | ||
91 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
92 | ret = i * weak_random (); | ||
93 | if (ret >= i) | ||
94 | ret = i - 1; | ||
95 | return ret; | ||
96 | default: | ||
97 | GNUNET_assert (0); | ||
98 | } | 88 | } |
89 | while (ret >= ul); | ||
90 | return ret % i; | ||
91 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
92 | ret = i * weak_random (); | ||
93 | if (ret >= i) | ||
94 | ret = i - 1; | ||
95 | return ret; | ||
96 | default: | ||
97 | GNUNET_assert (0); | ||
98 | } | ||
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | 101 | ||
@@ -121,12 +121,12 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n) | |||
121 | for (i = 0; i < n; i++) | 121 | for (i = 0; i < n; i++) |
122 | ret[i] = i; | 122 | ret[i] = i; |
123 | for (i = n - 1; i > 0; i--) | 123 | for (i = n - 1; i > 0; i--) |
124 | { | 124 | { |
125 | x = GNUNET_CRYPTO_random_u32 (mode, i + 1); | 125 | x = GNUNET_CRYPTO_random_u32 (mode, i + 1); |
126 | tmp = ret[x]; | 126 | tmp = ret[x]; |
127 | ret[x] = ret[i]; | 127 | ret[x] = ret[i]; |
128 | ret[i] = tmp; | 128 | ret[i] = tmp; |
129 | } | 129 | } |
130 | return ret; | 130 | return ret; |
131 | } | 131 | } |
132 | 132 | ||
@@ -146,33 +146,33 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) | |||
146 | 146 | ||
147 | GNUNET_assert (max > 0); | 147 | GNUNET_assert (max > 0); |
148 | switch (mode) | 148 | switch (mode) |
149 | { | ||
150 | case GNUNET_CRYPTO_QUALITY_STRONG: | ||
151 | ul = UINT64_MAX - (UINT64_MAX % max); | ||
152 | do | ||
149 | { | 153 | { |
150 | case GNUNET_CRYPTO_QUALITY_STRONG: | 154 | gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t), |
151 | ul = UINT64_MAX - (UINT64_MAX % max); | 155 | GCRY_STRONG_RANDOM); |
152 | do | ||
153 | { | ||
154 | gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t), | ||
155 | GCRY_STRONG_RANDOM); | ||
156 | } | ||
157 | while (ret >= ul); | ||
158 | return ret % max; | ||
159 | case GNUNET_CRYPTO_QUALITY_NONCE: | ||
160 | ul = UINT64_MAX - (UINT64_MAX % max); | ||
161 | do | ||
162 | { | ||
163 | gcry_create_nonce (&ret, sizeof (ret)); | ||
164 | } | ||
165 | while (ret >= ul); | ||
166 | |||
167 | return ret % max; | ||
168 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
169 | ret = max * weak_random (); | ||
170 | if (ret >= max) | ||
171 | ret = max - 1; | ||
172 | return ret; | ||
173 | default: | ||
174 | GNUNET_assert (0); | ||
175 | } | 156 | } |
157 | while (ret >= ul); | ||
158 | return ret % max; | ||
159 | case GNUNET_CRYPTO_QUALITY_NONCE: | ||
160 | ul = UINT64_MAX - (UINT64_MAX % max); | ||
161 | do | ||
162 | { | ||
163 | gcry_create_nonce (&ret, sizeof (ret)); | ||
164 | } | ||
165 | while (ret >= ul); | ||
166 | |||
167 | return ret % max; | ||
168 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
169 | ret = max * weak_random (); | ||
170 | if (ret >= max) | ||
171 | ret = max - 1; | ||
172 | return ret; | ||
173 | default: | ||
174 | GNUNET_assert (0); | ||
175 | } | ||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
178 | 178 | ||
@@ -200,7 +200,7 @@ static struct GNUNET_OS_Process *genproc; | |||
200 | */ | 200 | */ |
201 | static void | 201 | static void |
202 | entropy_generator (void *cls, const char *what, int printchar, int current, | 202 | entropy_generator (void *cls, const char *what, int printchar, int current, |
203 | int total) | 203 | int total) |
204 | { | 204 | { |
205 | unsigned long code; | 205 | unsigned long code; |
206 | enum GNUNET_OS_ProcessStatusType type; | 206 | enum GNUNET_OS_ProcessStatusType type; |
@@ -209,39 +209,39 @@ entropy_generator (void *cls, const char *what, int printchar, int current, | |||
209 | if (0 != strcmp (what, "need_entropy")) | 209 | if (0 != strcmp (what, "need_entropy")) |
210 | return; | 210 | return; |
211 | if (current == total) | 211 | if (current == total) |
212 | { | ||
213 | if (genproc != NULL) | ||
212 | { | 214 | { |
213 | if (genproc != NULL) | ||
214 | { | ||
215 | if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) | ||
216 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); | ||
217 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); | ||
218 | GNUNET_OS_process_close (genproc); | ||
219 | genproc = NULL; | ||
220 | } | ||
221 | return; | ||
222 | } | ||
223 | if (genproc != NULL) | ||
224 | { | ||
225 | ret = GNUNET_OS_process_status (genproc, &type, &code); | ||
226 | if (ret == GNUNET_NO) | ||
227 | return; /* still running */ | ||
228 | if (ret == GNUNET_SYSERR) | ||
229 | { | ||
230 | GNUNET_break (0); | ||
231 | return; | ||
232 | } | ||
233 | if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) | 215 | if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) |
234 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); | 216 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); |
235 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); | 217 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); |
236 | GNUNET_OS_process_close (genproc); | 218 | GNUNET_OS_process_close (genproc); |
237 | genproc = NULL; | 219 | genproc = NULL; |
238 | } | 220 | } |
239 | LOG (GNUNET_ERROR_TYPE_INFO, | 221 | return; |
240 | _("Starting `%s' process to generate entropy\n"), "find"); | 222 | } |
223 | if (genproc != NULL) | ||
224 | { | ||
225 | ret = GNUNET_OS_process_status (genproc, &type, &code); | ||
226 | if (ret == GNUNET_NO) | ||
227 | return; /* still running */ | ||
228 | if (ret == GNUNET_SYSERR) | ||
229 | { | ||
230 | GNUNET_break (0); | ||
231 | return; | ||
232 | } | ||
233 | if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) | ||
234 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); | ||
235 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); | ||
236 | GNUNET_OS_process_close (genproc); | ||
237 | genproc = NULL; | ||
238 | } | ||
239 | LOG (GNUNET_ERROR_TYPE_INFO, _("Starting `%s' process to generate entropy\n"), | ||
240 | "find"); | ||
241 | genproc = | 241 | genproc = |
242 | GNUNET_OS_start_process (NULL, NULL, "sh", "sh", "-c", | 242 | GNUNET_OS_start_process (NULL, NULL, "sh", "sh", "-c", |
243 | "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null", | 243 | "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null", |
244 | NULL); | 244 | NULL); |
245 | } | 245 | } |
246 | 246 | ||
247 | 247 | ||
@@ -249,11 +249,11 @@ static void | |||
249 | killfind () | 249 | killfind () |
250 | { | 250 | { |
251 | if (genproc != NULL) | 251 | if (genproc != NULL) |
252 | { | 252 | { |
253 | GNUNET_OS_process_kill (genproc, SIGKILL); | 253 | GNUNET_OS_process_kill (genproc, SIGKILL); |
254 | GNUNET_OS_process_close (genproc); | 254 | GNUNET_OS_process_close (genproc); |
255 | genproc = NULL; | 255 | genproc = NULL; |
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | 259 | ||
@@ -261,21 +261,20 @@ void __attribute__ ((constructor)) GNUNET_CRYPTO_random_init () | |||
261 | { | 261 | { |
262 | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); | 262 | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); |
263 | if (!gcry_check_version (GCRYPT_VERSION)) | 263 | if (!gcry_check_version (GCRYPT_VERSION)) |
264 | { | 264 | { |
265 | fprintf (stderr, | 265 | fprintf (stderr, |
266 | _ | 266 | _ |
267 | ("libgcrypt has not the expected version (version %s is required).\n"), | 267 | ("libgcrypt has not the expected version (version %s is required).\n"), |
268 | GCRYPT_VERSION); | 268 | GCRYPT_VERSION); |
269 | abort (); | 269 | abort (); |
270 | } | 270 | } |
271 | #ifdef gcry_fast_random_poll | 271 | #ifdef gcry_fast_random_poll |
272 | gcry_fast_random_poll (); | 272 | gcry_fast_random_poll (); |
273 | #endif | 273 | #endif |
274 | gcry_set_progress_handler (&entropy_generator, NULL); | 274 | gcry_set_progress_handler (&entropy_generator, NULL); |
275 | atexit (&killfind); | 275 | atexit (&killfind); |
276 | SRANDOM (time (NULL) ^ | 276 | SRANDOM (time (NULL) ^ |
277 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | 277 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); |
278 | UINT32_MAX)); | ||
279 | } | 278 | } |
280 | 279 | ||
281 | 280 | ||