randgen.c revision 4861fc6d4f8dc4868a626e58733dd39cf88094b5
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/*
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen randgen.c : Random generator
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen Copyright (c) 2002 Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen Permission is hereby granted, free of charge, to any person obtaining
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen a copy of this software and associated documentation files (the
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "Software"), to deal in the Software without restriction, including
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen without limitation the rights to use, copy, modify, merge, publish,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen permit persons to whom the Software is furnished to do so, subject to
7a7d2aa11e46195e2d92d6c337d7e78052a5ce67Timo Sirainen the following conditions:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen The above copyright notice and this permission notice shall be
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen included in all copies or substantial portions of the Software.
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen*/
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#include "lib.h"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#include "randgen.h"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#include <unistd.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <fcntl.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int init_refcount = 0;
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainenstatic int urandom_fd;
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvoid random_fill(void *buf, unsigned int size)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int pos;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen int ret;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen i_assert(init_refcount > 0);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen i_assert(size < INT_MAX);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen for (pos = 0; pos < size; pos += ret) {
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen ret = read(urandom_fd, (char *) buf + pos, size - pos);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (ret < 0)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen i_fatal("Error reading from /dev/urandom: %m");
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainenvoid random_init(void)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (init_refcount++ > 0)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen urandom_fd = open("/dev/urandom", O_RDONLY);
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen if (urandom_fd == -1) {
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (errno == ENOENT) {
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen i_fatal("/dev/urandom doesn't exist, currently we "
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen "require it");
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen } else {
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen i_fatal("Can't open /dev/urandom: %m");
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen if (fcntl(urandom_fd, FD_CLOEXEC, 1L) < 0)
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen i_fatal("Error setting close-on-exec flag to /dev/urandom: %m");
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvoid random_deinit(void)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (--init_refcount > 0)
cd8507179823de33d6e8242e10dbc15d136245b5Timo Sirainen return;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen (void)close(urandom_fd);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen urandom_fd = -1;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen