diff options
Diffstat (limited to 'src/util/crypto_random.c')
-rw-r--r-- | src/util/crypto_random.c | 84 |
1 files changed, 35 insertions, 49 deletions
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index 8bb5f0587..71eaab87a 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c | |||
@@ -28,22 +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) GNUNET_log_from_strerror (kind, "util-crypto-random", syscall) | 33 | #define LOG_STRERROR(kind, syscall) \ |
34 | GNUNET_log_from_strerror (kind, "util-crypto-random", syscall) | ||
34 | 35 | ||
35 | 36 | ||
36 | /* TODO: ndurner, move this to plibc? */ | 37 | /* TODO: ndurner, move this to plibc? */ |
37 | /* The code is derived from glibc, obviously */ | 38 | /* The code is derived from glibc, obviously */ |
38 | #if !HAVE_RANDOM || !HAVE_SRANDOM | 39 | #if ! HAVE_RANDOM || ! HAVE_SRANDOM |
39 | #ifdef RANDOM | 40 | #ifdef RANDOM |
40 | #undef RANDOM | 41 | #undef RANDOM |
41 | #endif | 42 | #endif |
42 | #ifdef SRANDOM | 43 | #ifdef SRANDOM |
43 | #undef SRANDOM | 44 | #undef SRANDOM |
44 | #endif | 45 | #endif |
45 | #define RANDOM() glibc_weak_rand32() | 46 | #define RANDOM() glibc_weak_rand32 () |
46 | #define SRANDOM(s) glibc_weak_srand32(s) | 47 | #define SRANDOM(s) glibc_weak_srand32 (s) |
47 | #if defined(RAND_MAX) | 48 | #if defined(RAND_MAX) |
48 | #undef RAND_MAX | 49 | #undef RAND_MAX |
49 | #endif | 50 | #endif |
@@ -105,17 +106,12 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed) | |||
105 | * @param length buffer length | 106 | * @param length buffer length |
106 | */ | 107 | */ |
107 | void | 108 | void |
108 | GNUNET_CRYPTO_zero_keys (void *buffer, | 109 | GNUNET_CRYPTO_zero_keys (void *buffer, size_t length) |
109 | size_t length) | ||
110 | { | 110 | { |
111 | #if HAVE_MEMSET_S | 111 | #if HAVE_MEMSET_S |
112 | memset_s (buffer, | 112 | memset_s (buffer, length, 0, length); |
113 | length, | ||
114 | 0, | ||
115 | length); | ||
116 | #elif HAVE_EXPLICIT_BZERO | 113 | #elif HAVE_EXPLICIT_BZERO |
117 | explicit_bzero (buffer, | 114 | explicit_bzero (buffer, length); |
118 | length); | ||
119 | #else | 115 | #else |
120 | volatile unsigned char *p = buffer; | 116 | volatile unsigned char *p = buffer; |
121 | while (length--) | 117 | while (length--) |
@@ -175,8 +171,7 @@ GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, | |||
175 | * @return a random value in the interval [0,i[. | 171 | * @return a random value in the interval [0,i[. |
176 | */ | 172 | */ |
177 | uint32_t | 173 | uint32_t |
178 | GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, | 174 | GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i) |
179 | uint32_t i) | ||
180 | { | 175 | { |
181 | #ifdef gcry_fast_random_poll | 176 | #ifdef gcry_fast_random_poll |
182 | static unsigned int invokeCount; | 177 | static unsigned int invokeCount; |
@@ -197,18 +192,17 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, | |||
197 | ul = UINT32_MAX - (UINT32_MAX % i); | 192 | ul = UINT32_MAX - (UINT32_MAX % i); |
198 | do | 193 | do |
199 | { | 194 | { |
200 | gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t), | 195 | gcry_randomize ((unsigned char *) &ret, |
196 | sizeof (uint32_t), | ||
201 | GCRY_STRONG_RANDOM); | 197 | GCRY_STRONG_RANDOM); |
202 | } | 198 | } while (ret >= ul); |
203 | while (ret >= ul); | ||
204 | return ret % i; | 199 | return ret % i; |
205 | case GNUNET_CRYPTO_QUALITY_NONCE: | 200 | case GNUNET_CRYPTO_QUALITY_NONCE: |
206 | ul = UINT32_MAX - (UINT32_MAX % i); | 201 | ul = UINT32_MAX - (UINT32_MAX % i); |
207 | do | 202 | do |
208 | { | 203 | { |
209 | gcry_create_nonce (&ret, sizeof (ret)); | 204 | gcry_create_nonce (&ret, sizeof (ret)); |
210 | } | 205 | } while (ret >= ul); |
211 | while (ret >= ul); | ||
212 | return ret % i; | 206 | return ret % i; |
213 | case GNUNET_CRYPTO_QUALITY_WEAK: | 207 | case GNUNET_CRYPTO_QUALITY_WEAK: |
214 | ret = i * get_weak_random (); | 208 | ret = i * get_weak_random (); |
@@ -231,8 +225,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, | |||
231 | * @return the permutation array (allocated from heap) | 225 | * @return the permutation array (allocated from heap) |
232 | */ | 226 | */ |
233 | unsigned int * | 227 | unsigned int * |
234 | GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, | 228 | GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n) |
235 | unsigned int n) | ||
236 | { | 229 | { |
237 | unsigned int *ret; | 230 | unsigned int *ret; |
238 | unsigned int i; | 231 | unsigned int i; |
@@ -262,8 +255,7 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, | |||
262 | * @return random 64-bit number | 255 | * @return random 64-bit number |
263 | */ | 256 | */ |
264 | uint64_t | 257 | uint64_t |
265 | GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, | 258 | GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) |
266 | uint64_t max) | ||
267 | { | 259 | { |
268 | uint64_t ret; | 260 | uint64_t ret; |
269 | uint64_t ul; | 261 | uint64_t ul; |
@@ -275,18 +267,17 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, | |||
275 | ul = UINT64_MAX - (UINT64_MAX % max); | 267 | ul = UINT64_MAX - (UINT64_MAX % max); |
276 | do | 268 | do |
277 | { | 269 | { |
278 | gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t), | 270 | gcry_randomize ((unsigned char *) &ret, |
271 | sizeof (uint64_t), | ||
279 | GCRY_STRONG_RANDOM); | 272 | GCRY_STRONG_RANDOM); |
280 | } | 273 | } while (ret >= ul); |
281 | while (ret >= ul); | ||
282 | return ret % max; | 274 | return ret % max; |
283 | case GNUNET_CRYPTO_QUALITY_NONCE: | 275 | case GNUNET_CRYPTO_QUALITY_NONCE: |
284 | ul = UINT64_MAX - (UINT64_MAX % max); | 276 | ul = UINT64_MAX - (UINT64_MAX % max); |
285 | do | 277 | do |
286 | { | 278 | { |
287 | gcry_create_nonce (&ret, sizeof (ret)); | 279 | gcry_create_nonce (&ret, sizeof (ret)); |
288 | } | 280 | } while (ret >= ul); |
289 | while (ret >= ul); | ||
290 | 281 | ||
291 | return ret % max; | 282 | return ret % max; |
292 | case GNUNET_CRYPTO_QUALITY_WEAK: | 283 | case GNUNET_CRYPTO_QUALITY_WEAK: |
@@ -319,6 +310,7 @@ w_malloc (size_t n) | |||
319 | static int | 310 | static int |
320 | w_check (const void *p) | 311 | w_check (const void *p) |
321 | { | 312 | { |
313 | (void) p; | ||
322 | return 0; /* not secure memory */ | 314 | return 0; /* not secure memory */ |
323 | } | 315 | } |
324 | 316 | ||
@@ -326,50 +318,45 @@ w_check (const void *p) | |||
326 | /** | 318 | /** |
327 | * Initialize libgcrypt. | 319 | * Initialize libgcrypt. |
328 | */ | 320 | */ |
329 | void __attribute__ ((constructor)) | 321 | void __attribute__ ((constructor)) GNUNET_CRYPTO_random_init () |
330 | GNUNET_CRYPTO_random_init () | ||
331 | { | 322 | { |
332 | gcry_error_t rc; | 323 | gcry_error_t rc; |
333 | 324 | ||
334 | if (! gcry_check_version (NEED_LIBGCRYPT_VERSION)) | 325 | if (! gcry_check_version (NEED_LIBGCRYPT_VERSION)) |
335 | { | 326 | { |
336 | FPRINTF (stderr, | 327 | FPRINTF ( |
337 | _("libgcrypt has not the expected version (version %s is required).\n"), | 328 | stderr, |
338 | NEED_LIBGCRYPT_VERSION); | 329 | _ ("libgcrypt has not the expected version (version %s is required).\n"), |
330 | NEED_LIBGCRYPT_VERSION); | ||
339 | GNUNET_assert (0); | 331 | GNUNET_assert (0); |
340 | } | 332 | } |
341 | /* set custom allocators */ | 333 | /* set custom allocators */ |
342 | gcry_set_allocation_handler (&w_malloc, | 334 | gcry_set_allocation_handler (&w_malloc, &w_malloc, &w_check, &realloc, &free); |
343 | &w_malloc, | ||
344 | &w_check, | ||
345 | &realloc, | ||
346 | &free); | ||
347 | /* Disable use of secure memory */ | 335 | /* Disable use of secure memory */ |
348 | if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0))) | 336 | if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0))) |
349 | FPRINTF (stderr, | 337 | FPRINTF (stderr, |
350 | "Failed to set libgcrypt option %s: %s\n", | 338 | "Failed to set libgcrypt option %s: %s\n", |
351 | "DISABLE_SECMEM", | 339 | "DISABLE_SECMEM", |
352 | gcry_strerror (rc)); | 340 | gcry_strerror (rc)); |
353 | /* Otherwise gnunet-ecc takes forever to complete, besides | 341 | /* Otherwise gnunet-ecc takes forever to complete, besides |
354 | we are fine with "just" using GCRY_STRONG_RANDOM */ | 342 | we are fine with "just" using GCRY_STRONG_RANDOM */ |
355 | if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0))) | 343 | if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0))) |
356 | FPRINTF (stderr, | 344 | FPRINTF (stderr, |
357 | "Failed to set libgcrypt option %s: %s\n", | 345 | "Failed to set libgcrypt option %s: %s\n", |
358 | "ENABLE_QUICK_RANDOM", | 346 | "ENABLE_QUICK_RANDOM", |
359 | gcry_strerror (rc)); | 347 | gcry_strerror (rc)); |
360 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); | 348 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); |
361 | gcry_fast_random_poll (); | 349 | gcry_fast_random_poll (); |
362 | GNUNET_CRYPTO_seed_weak_random (time (NULL) ^ | 350 | GNUNET_CRYPTO_seed_weak_random ( |
363 | GNUNET_CRYPTO_random_u32 | 351 | time (NULL) ^ |
364 | (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); | 352 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); |
365 | } | 353 | } |
366 | 354 | ||
367 | 355 | ||
368 | /** | 356 | /** |
369 | * Nicely shut down libgcrypt. | 357 | * Nicely shut down libgcrypt. |
370 | */ | 358 | */ |
371 | void __attribute__ ((destructor)) | 359 | void __attribute__ ((destructor)) GNUNET_CRYPTO_random_fini () |
372 | GNUNET_CRYPTO_random_fini () | ||
373 | { | 360 | { |
374 | gcry_set_progress_handler (NULL, NULL); | 361 | gcry_set_progress_handler (NULL, NULL); |
375 | #ifdef GCRYCTL_CLOSE_RANDOM_DEVICE | 362 | #ifdef GCRYCTL_CLOSE_RANDOM_DEVICE |
@@ -378,5 +365,4 @@ GNUNET_CRYPTO_random_fini () | |||
378 | } | 365 | } |
379 | 366 | ||
380 | 367 | ||
381 | |||
382 | /* end of crypto_random.c */ | 368 | /* end of crypto_random.c */ |