randgen.c revision 0bd1883396e95233def27bb13d16694c06ff4028
0N/A/* Copyright (c) 2002-2016 Dovecot authors, see the included COPYING file */
5539N/A
0N/A#include "lib.h"
0N/A#include "randgen.h"
0N/A#include "fd-close-on-exec.h"
0N/A#include <unistd.h>
0N/A#include <fcntl.h>
0N/A
0N/Astatic int init_refcount = 0;
0N/Astatic int urandom_fd;
0N/A
0N/Avoid random_fill(void *buf, size_t size)
0N/A{
0N/A size_t pos;
2362N/A ssize_t ret;
0N/A
0N/A i_assert(init_refcount > 0);
0N/A i_assert(size < SSIZE_T_MAX);
0N/A
0N/A for (pos = 0; pos < size; ) {
0N/A ret = read(urandom_fd, (char *) buf + pos, size - pos);
0N/A if (unlikely(ret <= 0)) {
0N/A if (ret == 0)
0N/A i_fatal("EOF when reading from "DEV_URANDOM_PATH);
0N/A else if (errno != EINTR)
0N/A i_fatal("read("DEV_URANDOM_PATH") failed: %m");
0N/A } else {
0N/A pos += ret;
0N/A }
0N/A }
0N/A}
4378N/A
4378N/Avoid random_init(void)
4378N/A{
4378N/A unsigned int seed;
4378N/A
4378N/A if (init_refcount++ > 0)
4378N/A return;
4378N/A
4378N/A urandom_fd = open(DEV_URANDOM_PATH, O_RDONLY);
3410N/A if (urandom_fd == -1) {
3410N/A if (errno == ENOENT) {
3410N/A i_fatal(DEV_URANDOM_PATH" doesn't exist, "
0N/A "currently we require it");
0N/A } else {
0N/A i_fatal("Can't open "DEV_URANDOM_PATH": %m");
0N/A }
0N/A }
0N/A
0N/A random_fill(&seed, sizeof(seed));
0N/A rand_set_seed(seed);
0N/A
0N/A fd_close_on_exec(urandom_fd, TRUE);
0N/A}
0N/A
0N/Avoid random_deinit(void)
0N/A{
0N/A if (--init_refcount > 0)
0N/A return;
0N/A
0N/A i_close_fd(&urandom_fd);
0N/A}
0N/A
0N/Avoid random_fill_weak(void *buf, size_t size)
0N/A{
0N/A unsigned char *cbuf = buf;
0N/A
0N/A for (; size > 0; size--)
0N/A *cbuf++ = (unsigned char)rand();
0N/A}
0N/A