From fdda69207d1509e0383e3da549f71666b194c40a Mon Sep 17 00:00:00 2001 From: Etienne CHAMPETIER Date: Thu, 9 Jun 2016 13:03:00 +0000 Subject: [PATCH] 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 --- CMakeLists.txt | 5 +++++ getrandom.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 getrandom.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 834b5b6..73e8753 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,11 @@ IF(DEBUG) ADD_DEFINITIONS(-DDEBUG -g3) ENDIF() +ADD_EXECUTABLE(getrandom getrandom.c) +INSTALL(TARGETS getrandom + RUNTIME DESTINATION bin +) + ADD_EXECUTABLE(kmodloader kmodloader.c) TARGET_LINK_LIBRARIES(kmodloader ubox) 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 + * + * 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 +#include +#include +#include +#include +#include +#include + +#define ERROR_EXIT(fmt, ...) do { \ + fprintf(stderr, fmt, ## __VA_ARGS__); \ + return EXIT_FAILURE; \ + } while (0) + +static int usage(char *name) +{ + fprintf(stderr, "Usage: %s \n", name); + fprintf(stderr, " => return 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 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); + } +} -- 2.11.0