diff options
Diffstat (limited to 'src/util/crypto_random.c')
-rw-r--r-- | src/util/crypto_random.c | 284 |
1 files changed, 142 insertions, 142 deletions
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index d16ba2412..f70763757 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c | |||
@@ -28,23 +28,23 @@ | |||
28 | #include "gnunet_crypto_lib.h" | 28 | #include "gnunet_crypto_lib.h" |
29 | #include <gcrypt.h> | 29 | #include <gcrypt.h> |
30 | 30 | ||
31 | #define LOG(kind, ...) GNUNET_log_from(kind, "util-crypto-random", __VA_ARGS__) | 31 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-random", __VA_ARGS__) |
32 | 32 | ||
33 | #define LOG_STRERROR(kind, syscall) \ | 33 | #define LOG_STRERROR(kind, syscall) \ |
34 | GNUNET_log_from_strerror(kind, "util-crypto-random", syscall) | 34 | GNUNET_log_from_strerror (kind, "util-crypto-random", syscall) |
35 | 35 | ||
36 | 36 | ||
37 | /* TODO: ndurner, move this to plibc? */ | 37 | /* TODO: ndurner, move this to plibc? */ |
38 | /* The code is derived from glibc, obviously */ | 38 | /* The code is derived from glibc, obviously */ |
39 | #if !HAVE_RANDOM || !HAVE_SRANDOM | 39 | #if ! HAVE_RANDOM || ! HAVE_SRANDOM |
40 | #ifdef RANDOM | 40 | #ifdef RANDOM |
41 | #undef RANDOM | 41 | #undef RANDOM |
42 | #endif | 42 | #endif |
43 | #ifdef SRANDOM | 43 | #ifdef SRANDOM |
44 | #undef SRANDOM | 44 | #undef SRANDOM |
45 | #endif | 45 | #endif |
46 | #define RANDOM() glibc_weak_rand32() | 46 | #define RANDOM() glibc_weak_rand32 () |
47 | #define SRANDOM(s) glibc_weak_srand32(s) | 47 | #define SRANDOM(s) glibc_weak_srand32 (s) |
48 | #if defined(RAND_MAX) | 48 | #if defined(RAND_MAX) |
49 | #undef RAND_MAX | 49 | #undef RAND_MAX |
50 | #endif | 50 | #endif |
@@ -55,14 +55,14 @@ static int32_t glibc_weak_rand32_state = 1; | |||
55 | 55 | ||
56 | 56 | ||
57 | void | 57 | void |
58 | glibc_weak_srand32(int32_t s) | 58 | glibc_weak_srand32 (int32_t s) |
59 | { | 59 | { |
60 | glibc_weak_rand32_state = s; | 60 | glibc_weak_rand32_state = s; |
61 | } | 61 | } |
62 | 62 | ||
63 | 63 | ||
64 | int32_t | 64 | int32_t |
65 | glibc_weak_rand32() | 65 | glibc_weak_rand32 () |
66 | { | 66 | { |
67 | int32_t val = glibc_weak_rand32_state; | 67 | int32_t val = glibc_weak_rand32_state; |
68 | 68 | ||
@@ -78,9 +78,9 @@ glibc_weak_rand32() | |||
78 | * @return number between 0 and 1. | 78 | * @return number between 0 and 1. |
79 | */ | 79 | */ |
80 | static double | 80 | static double |
81 | get_weak_random() | 81 | get_weak_random () |
82 | { | 82 | { |
83 | return((double)random() / RAND_MAX); | 83 | return((double) random () / RAND_MAX); |
84 | } | 84 | } |
85 | 85 | ||
86 | 86 | ||
@@ -91,9 +91,9 @@ get_weak_random() | |||
91 | * @param seed the seed to use | 91 | * @param seed the seed to use |
92 | */ | 92 | */ |
93 | void | 93 | void |
94 | GNUNET_CRYPTO_seed_weak_random(int32_t seed) | 94 | GNUNET_CRYPTO_seed_weak_random (int32_t seed) |
95 | { | 95 | { |
96 | srandom(seed); | 96 | srandom (seed); |
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
@@ -106,12 +106,12 @@ GNUNET_CRYPTO_seed_weak_random(int32_t seed) | |||
106 | * @param length buffer length | 106 | * @param length buffer length |
107 | */ | 107 | */ |
108 | void | 108 | void |
109 | GNUNET_CRYPTO_zero_keys(void *buffer, size_t length) | 109 | GNUNET_CRYPTO_zero_keys (void *buffer, size_t length) |
110 | { | 110 | { |
111 | #if HAVE_MEMSET_S | 111 | #if HAVE_MEMSET_S |
112 | memset_s(buffer, length, 0, length); | 112 | memset_s (buffer, length, 0, length); |
113 | #elif HAVE_EXPLICIT_BZERO | 113 | #elif HAVE_EXPLICIT_BZERO |
114 | explicit_bzero(buffer, length); | 114 | explicit_bzero (buffer, length); |
115 | #else | 115 | #else |
116 | volatile unsigned char *p = buffer; | 116 | volatile unsigned char *p = buffer; |
117 | while (length--) | 117 | while (length--) |
@@ -129,40 +129,40 @@ GNUNET_CRYPTO_zero_keys(void *buffer, size_t length) | |||
129 | * @param length buffer length | 129 | * @param length buffer length |
130 | */ | 130 | */ |
131 | void | 131 | void |
132 | GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, | 132 | GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, |
133 | void *buffer, | 133 | void *buffer, |
134 | size_t length) | 134 | size_t length) |
135 | { | 135 | { |
136 | #ifdef gcry_fast_random_poll | 136 | #ifdef gcry_fast_random_poll |
137 | static unsigned int invokeCount; | 137 | static unsigned int invokeCount; |
138 | #endif | 138 | #endif |
139 | switch (mode) | 139 | switch (mode) |
140 | { | 140 | { |
141 | case GNUNET_CRYPTO_QUALITY_STRONG: | 141 | case GNUNET_CRYPTO_QUALITY_STRONG: |
142 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ | 142 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ |
143 | #ifdef gcry_fast_random_poll | 143 | #ifdef gcry_fast_random_poll |
144 | if ((invokeCount++ % 256) == 0) | 144 | if ((invokeCount++ % 256) == 0) |
145 | gcry_fast_random_poll(); | 145 | gcry_fast_random_poll (); |
146 | #endif | 146 | #endif |
147 | gcry_randomize(buffer, length, GCRY_STRONG_RANDOM); | 147 | gcry_randomize (buffer, length, GCRY_STRONG_RANDOM); |
148 | return; | 148 | return; |
149 | 149 | ||
150 | case GNUNET_CRYPTO_QUALITY_NONCE: | 150 | case GNUNET_CRYPTO_QUALITY_NONCE: |
151 | gcry_create_nonce(buffer, length); | 151 | gcry_create_nonce (buffer, length); |
152 | return; | 152 | return; |
153 | 153 | ||
154 | case GNUNET_CRYPTO_QUALITY_WEAK: | 154 | case GNUNET_CRYPTO_QUALITY_WEAK: |
155 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ | 155 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ |
156 | #ifdef gcry_fast_random_poll | 156 | #ifdef gcry_fast_random_poll |
157 | if ((invokeCount++ % 256) == 0) | 157 | if ((invokeCount++ % 256) == 0) |
158 | gcry_fast_random_poll(); | 158 | gcry_fast_random_poll (); |
159 | #endif | 159 | #endif |
160 | gcry_randomize(buffer, length, GCRY_WEAK_RANDOM); | 160 | gcry_randomize (buffer, length, GCRY_WEAK_RANDOM); |
161 | return; | 161 | return; |
162 | 162 | ||
163 | default: | 163 | default: |
164 | GNUNET_assert(0); | 164 | GNUNET_assert (0); |
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | ||
168 | 168 | ||
@@ -174,7 +174,7 @@ GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, | |||
174 | * @return a random value in the interval [0,i[. | 174 | * @return a random value in the interval [0,i[. |
175 | */ | 175 | */ |
176 | uint32_t | 176 | uint32_t |
177 | GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i) | 177 | GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i) |
178 | { | 178 | { |
179 | #ifdef gcry_fast_random_poll | 179 | #ifdef gcry_fast_random_poll |
180 | static unsigned int invokeCount; | 180 | static unsigned int invokeCount; |
@@ -182,44 +182,44 @@ GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i) | |||
182 | uint32_t ret; | 182 | uint32_t ret; |
183 | uint32_t ul; | 183 | uint32_t ul; |
184 | 184 | ||
185 | GNUNET_assert(i > 0); | 185 | GNUNET_assert (i > 0); |
186 | 186 | ||
187 | switch (mode) | 187 | switch (mode) |
188 | { | 188 | { |
189 | case GNUNET_CRYPTO_QUALITY_STRONG: | 189 | case GNUNET_CRYPTO_QUALITY_STRONG: |
190 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ | 190 | /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ |
191 | #ifdef gcry_fast_random_poll | 191 | #ifdef gcry_fast_random_poll |
192 | if ((invokeCount++ % 256) == 0) | 192 | if ((invokeCount++ % 256) == 0) |
193 | gcry_fast_random_poll(); | 193 | gcry_fast_random_poll (); |
194 | #endif | 194 | #endif |
195 | ul = UINT32_MAX - (UINT32_MAX % i); | 195 | ul = UINT32_MAX - (UINT32_MAX % i); |
196 | do | 196 | do |
197 | { | 197 | { |
198 | gcry_randomize((unsigned char *)&ret, | 198 | gcry_randomize ((unsigned char *) &ret, |
199 | sizeof(uint32_t), | 199 | sizeof(uint32_t), |
200 | GCRY_STRONG_RANDOM); | 200 | GCRY_STRONG_RANDOM); |
201 | } | ||
202 | while (ret >= ul); | ||
203 | return ret % i; | ||
204 | |||
205 | case GNUNET_CRYPTO_QUALITY_NONCE: | ||
206 | ul = UINT32_MAX - (UINT32_MAX % i); | ||
207 | do | ||
208 | { | ||
209 | gcry_create_nonce(&ret, sizeof(ret)); | ||
210 | } | ||
211 | while (ret >= ul); | ||
212 | return ret % i; | ||
213 | |||
214 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
215 | ret = i * get_weak_random(); | ||
216 | if (ret >= i) | ||
217 | ret = i - 1; | ||
218 | return ret; | ||
219 | |||
220 | default: | ||
221 | GNUNET_assert(0); | ||
222 | } | 201 | } |
202 | while (ret >= ul); | ||
203 | return ret % i; | ||
204 | |||
205 | case GNUNET_CRYPTO_QUALITY_NONCE: | ||
206 | ul = UINT32_MAX - (UINT32_MAX % i); | ||
207 | do | ||
208 | { | ||
209 | gcry_create_nonce (&ret, sizeof(ret)); | ||
210 | } | ||
211 | while (ret >= ul); | ||
212 | return ret % i; | ||
213 | |||
214 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
215 | ret = i * get_weak_random (); | ||
216 | if (ret >= i) | ||
217 | ret = i - 1; | ||
218 | return ret; | ||
219 | |||
220 | default: | ||
221 | GNUNET_assert (0); | ||
222 | } | ||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
@@ -233,24 +233,24 @@ GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i) | |||
233 | * @return the permutation array (allocated from heap) | 233 | * @return the permutation array (allocated from heap) |
234 | */ | 234 | */ |
235 | unsigned int * | 235 | unsigned int * |
236 | GNUNET_CRYPTO_random_permute(enum GNUNET_CRYPTO_Quality mode, unsigned int n) | 236 | GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n) |
237 | { | 237 | { |
238 | unsigned int *ret; | 238 | unsigned int *ret; |
239 | unsigned int i; | 239 | unsigned int i; |
240 | unsigned int tmp; | 240 | unsigned int tmp; |
241 | uint32_t x; | 241 | uint32_t x; |
242 | 242 | ||
243 | GNUNET_assert(n > 0); | 243 | GNUNET_assert (n > 0); |
244 | ret = GNUNET_malloc(n * sizeof(unsigned int)); | 244 | ret = GNUNET_malloc (n * sizeof(unsigned int)); |
245 | for (i = 0; i < n; i++) | 245 | for (i = 0; i < n; i++) |
246 | ret[i] = i; | 246 | ret[i] = i; |
247 | for (i = n - 1; i > 0; i--) | 247 | for (i = n - 1; i > 0; i--) |
248 | { | 248 | { |
249 | x = GNUNET_CRYPTO_random_u32(mode, i + 1); | 249 | x = GNUNET_CRYPTO_random_u32 (mode, i + 1); |
250 | tmp = ret[x]; | 250 | tmp = ret[x]; |
251 | ret[x] = ret[i]; | 251 | ret[x] = ret[i]; |
252 | ret[i] = tmp; | 252 | ret[i] = tmp; |
253 | } | 253 | } |
254 | return ret; | 254 | return ret; |
255 | } | 255 | } |
256 | 256 | ||
@@ -263,44 +263,44 @@ GNUNET_CRYPTO_random_permute(enum GNUNET_CRYPTO_Quality mode, unsigned int n) | |||
263 | * @return random 64-bit number | 263 | * @return random 64-bit number |
264 | */ | 264 | */ |
265 | uint64_t | 265 | uint64_t |
266 | GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max) | 266 | GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) |
267 | { | 267 | { |
268 | uint64_t ret; | 268 | uint64_t ret; |
269 | uint64_t ul; | 269 | uint64_t ul; |
270 | 270 | ||
271 | GNUNET_assert(max > 0); | 271 | GNUNET_assert (max > 0); |
272 | switch (mode) | 272 | switch (mode) |
273 | { | ||
274 | case GNUNET_CRYPTO_QUALITY_STRONG: | ||
275 | ul = UINT64_MAX - (UINT64_MAX % max); | ||
276 | do | ||
273 | { | 277 | { |
274 | case GNUNET_CRYPTO_QUALITY_STRONG: | 278 | gcry_randomize ((unsigned char *) &ret, |
275 | ul = UINT64_MAX - (UINT64_MAX % max); | 279 | sizeof(uint64_t), |
276 | do | 280 | GCRY_STRONG_RANDOM); |
277 | { | ||
278 | gcry_randomize((unsigned char *)&ret, | ||
279 | sizeof(uint64_t), | ||
280 | GCRY_STRONG_RANDOM); | ||
281 | } | ||
282 | while (ret >= ul); | ||
283 | return ret % max; | ||
284 | |||
285 | case GNUNET_CRYPTO_QUALITY_NONCE: | ||
286 | ul = UINT64_MAX - (UINT64_MAX % max); | ||
287 | do | ||
288 | { | ||
289 | gcry_create_nonce(&ret, sizeof(ret)); | ||
290 | } | ||
291 | while (ret >= ul); | ||
292 | |||
293 | return ret % max; | ||
294 | |||
295 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
296 | ret = max * get_weak_random(); | ||
297 | if (ret >= max) | ||
298 | ret = max - 1; | ||
299 | return ret; | ||
300 | |||
301 | default: | ||
302 | GNUNET_assert(0); | ||
303 | } | 281 | } |
282 | while (ret >= ul); | ||
283 | return ret % max; | ||
284 | |||
285 | case GNUNET_CRYPTO_QUALITY_NONCE: | ||
286 | ul = UINT64_MAX - (UINT64_MAX % max); | ||
287 | do | ||
288 | { | ||
289 | gcry_create_nonce (&ret, sizeof(ret)); | ||
290 | } | ||
291 | while (ret >= ul); | ||
292 | |||
293 | return ret % max; | ||
294 | |||
295 | case GNUNET_CRYPTO_QUALITY_WEAK: | ||
296 | ret = max * get_weak_random (); | ||
297 | if (ret >= max) | ||
298 | ret = max - 1; | ||
299 | return ret; | ||
300 | |||
301 | default: | ||
302 | GNUNET_assert (0); | ||
303 | } | ||
304 | return 0; | 304 | return 0; |
305 | } | 305 | } |
306 | 306 | ||
@@ -310,9 +310,9 @@ GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max) | |||
310 | * strategy of libgcrypt implementation. | 310 | * strategy of libgcrypt implementation. |
311 | */ | 311 | */ |
312 | static void * | 312 | static void * |
313 | w_malloc(size_t n) | 313 | w_malloc (size_t n) |
314 | { | 314 | { |
315 | return calloc(n, 1); | 315 | return calloc (n, 1); |
316 | } | 316 | } |
317 | 317 | ||
318 | 318 | ||
@@ -321,9 +321,9 @@ w_malloc(size_t n) | |||
321 | * strategy of libgcrypt implementation. | 321 | * strategy of libgcrypt implementation. |
322 | */ | 322 | */ |
323 | static int | 323 | static int |
324 | w_check(const void *p) | 324 | w_check (const void *p) |
325 | { | 325 | { |
326 | (void)p; | 326 | (void) p; |
327 | return 0; /* not secure memory */ | 327 | return 0; /* not secure memory */ |
328 | } | 328 | } |
329 | 329 | ||
@@ -331,49 +331,49 @@ w_check(const void *p) | |||
331 | /** | 331 | /** |
332 | * Initialize libgcrypt. | 332 | * Initialize libgcrypt. |
333 | */ | 333 | */ |
334 | void __attribute__ ((constructor)) GNUNET_CRYPTO_random_init() | 334 | void __attribute__ ((constructor)) GNUNET_CRYPTO_random_init () |
335 | { | 335 | { |
336 | gcry_error_t rc; | 336 | gcry_error_t rc; |
337 | 337 | ||
338 | if (!gcry_check_version(NEED_LIBGCRYPT_VERSION)) | 338 | if (! gcry_check_version (NEED_LIBGCRYPT_VERSION)) |
339 | { | 339 | { |
340 | fprintf( | 340 | fprintf ( |
341 | stderr, | 341 | stderr, |
342 | _("libgcrypt has not the expected version (version %s is required).\n"), | 342 | _ ("libgcrypt has not the expected version (version %s is required).\n"), |
343 | NEED_LIBGCRYPT_VERSION); | 343 | NEED_LIBGCRYPT_VERSION); |
344 | GNUNET_assert(0); | 344 | GNUNET_assert (0); |
345 | } | 345 | } |
346 | /* set custom allocators */ | 346 | /* set custom allocators */ |
347 | gcry_set_allocation_handler(&w_malloc, &w_malloc, &w_check, &realloc, &free); | 347 | gcry_set_allocation_handler (&w_malloc, &w_malloc, &w_check, &realloc, &free); |
348 | /* Disable use of secure memory */ | 348 | /* Disable use of secure memory */ |
349 | if ((rc = gcry_control(GCRYCTL_DISABLE_SECMEM, 0))) | 349 | if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0))) |
350 | fprintf(stderr, | 350 | fprintf (stderr, |
351 | "Failed to set libgcrypt option %s: %s\n", | 351 | "Failed to set libgcrypt option %s: %s\n", |
352 | "DISABLE_SECMEM", | 352 | "DISABLE_SECMEM", |
353 | gcry_strerror(rc)); | 353 | gcry_strerror (rc)); |
354 | /* Otherwise gnunet-ecc takes forever to complete, besides | 354 | /* Otherwise gnunet-ecc takes forever to complete, besides |
355 | we are fine with "just" using GCRY_STRONG_RANDOM */ | 355 | we are fine with "just" using GCRY_STRONG_RANDOM */ |
356 | if ((rc = gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0))) | 356 | if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0))) |
357 | fprintf(stderr, | 357 | fprintf (stderr, |
358 | "Failed to set libgcrypt option %s: %s\n", | 358 | "Failed to set libgcrypt option %s: %s\n", |
359 | "ENABLE_QUICK_RANDOM", | 359 | "ENABLE_QUICK_RANDOM", |
360 | gcry_strerror(rc)); | 360 | gcry_strerror (rc)); |
361 | gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); | 361 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); |
362 | gcry_fast_random_poll(); | 362 | gcry_fast_random_poll (); |
363 | GNUNET_CRYPTO_seed_weak_random( | 363 | GNUNET_CRYPTO_seed_weak_random ( |
364 | time(NULL) ^ | 364 | time (NULL) |
365 | GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); | 365 | ^ GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); |
366 | } | 366 | } |
367 | 367 | ||
368 | 368 | ||
369 | /** | 369 | /** |
370 | * Nicely shut down libgcrypt. | 370 | * Nicely shut down libgcrypt. |
371 | */ | 371 | */ |
372 | void __attribute__ ((destructor)) GNUNET_CRYPTO_random_fini() | 372 | void __attribute__ ((destructor)) GNUNET_CRYPTO_random_fini () |
373 | { | 373 | { |
374 | gcry_set_progress_handler(NULL, NULL); | 374 | gcry_set_progress_handler (NULL, NULL); |
375 | #ifdef GCRYCTL_CLOSE_RANDOM_DEVICE | 375 | #ifdef GCRYCTL_CLOSE_RANDOM_DEVICE |
376 | (void)gcry_control(GCRYCTL_CLOSE_RANDOM_DEVICE, 0); | 376 | (void) gcry_control (GCRYCTL_CLOSE_RANDOM_DEVICE, 0); |
377 | #endif | 377 | #endif |
378 | } | 378 | } |
379 | 379 | ||