X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcrypto_random.c;h=25ba4db2a81ac94c9172c82c428590288ca7e474;hb=0ea8e006d5f5ef84e31e000607bd24a23f8fc1ed;hp=5d85d1daa1376d5b2f96b5f2ba146acd69e8664a;hpb=652e89b59ed2207c2c12172fdabcd6e659995c81;p=oweals%2Fgnunet.git diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index 5d85d1daa..25ba4db2a 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c @@ -29,6 +29,18 @@ #include "gnunet_crypto_lib.h" #include +/** + * Create a cryptographically weak pseudo-random number in the interval of 0 to 1. + * + * @return number between 0 and 1. + */ +static double +weak_random () +{ + return ((double) RANDOM () / RAND_MAX); +} + + /** * Produce a random value. * @@ -43,6 +55,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i) static unsigned int invokeCount; #endif uint32_t ret; + uint32_t ul; GNUNET_assert (i > 0); @@ -53,13 +66,18 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i) if ((invokeCount++ % 256) == 0) gcry_fast_random_poll (); #endif - gcry_randomize ((unsigned char *) &ret, - sizeof (uint32_t), GCRY_STRONG_RANDOM); + ul = UINT32_MAX - (UINT32_MAX % i); + do + { + gcry_randomize ((unsigned char *) &ret, + sizeof (uint32_t), GCRY_STRONG_RANDOM); + } + while (ret >= ul); return ret % i; } else { - ret = i * ((double) RANDOM () / RAND_MAX); + ret = i * weak_random (); if (ret >= i) ret = i - 1; return ret; @@ -87,9 +105,9 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n) ret = GNUNET_malloc (n * sizeof (unsigned int)); for (i = 0; i < n; i++) ret[i] = i; - for (i = 0; i < n; i++) + for (i = n - 1; i > 0; i--) { - x = GNUNET_CRYPTO_random_u32 (mode, n); + x = GNUNET_CRYPTO_random_u32 (mode, i+1); tmp = ret[x]; ret[x] = ret[i]; ret[i] = tmp; @@ -109,17 +127,23 @@ uint64_t GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) { uint64_t ret; + uint64_t ul; GNUNET_assert (max > 0); if (mode == GNUNET_CRYPTO_QUALITY_STRONG) { - gcry_randomize ((unsigned char *) &ret, - sizeof (uint64_t), GCRY_STRONG_RANDOM); + ul = UINT64_MAX - (UINT64_MAX % max); + do + { + gcry_randomize ((unsigned char *) &ret, + sizeof (uint64_t), GCRY_STRONG_RANDOM); + } + while (ret >= ul); return ret % max; } else { - ret = max * ((double) RANDOM () / RAND_MAX); + ret = max * weak_random (); if (ret >= max) ret = max - 1; return ret;