static int urandom_fd = -1;
#if defined(USE_GETRANDOM) || defined(USE_RANDOM_DEV)
-/* Use a small buffer when reading randomness. This is mainly to make small
- random reads more efficient, such as i_rand*(). When reading larger amount
- of randomness this buffer is bypassed.
-
- There doesn't seem to be a big difference in Linux system CPU usage when
- buffer size is above 16 bytes. Double it just to be safe. Avoid it being
- too large anyway so we don't unnecessarily waste CPU and memory. */
-#define RANDOM_READ_BUFFER_SIZE 32
static unsigned char random_next[RANDOM_READ_BUFFER_SIZE];
static size_t random_next_pos = 0;
static size_t random_next_size = 0;
int rand_get_last_seed(unsigned int *seed_r);
#endif
+/* Internal for unit test:
+
+ Use a small buffer when reading randomness. This is mainly to make small
+ random reads more efficient, such as i_rand*(). When reading larger amount
+ of randomness this buffer is bypassed.
+
+ There doesn't seem to be a big difference in Linux system CPU usage when
+ buffer size is above 16 bytes. Double it just to be safe. Avoid it being
+ too large anyway so we don't unnecessarily waste CPU and memory. */
+#define RANDOM_READ_BUFFER_SIZE 32
+
#endif
/* Copyright (c) 2018 Dovecot authors, see the included COPYING file */
#include "test-lib.h"
+#include "hash.h"
#include "stats-dist.h"
#include "randgen.h"
#include <math.h>
test_end();
}
+static void test_random_fill(void)
+{
+ test_begin("random_fill()");
+ unsigned int hash = 0;
+ for (unsigned int i = 0; i <= (2*RANDOM_READ_BUFFER_SIZE)+1; i++) {
+ /* Rely on valgrind to verify that there are no uninitialized
+ bytes, so don't use i_malloc(). */
+ unsigned char *buf = malloc(i);
+ random_fill(buf, i);
+ hash ^= mem_hash(buf, i);
+ free(buf);
+ }
+ /* Try also with some random small numbers */
+ for (unsigned int i = 0; i < 100; i++) {
+ /* 32 = RANDOM_READ_BUFFER_SIZE */
+ unsigned int size = i_rand_minmax(1, RANDOM_READ_BUFFER_SIZE);
+ unsigned char *buf = malloc(size);
+ random_fill(buf, size);
+ hash ^= mem_hash(buf, size);
+ free(buf);
+ }
+ test_out_reason("hash", TRUE, dec2str(hash));
+ test_end();
+}
+
void test_random(void)
{
test_random_median();
test_random_limits();
+ test_random_fill();
}
enum fatal_test_state fatal_random(unsigned int stage)