diff options
Diffstat (limited to 'src/tools/genkey.c')
-rw-r--r-- | src/tools/genkey.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/tools/genkey.c b/src/tools/genkey.c index d2d4c53..b9c2a86 100644 --- a/src/tools/genkey.c +++ b/src/tools/genkey.c @@ -1,10 +1,11 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ #include <errno.h> #include <stdio.h> +#include <stdbool.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> @@ -27,30 +28,45 @@ #include "encoding.h" #include "subcommands.h" -static inline ssize_t get_random_bytes(uint8_t *out, size_t len) +#ifndef WINCOMPAT +static inline bool __attribute__((__warn_unused_result__)) get_random_bytes(uint8_t *out, size_t len) { - ssize_t ret; + ssize_t ret = 0; + size_t i; int fd; + if (len > 256) { + errno = EOVERFLOW; + return false; + } + #if defined(__OpenBSD__) || (defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) || (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) - ret = getentropy(out, len); - if (!ret) - return len; + if (!getentropy(out, len)) + return true; #endif #if defined(__NR_getrandom) && defined(__linux__) - ret = syscall(__NR_getrandom, out, len, 0); - if (ret >= 0) - return ret; + if (syscall(__NR_getrandom, out, len, 0) == (ssize_t)len) + return true; #endif fd = open("/dev/urandom", O_RDONLY); if (fd < 0) - return fd; - ret = read(fd, out, len); + return false; + for (errno = 0, i = 0; i < len; i += ret, ret = 0) { + ret = read(fd, out + i, len - i); + if (ret <= 0) { + ret = errno ? -errno : -EIO; + break; + } + } close(fd); - return ret; + errno = -ret; + return i == len; } +#else +#include "wincompat/getrandom.c" +#endif int genkey_main(int argc, char *argv[]) { @@ -66,12 +82,12 @@ int genkey_main(int argc, char *argv[]) if (!fstat(STDOUT_FILENO, &stat) && S_ISREG(stat.st_mode) && stat.st_mode & S_IRWXO) fputs("Warning: writing to world accessible file.\nConsider setting the umask to 077 and trying again.\n", stderr); - if (get_random_bytes(key, WG_KEY_LEN) != WG_KEY_LEN) { + if (!get_random_bytes(key, WG_KEY_LEN)) { perror("getrandom"); return 1; } if (!strcmp(argv[0], "genkey")) - curve25519_normalize_secret(key); + curve25519_clamp_secret(key); key_to_base64(base64, key); puts(base64); |