GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
crypto_random.c File Reference

functions to gather random numbers More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include <gcrypt.h>
Include dependency graph for crypto_random.c:

Go to the source code of this file.

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-crypto-random", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)    GNUNET_log_from_strerror (kind, "util-crypto-random", syscall)
 
#define RANDOM()   glibc_weak_rand32 ()
 
#define SRANDOM(s)   glibc_weak_srand32 (s)
 
#define RAND_MAX   0x7fffffff /* Hopefully this is correct */
 

Functions

void glibc_weak_srand32 (int32_t s)
 
int32_t glibc_weak_rand32 ()
 
static double get_weak_random (void)
 Create a cryptographically weak pseudo-random number in the interval of 0 to 1.
 
void GNUNET_CRYPTO_seed_weak_random (int32_t seed)
 Seed a weak random generator.
 
void GNUNET_CRYPTO_zero_keys (void *buffer, size_t length)
 Zero out buffer, securely against compiler optimizations.
 
void GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
 Fill block with a random values.
 
uint32_t GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i)
 Produce a random unsigned 32-bit number modulo i.
 
unsigned int * GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n)
 Get an array with a random permutation of the numbers 0...n-1.
 
uint64_t GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
 Generate a random unsigned 64-bit value.
 
void GNUNET_CRYPTO_random_timeflake (enum GNUNET_CRYPTO_Quality mode, struct GNUNET_Uuid *uuid)
 Fill UUID with a timeflake pseudo-random value.
 
static void * w_malloc (size_t n)
 Allocation wrapper for libgcrypt, used to avoid bad locking strategy of libgcrypt implementation.
 
static int w_check (const void *p)
 Allocation wrapper for libgcrypt, used to avoid bad locking strategy of libgcrypt implementation.
 
void GNUNET_CRYPTO_random_init (void)
 
void __attribute__ ((constructor))
 Initialize libgcrypt.
 
void GNUNET_CRYPTO_random_fini (void)
 
void __attribute__ ((destructor))
 Nicely shut down libgcrypt.
 

Variables

static int32_t glibc_weak_rand32_state = 1
 

Detailed Description

functions to gather random numbers

Author
Christian Grothoff

Definition in file crypto_random.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-crypto-random", __VA_ARGS__)

Definition at line 32 of file crypto_random.c.

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)     GNUNET_log_from_strerror (kind, "util-crypto-random", syscall)

Definition at line 34 of file crypto_random.c.

59{
61}
62
63
64int32_t
66{
67 int32_t val = glibc_weak_rand32_state;
68
69 val = ((glibc_weak_rand32_state * 1103515245) + 12345) & 0x7fffffff;
71 return val;
72}
73
74
75#endif
76
82static double
83get_weak_random (void)
84{
85 return(random () / (double) RAND_MAX);
86}
87
88
89void
91{
92#ifdef OPENBSD
93 srandom_deterministic (seed);
94#else
95 srandom (seed);
96#endif
97}
98
99
108void
109GNUNET_CRYPTO_zero_keys (void *buffer, size_t length)
110{
111#if HAVE_MEMSET_S
112 memset_s (buffer, length, 0, length);
113#elif HAVE_EXPLICIT_BZERO
114 explicit_bzero (buffer, length);
115#else
116 volatile unsigned char *p = buffer;
117 while (length--)
118 *p++ = 0;
119#endif
120}
121
122
131void
133 void *buffer,
134 size_t length)
135{
136#ifdef gcry_fast_random_poll
137 static unsigned int invokeCount;
138#endif
139 switch (mode)
140 {
142 /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
143#ifdef gcry_fast_random_poll
144 if ((invokeCount++ % 256) == 0)
145 gcry_fast_random_poll ();
146#endif
147 gcry_randomize (buffer, length, GCRY_STRONG_RANDOM);
148 return;
149
151 gcry_create_nonce (buffer, length);
152 return;
153
155 /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
156#ifdef gcry_fast_random_poll
157 if ((invokeCount++ % 256) == 0)
158 gcry_fast_random_poll ();
159#endif
160 gcry_randomize (buffer, length, GCRY_WEAK_RANDOM);
161 return;
162
163 default:
164 GNUNET_assert (0);
165 }
166}
167
168
176uint32_t
178 uint32_t i)
179{
180#ifdef gcry_fast_random_poll
181 static unsigned int invokeCount;
182#endif
183 uint32_t ret;
184 uint32_t ul;
185
186 GNUNET_assert (i > 0);
187
188 switch (mode)
189 {
191 /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
192#ifdef gcry_fast_random_poll
193 if ((invokeCount++ % 256) == 0)
194 gcry_fast_random_poll ();
195#endif
196 ul = UINT32_MAX - (UINT32_MAX % i);
197 do
198 {
199 gcry_randomize ((unsigned char *) &ret,
200 sizeof(uint32_t),
201 GCRY_STRONG_RANDOM);
202 }
203 while (ret >= ul);
204 return ret % i;
205
207 ul = UINT32_MAX - (UINT32_MAX % i);
208 do
209 {
210 gcry_create_nonce (&ret, sizeof(ret));
211 }
212 while (ret >= ul);
213 return ret % i;
214
216 ret = i * get_weak_random ();
217 if (ret >= i)
218 ret = i - 1;
219 return ret;
220
221 default:
222 GNUNET_assert (0);
223 }
224 return 0;
225}
226
227
236unsigned int *
238 unsigned int n)
239{
240 unsigned int *ret;
241 unsigned int i;
242 unsigned int tmp;
243 uint32_t x;
244
245 GNUNET_assert (n > 0);
246 ret = GNUNET_malloc (n * sizeof(unsigned int));
247 for (i = 0; i < n; i++)
248 ret[i] = i;
249 for (i = n - 1; i > 0; i--)
250 {
251 x = GNUNET_CRYPTO_random_u32 (mode, i + 1);
252 tmp = ret[x];
253 ret[x] = ret[i];
254 ret[i] = tmp;
255 }
256 return ret;
257}
258
259
260uint64_t
262 uint64_t max)
263{
264 uint64_t ret;
265 uint64_t ul;
266
267 GNUNET_assert (max > 0);
268 switch (mode)
269 {
271 ul = UINT64_MAX - (UINT64_MAX % max);
272 do
273 {
274 gcry_randomize ((unsigned char *) &ret,
275 sizeof(uint64_t),
276 GCRY_STRONG_RANDOM);
277 }
278 while (ret >= ul);
279 return ret % max;
280
282 ul = UINT64_MAX - (UINT64_MAX % max);
283 do
284 {
285 gcry_create_nonce (&ret, sizeof(ret));
286 }
287 while (ret >= ul);
288
289 return ret % max;
290
292 ret = max * get_weak_random ();
293 if (ret >= max)
294 ret = max - 1;
295 return ret;
296
297 default:
298 GNUNET_assert (0);
299 }
300 return 0;
301}
302
303
314void
316 struct GNUNET_Uuid *uuid)
317{
318 struct GNUNET_TIME_Absolute now;
319 uint64_t ms;
320 uint64_t be;
321 char *base;
322
324 uuid,
325 sizeof (struct GNUNET_Uuid));
327 ms = now.abs_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
328 be = GNUNET_htonll (ms);
329 base = (char *) &be;
330 memcpy (uuid,
331 base + 2,
332 sizeof (be) - 2);
333}
334
335
340static void *
341w_malloc (size_t n)
342{
343 return calloc (n, 1);
344}
345
346
351static int
352w_check (const void *p)
353{
354 (void) p;
355 return 0; /* not secure memory */
356}
357
358void
360
364void __attribute__ ((constructor))
366{
367 gcry_error_t rc;
368
369 if (! gcry_check_version (NEED_LIBGCRYPT_VERSION))
370 {
371 fprintf (
372 stderr,
373 _ ("libgcrypt has not the expected version (version %s is required).\n"),
374 NEED_LIBGCRYPT_VERSION);
375 GNUNET_assert (0);
376 }
377 /* set custom allocators */
378 gcry_set_allocation_handler (&w_malloc, &w_malloc, &w_check, &realloc, &free);
379 /* Disable use of secure memory */
380 if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0)))
381 fprintf (stderr,
382 "Failed to set libgcrypt option %s: %s\n",
383 "DISABLE_SECMEM",
384 gcry_strerror (rc));
385 /* Otherwise gnunet-ecc takes forever to complete, besides
386 we are fine with "just" using GCRY_STRONG_RANDOM */
387 if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0)))
388 fprintf (stderr,
389 "Failed to set libgcrypt option %s: %s\n",
390 "ENABLE_QUICK_RANDOM",
391 gcry_strerror (rc));
392 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
393 gcry_fast_random_poll ();
395 time (NULL)
397}
398
399void
401
405void __attribute__ ((destructor))
407{
408 gcry_set_progress_handler (NULL, NULL);
409#ifdef GCRYCTL_CLOSE_RANDOM_DEVICE
410 (void) gcry_control (GCRYCTL_CLOSE_RANDOM_DEVICE, 0);
411#endif
412}
413
414
415/* end of crypto_random.c */
static int32_t glibc_weak_rand32_state
#define RAND_MAX
int32_t glibc_weak_rand32()
void GNUNET_CRYPTO_random_init(void)
static double get_weak_random(void)
Create a cryptographically weak pseudo-random number in the interval of 0 to 1.
void GNUNET_CRYPTO_random_fini(void)
static void * w_malloc(size_t n)
Allocation wrapper for libgcrypt, used to avoid bad locking strategy of libgcrypt implementation.
static int w_check(const void *p)
Allocation wrapper for libgcrypt, used to avoid bad locking strategy of libgcrypt implementation.
static int ret
Final status code.
Definition gnunet-arm.c:93
static uint8_t seed
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static enum @44 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
struct GNUNET_PQ_ResultSpec __attribute__
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
void GNUNET_CRYPTO_random_timeflake(enum GNUNET_CRYPTO_Quality mode, struct GNUNET_Uuid *uuid)
Fill UUID with a timeflake pseudo-random value.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
GNUNET_CRYPTO_Quality
Desired quality level for random numbers.
void GNUNET_CRYPTO_seed_weak_random(int32_t seed)
Seed a weak random generator.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random unsigned 32-bit number modulo i.
unsigned int * GNUNET_CRYPTO_random_permute(enum GNUNET_CRYPTO_Quality mode, unsigned int n)
Get an array with a random permutation of the numbers 0...n-1.
void GNUNET_CRYPTO_zero_keys(void *buffer, size_t length)
Zero out buffer, securely against compiler optimizations.
@ GNUNET_CRYPTO_QUALITY_STRONG
High-quality operations are desired.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define max(x, y)
#define _(String)
GNU gettext support macro.
Definition platform.h:179
Time for absolute times used by GNUnet, in microseconds.
A UUID, a 128 bit "random" value.

◆ RANDOM

#define RANDOM ( )    glibc_weak_rand32 ()

Definition at line 47 of file crypto_random.c.

◆ SRANDOM

#define SRANDOM (   s)    glibc_weak_srand32 (s)

Definition at line 48 of file crypto_random.c.

◆ RAND_MAX

#define RAND_MAX   0x7fffffff /* Hopefully this is correct */

Definition at line 52 of file crypto_random.c.

Function Documentation

◆ glibc_weak_srand32()

void glibc_weak_srand32 ( int32_t  s)

Definition at line 59 of file crypto_random.c.

60{
62}

References glibc_weak_rand32_state.

◆ glibc_weak_rand32()

int32_t glibc_weak_rand32 ( )

Definition at line 66 of file crypto_random.c.

67{
68 int32_t val = glibc_weak_rand32_state;
69
70 val = ((glibc_weak_rand32_state * 1103515245) + 12345) & 0x7fffffff;
72 return val;
73}

References glibc_weak_rand32_state.

◆ get_weak_random()

static double get_weak_random ( void  )
static

Create a cryptographically weak pseudo-random number in the interval of 0 to 1.

Returns
number between 0 and 1.

Definition at line 84 of file crypto_random.c.

85{
86 return(random () / (double) RAND_MAX);
87}

References RAND_MAX.

Referenced by GNUNET_CRYPTO_random_u32(), and GNUNET_CRYPTO_random_u64().

Here is the caller graph for this function:

◆ w_malloc()

static void * w_malloc ( size_t  n)
static

Allocation wrapper for libgcrypt, used to avoid bad locking strategy of libgcrypt implementation.

Definition at line 342 of file crypto_random.c.

343{
344 return calloc (n, 1);
345}

Referenced by __attribute__().

Here is the caller graph for this function:

◆ w_check()

static int w_check ( const void *  p)
static

Allocation wrapper for libgcrypt, used to avoid bad locking strategy of libgcrypt implementation.

Definition at line 353 of file crypto_random.c.

354{
355 (void) p;
356 return 0; /* not secure memory */
357}

References p.

Referenced by __attribute__().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_random_init()

void GNUNET_CRYPTO_random_init ( void  )

◆ __attribute__() [1/2]

void __attribute__ ( (constructor)  )

Initialize libgcrypt.

Definition at line 365 of file crypto_random.c.

367{
368 gcry_error_t rc;
369
370 if (! gcry_check_version (NEED_LIBGCRYPT_VERSION))
371 {
372 fprintf (
373 stderr,
374 _ ("libgcrypt has not the expected version (version %s is required).\n"),
375 NEED_LIBGCRYPT_VERSION);
376 GNUNET_assert (0);
377 }
378 /* set custom allocators */
379 gcry_set_allocation_handler (&w_malloc, &w_malloc, &w_check, &realloc, &free);
380 /* Disable use of secure memory */
381 if ((rc = gcry_control (GCRYCTL_DISABLE_SECMEM, 0)))
382 fprintf (stderr,
383 "Failed to set libgcrypt option %s: %s\n",
384 "DISABLE_SECMEM",
385 gcry_strerror (rc));
386 /* Otherwise gnunet-ecc takes forever to complete, besides
387 we are fine with "just" using GCRY_STRONG_RANDOM */
388 if ((rc = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0)))
389 fprintf (stderr,
390 "Failed to set libgcrypt option %s: %s\n",
391 "ENABLE_QUICK_RANDOM",
392 gcry_strerror (rc));
393 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
394 gcry_fast_random_poll ();
396 time (NULL)
398}

References _, GNUNET_assert, GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_CRYPTO_seed_weak_random(), w_check(), and w_malloc().

Here is the call graph for this function:

◆ GNUNET_CRYPTO_random_fini()

void GNUNET_CRYPTO_random_fini ( void  )

◆ __attribute__() [2/2]

void __attribute__ ( (destructor)  )

Nicely shut down libgcrypt.

Definition at line 406 of file crypto_random.c.

408{
409 gcry_set_progress_handler (NULL, NULL);
410#ifdef GCRYCTL_CLOSE_RANDOM_DEVICE
411 (void) gcry_control (GCRYCTL_CLOSE_RANDOM_DEVICE, 0);
412#endif
413}

Variable Documentation

◆ glibc_weak_rand32_state

int32_t glibc_weak_rand32_state = 1
static

Definition at line 55 of file crypto_random.c.

Referenced by glibc_weak_rand32(), and glibc_weak_srand32().