diff options
Diffstat (limited to 'src/tools/genkey.c')
-rw-r--r-- | src/tools/genkey.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/src/tools/genkey.c b/src/tools/genkey.c index 645f614..21d2f7a 100644 --- a/src/tools/genkey.c +++ b/src/tools/genkey.c @@ -5,6 +5,7 @@ #include <errno.h> #include <stdio.h> +#include <stdbool.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> @@ -27,29 +28,40 @@ #include "encoding.h" #include "subcommands.h" -static inline ssize_t get_random_bytes(uint8_t *out, size_t len) +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; } int genkey_main(int argc, char *argv[]) @@ -66,7 +78,7 @@ 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; } |