diff options
author | Etienne CHAMPETIER <champetier.etienne@gmail.com> | 2016-06-09 13:03:00 +0000 |
---|---|---|
committer | John Crispin <john@phrozen.org> | 2016-06-08 00:19:24 +0200 |
commit | fdda69207d1509e0383e3da549f71666b194c40a (patch) | |
tree | 5f7ab6863fe9ea8a9729a535129cbb970d8b80c1 /getrandom.c | |
parent | fd4bb41ee7ab136d25609c2a917beea5d52b723b (diff) | |
download | ubox-fdda69207d1509e0383e3da549f71666b194c40a.tar.gz |
getrandom: add helper for getrandom() syscall
getrandom() was introduced in version 3.17 of the Linux kernel.
By default getrandom() block until /dev/urandom pool has been initialized
and then read from it.
Read buffer is 256 bytes so getrandom() calls always succeed.
First usage will be to save a seed for /dev/urandom.
Signed-off-by: Etienne CHAMPETIER <champetier.etienne@gmail.com>
Diffstat (limited to 'getrandom.c')
-rw-r--r-- | getrandom.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/getrandom.c b/getrandom.c new file mode 100644 index 0000000..9671202 --- /dev/null +++ b/getrandom.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 Etienne Champetier <champetier.etienne@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#define _GNU_SOURCE +#include <errno.h> +#include <linux/random.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/syscall.h> +#include <unistd.h> + +#define ERROR_EXIT(fmt, ...) do { \ + fprintf(stderr, fmt, ## __VA_ARGS__); \ + return EXIT_FAILURE; \ + } while (0) + +static int usage(char *name) +{ + fprintf(stderr, "Usage: %s <nb>\n", name); + fprintf(stderr, " => return <nb> bytes from getrandom()\n"); + return EXIT_FAILURE; +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) + return usage(argv[0]); + + if (isatty(STDOUT_FILENO)) + ERROR_EXIT("Not outputting random to a tty\n"); + + int nbtot = atoi(argv[1]); + if (nbtot < 1) + ERROR_EXIT("Invalid <nb> param (must be > 0)\n"); + + char buf[256]; + int len = sizeof(buf); + while (nbtot > 0) { + if (nbtot <= sizeof(buf)) + len = nbtot; + if (syscall(SYS_getrandom, buf, len, 0) == -1) + ERROR_EXIT("getrandom() failed: %s\n", strerror(errno)); + if (write(STDOUT_FILENO, buf, len) != len) + ERROR_EXIT("write() failed: %s\n", strerror(errno)); + nbtot -= sizeof(buf); + } +} |