diff options
author | dartraiden <wowemuh@gmail.com> | 2023-09-14 22:53:45 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2023-09-14 22:53:45 +0300 |
commit | c400f5c17af4996eb2ecf0597e17eb25c17857d8 (patch) | |
tree | c895207a210e5538c491ba9fc15ee0f28780a7f6 /libs/libsodium/src/randombytes | |
parent | cd3146d46f9b9e24065b9ec31d963d52da3cdcbe (diff) |
libsodium: update to 1.0.19
Diffstat (limited to 'libs/libsodium/src/randombytes')
4 files changed, 1229 insertions, 1231 deletions
diff --git a/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c index 85ffa9b29b..93eec1f601 100644 --- a/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c +++ b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c @@ -1,61 +1,61 @@ - -#include <assert.h> -#include <stdint.h> -#include <stdlib.h> - -#ifdef __native_client__ -# include <irt.h> - -# include "core.h" -# include "utils.h" -# include "randombytes.h" -# include "randombytes_nativeclient.h" - -static void -randombytes_nativeclient_buf(void * const buf, const size_t size) -{ - unsigned char *buf_ = (unsigned char *) buf; - struct nacl_irt_random rand_intf; - size_t readnb = (size_t) 0U; - size_t toread = size; - - if (nacl_interface_query(NACL_IRT_RANDOM_v0_1, &rand_intf, - sizeof rand_intf) != sizeof rand_intf) { - sodium_misuse(); - } - while (toread > (size_t) 0U) { - if (rand_intf.get_random_bytes(buf_, size, &readnb) != 0 || - readnb > size) { - sodium_misuse(); - } - toread -= readnb; - buf_ += readnb; - } -} - -static uint32_t -randombytes_nativeclient_random(void) -{ - uint32_t r; - - randombytes_nativeclient_buf(&r, sizeof r); - - return r; -} - -static const char * -randombytes_nativeclient_implementation_name(void) -{ - return "nativeclient"; -} - -struct randombytes_implementation randombytes_nativeclient_implementation = { - SODIUM_C99(.implementation_name =) randombytes_nativeclient_implementation_name, - SODIUM_C99(.random =) randombytes_nativeclient_random, - SODIUM_C99(.stir =) NULL, - SODIUM_C99(.uniform =) NULL, - SODIUM_C99(.buf =) randombytes_nativeclient_buf, - SODIUM_C99(.close =) NULL -}; - -#endif +
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __native_client__
+# include <irt.h>
+
+# include "core.h"
+# include "utils.h"
+# include "randombytes.h"
+# include "randombytes_nativeclient.h"
+
+static void
+randombytes_nativeclient_buf(void * const buf, const size_t size)
+{
+ unsigned char *buf_ = (unsigned char *) buf;
+ struct nacl_irt_random rand_intf;
+ size_t readnb = (size_t) 0U;
+ size_t toread = size;
+
+ if (nacl_interface_query(NACL_IRT_RANDOM_v0_1, &rand_intf,
+ sizeof rand_intf) != sizeof rand_intf) {
+ sodium_misuse();
+ }
+ while (toread > (size_t) 0U) {
+ if (rand_intf.get_random_bytes(buf_, size, &readnb) != 0 ||
+ readnb > size) {
+ sodium_misuse();
+ }
+ toread -= readnb;
+ buf_ += readnb;
+ }
+}
+
+static uint32_t
+randombytes_nativeclient_random(void)
+{
+ uint32_t r;
+
+ randombytes_nativeclient_buf(&r, sizeof r);
+
+ return r;
+}
+
+static const char *
+randombytes_nativeclient_implementation_name(void)
+{
+ return "nativeclient";
+}
+
+struct randombytes_implementation randombytes_nativeclient_implementation = {
+ SODIUM_C99(.implementation_name =) randombytes_nativeclient_implementation_name,
+ SODIUM_C99(.random =) randombytes_nativeclient_random,
+ SODIUM_C99(.stir =) NULL,
+ SODIUM_C99(.uniform =) NULL,
+ SODIUM_C99(.buf =) randombytes_nativeclient_buf,
+ SODIUM_C99(.close =) NULL
+};
+
+#endif
diff --git a/libs/libsodium/src/randombytes/randombytes.c b/libs/libsodium/src/randombytes/randombytes.c index 4c1a536ef2..34d9ebb1cd 100644 --- a/libs/libsodium/src/randombytes/randombytes.c +++ b/libs/libsodium/src/randombytes/randombytes.c @@ -1,206 +1,206 @@ - -#include <assert.h> -#include <limits.h> -#include <stdint.h> -#include <stdlib.h> - -#include <sys/types.h> - -#ifdef __EMSCRIPTEN__ -# include <emscripten.h> -#endif - -#include "core.h" -#include "crypto_stream_chacha20.h" -#include "randombytes.h" -#ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION -# include "randombytes_default.h" -#else -# ifdef __native_client__ -# include "randombytes_nativeclient.h" -# else -# include "randombytes_sysrandom.h" -# endif -#endif -#include "private/common.h" - -/* C++Builder defines a "random" macro */ -#undef random - -static const randombytes_implementation *implementation; - -#ifndef RANDOMBYTES_DEFAULT_IMPLEMENTATION -# ifdef __EMSCRIPTEN__ -# define RANDOMBYTES_DEFAULT_IMPLEMENTATION NULL -# else -# ifdef __native_client__ -# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_nativeclient_implementation; -# else -# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation; -# endif -# endif -#endif - -static void -randombytes_init_if_needed(void) -{ - if (implementation == NULL) { - implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION; - randombytes_stir(); - } -} - -int -randombytes_set_implementation(randombytes_implementation *impl) -{ - implementation = impl; - - return 0; -} - -const char * -randombytes_implementation_name(void) -{ -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - return implementation->implementation_name(); -#else - return "js"; -#endif -} - -uint32_t -randombytes_random(void) -{ -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - return implementation->random(); -#else - return EM_ASM_INT_V({ - return Module.getRandomValue(); - }); -#endif -} - -void -randombytes_stir(void) -{ -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - if (implementation->stir != NULL) { - implementation->stir(); - } -#else - EM_ASM({ - if (Module.getRandomValue === undefined) { - try { - var window_ = 'object' === typeof window ? window : self; - var crypto_ = typeof window_.crypto !== 'undefined' ? window_.crypto : window_.msCrypto; - var randomValuesStandard = function() { - var buf = new Uint32Array(1); - crypto_.getRandomValues(buf); - return buf[0] >>> 0; - }; - randomValuesStandard(); - Module.getRandomValue = randomValuesStandard; - } catch (e) { - try { - var crypto = require('crypto'); - var randomValueNodeJS = function() { - var buf = crypto['randomBytes'](4); - return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0; - }; - randomValueNodeJS(); - Module.getRandomValue = randomValueNodeJS; - } catch (e) { - throw 'No secure random number generator found'; - } - } - } - }); -#endif -} - -uint32_t -randombytes_uniform(const uint32_t upper_bound) -{ - uint32_t min; - uint32_t r; - -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - if (implementation->uniform != NULL) { - return implementation->uniform(upper_bound); - } -#endif - if (upper_bound < 2) { - return 0; - } - min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */ - do { - r = randombytes_random(); - } while (r < min); - /* r is now clamped to a set whose size mod upper_bound == 0 - * the worst case (2**31+1) requires ~ 2 attempts */ - - return r % upper_bound; -} - -void -randombytes_buf(void * const buf, const size_t size) -{ -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - if (size > (size_t) 0U) { - implementation->buf(buf, size); - } -#else - unsigned char *p = (unsigned char *) buf; - size_t i; - - for (i = (size_t) 0U; i < size; i++) { - p[i] = (unsigned char) randombytes_random(); - } -#endif -} - -void -randombytes_buf_deterministic(void * const buf, const size_t size, - const unsigned char seed[randombytes_SEEDBYTES]) -{ - static const unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES] = { - 'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G' - }; - - COMPILER_ASSERT(randombytes_SEEDBYTES == crypto_stream_chacha20_ietf_KEYBYTES); -#if SIZE_MAX > 0x4000000000ULL - COMPILER_ASSERT(randombytes_BYTES_MAX <= 0x4000000000ULL); - if (size > 0x4000000000ULL) { - sodium_misuse(); - } -#endif - crypto_stream_chacha20_ietf((unsigned char *) buf, (unsigned long long) size, - nonce, seed); -} - -size_t -randombytes_seedbytes(void) -{ - return randombytes_SEEDBYTES; -} - -int -randombytes_close(void) -{ - if (implementation != NULL && implementation->close != NULL) { - return implementation->close(); - } - return 0; -} - -void -randombytes(unsigned char * const buf, const unsigned long long buf_len) -{ - assert(buf_len <= SIZE_MAX); - randombytes_buf(buf, (size_t) buf_len); -} +
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#ifdef __EMSCRIPTEN__
+# include <emscripten.h>
+#endif
+
+#include "core.h"
+#include "crypto_stream_chacha20.h"
+#include "randombytes.h"
+#ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION
+# include "randombytes_default.h"
+#else
+# ifdef __native_client__
+# include "randombytes_nativeclient.h"
+# else
+# include "randombytes_sysrandom.h"
+# endif
+#endif
+#include "private/common.h"
+
+/* C++Builder defines a "random" macro */
+#undef random
+
+static const randombytes_implementation *implementation;
+
+#ifndef RANDOMBYTES_DEFAULT_IMPLEMENTATION
+# ifdef __EMSCRIPTEN__
+# define RANDOMBYTES_DEFAULT_IMPLEMENTATION NULL
+# else
+# ifdef __native_client__
+# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_nativeclient_implementation;
+# else
+# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation;
+# endif
+# endif
+#endif
+
+static void
+randombytes_init_if_needed(void)
+{
+ if (implementation == NULL) {
+ implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION;
+ randombytes_stir();
+ }
+}
+
+int
+randombytes_set_implementation(randombytes_implementation *impl)
+{
+ implementation = impl;
+
+ return 0;
+}
+
+const char *
+randombytes_implementation_name(void)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ return implementation->implementation_name();
+#else
+ return "js";
+#endif
+}
+
+uint32_t
+randombytes_random(void)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ return implementation->random();
+#else
+ return EM_ASM_INT_V({
+ return Module.getRandomValue();
+ });
+#endif
+}
+
+void
+randombytes_stir(void)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ if (implementation->stir != NULL) {
+ implementation->stir();
+ }
+#else
+ EM_ASM({
+ if (Module.getRandomValue === undefined) {
+ try {
+ var window_ = 'object' === typeof window ? window : self;
+ var crypto_ = typeof window_.crypto !== 'undefined' ? window_.crypto : window_.msCrypto;
+ var randomValuesStandard = function() {
+ var buf = new Uint32Array(1);
+ crypto_.getRandomValues(buf);
+ return buf[0] >>> 0;
+ };
+ randomValuesStandard();
+ Module.getRandomValue = randomValuesStandard;
+ } catch (e) {
+ try {
+ var crypto = require('crypto');
+ var randomValueNodeJS = function() {
+ var buf = crypto['randomBytes'](4);
+ return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
+ };
+ randomValueNodeJS();
+ Module.getRandomValue = randomValueNodeJS;
+ } catch (e) {
+ throw 'No secure random number generator found';
+ }
+ }
+ }
+ });
+#endif
+}
+
+uint32_t
+randombytes_uniform(const uint32_t upper_bound)
+{
+ uint32_t min;
+ uint32_t r;
+
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ if (implementation->uniform != NULL) {
+ return implementation->uniform(upper_bound);
+ }
+#endif
+ if (upper_bound < 2) {
+ return 0;
+ }
+ min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */
+ do {
+ r = randombytes_random();
+ } while (r < min);
+ /* r is now clamped to a set whose size mod upper_bound == 0
+ * the worst case (2**31+1) requires ~ 2 attempts */
+
+ return r % upper_bound;
+}
+
+void
+randombytes_buf(void * const buf, const size_t size)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ if (size > (size_t) 0U) {
+ implementation->buf(buf, size);
+ }
+#else
+ unsigned char *p = (unsigned char *) buf;
+ size_t i;
+
+ for (i = (size_t) 0U; i < size; i++) {
+ p[i] = (unsigned char) randombytes_random();
+ }
+#endif
+}
+
+void
+randombytes_buf_deterministic(void * const buf, const size_t size,
+ const unsigned char seed[randombytes_SEEDBYTES])
+{
+ static const unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES] = {
+ 'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G'
+ };
+
+ COMPILER_ASSERT(randombytes_SEEDBYTES == crypto_stream_chacha20_ietf_KEYBYTES);
+#if SIZE_MAX > 0x4000000000ULL
+ COMPILER_ASSERT(randombytes_BYTES_MAX <= 0x4000000000ULL);
+ if (size > 0x4000000000ULL) {
+ sodium_misuse();
+ }
+#endif
+ crypto_stream_chacha20_ietf((unsigned char *) buf, (unsigned long long) size,
+ nonce, seed);
+}
+
+size_t
+randombytes_seedbytes(void)
+{
+ return randombytes_SEEDBYTES;
+}
+
+int
+randombytes_close(void)
+{
+ if (implementation != NULL && implementation->close != NULL) {
+ return implementation->close();
+ }
+ return 0;
+}
+
+void
+randombytes(unsigned char * const buf, const unsigned long long buf_len)
+{
+ assert(buf_len <= SIZE_MAX);
+ randombytes_buf(buf, (size_t) buf_len);
+}
diff --git a/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c index e3ec30ff7a..fc4c9b3709 100644 --- a/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c +++ b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c @@ -1,571 +1,569 @@ - -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdlib.h> -#include <string.h> -#if !defined(_MSC_VER) && !defined(__BORLANDC__) -# include <unistd.h> -#endif - -#include <sys/types.h> -#ifndef _WIN32 -# include <sys/stat.h> -# include <sys/time.h> -#endif -#ifdef __linux__ -# ifdef __dietlibc__ -# define _LINUX_SOURCE -# include <sys/random.h> -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# else /* __dietlibc__ */ -# include <sys/syscall.h> -# if defined(SYS_getrandom) && defined(__NR_getrandom) -# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# endif -# endif /* __dietlibc__ */ -#elif defined(__FreeBSD__) -# include <sys/param.h> -# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 -# include <sys/random.h> -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# endif -#endif -#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__) -# define BLOCK_ON_DEV_RANDOM -#endif -#ifdef BLOCK_ON_DEV_RANDOM -# include <poll.h> -#endif -#ifdef HAVE_RDRAND -# pragma GCC target("rdrnd") -# include <immintrin.h> -#endif - -#include "core.h" -#include "crypto_core_salsa20.h" -#include "crypto_stream_salsa20.h" -#include "private/common.h" -#include "randombytes.h" -#include "randombytes_salsa20_random.h" -#include "runtime.h" -#include "utils.h" - -#ifdef _WIN32 -# include <windows.h> -# include <sys/timeb.h> -# define RtlGenRandom SystemFunction036 -# if defined(__cplusplus) -extern "C" -# endif -BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); -# pragma comment(lib, "advapi32.lib") -# ifdef __BORLANDC__ -# define _ftime ftime -# define _timeb timeb -# endif -#endif - -#define SALSA20_RANDOM_BLOCK_SIZE crypto_core_salsa20_OUTPUTBYTES - -#if defined(__OpenBSD__) || defined(__CloudABI__) -# define HAVE_SAFE_ARC4RANDOM 1 -#endif - -#ifndef SSIZE_MAX -# define SSIZE_MAX (SIZE_MAX / 2 - 1) -#endif -#ifndef S_ISNAM -# ifdef __COMPCERT__ -# define S_ISNAM(X) 1 -# else -# define S_ISNAM(X) 0 -# endif -#endif - -#ifndef TLS -# ifdef _WIN32 -# define TLS __declspec(thread) -# else -# define TLS -# endif -#endif - -typedef struct Salsa20RandomGlobal_ { - int initialized; - int random_data_source_fd; - int getrandom_available; - int rdrand_available; -#ifdef HAVE_GETPID - pid_t pid; -#endif -} Salsa20RandomGlobal; - -typedef struct Salsa20Random_ { - int initialized; - size_t rnd32_outleft; - unsigned char key[crypto_stream_salsa20_KEYBYTES]; - unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE]; - uint64_t nonce; -} Salsa20Random; - -static Salsa20RandomGlobal global = { - SODIUM_C99(.initialized =) 0, - SODIUM_C99(.random_data_source_fd =) -1 -}; - -static TLS Salsa20Random stream = { - SODIUM_C99(.initialized =) 0, - SODIUM_C99(.rnd32_outleft =) (size_t) 0U -}; - - -/* - * Get a high-resolution timestamp, as a uint64_t value - */ - -#ifdef _WIN32 -static uint64_t -sodium_hrtime(void) -{ - struct _timeb tb; -# pragma warning(push) -# pragma warning(disable: 4996) - _ftime(&tb); -# pragma warning(pop) - return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U; -} - -#else /* _WIN32 */ - -static uint64_t -sodium_hrtime(void) -{ - struct timeval tv; - - if (gettimeofday(&tv, NULL) != 0) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec; -} -#endif - -/* - * Initialize the entropy source - */ - -#ifdef _WIN32 - -static void -randombytes_salsa20_random_init(void) -{ - stream.nonce = sodium_hrtime(); - assert(stream.nonce != (uint64_t) 0U); - global.rdrand_available = sodium_runtime_has_rdrand(); -} - -#else /* _WIN32 */ - -static ssize_t -safe_read(const int fd, void * const buf_, size_t size) -{ - unsigned char *buf = (unsigned char *) buf_; - ssize_t readnb; - - assert(size > (size_t) 0U); - assert(size <= SSIZE_MAX); - do { - while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && - (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ - if (readnb < (ssize_t) 0) { - return readnb; /* LCOV_EXCL_LINE */ - } - if (readnb == (ssize_t) 0) { - break; /* LCOV_EXCL_LINE */ - } - size -= (size_t) readnb; - buf += readnb; - } while (size > (ssize_t) 0); - - return (ssize_t) (buf - (unsigned char *) buf_); -} - -# ifdef BLOCK_ON_DEV_RANDOM -static int -randombytes_block_on_dev_random(void) -{ - struct pollfd pfd; - int fd; - int pret; - - fd = open("/dev/random", O_RDONLY); - if (fd == -1) { - return 0; - } - pfd.fd = fd; - pfd.events = POLLIN; - pfd.revents = 0; - do { - pret = poll(&pfd, 1, -1); - } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); - if (pret != 1) { - (void) close(fd); - errno = EIO; - return -1; - } - return close(fd); -} -# endif - -# ifndef HAVE_SAFE_ARC4RANDOM -static int -randombytes_salsa20_random_random_dev_open(void) -{ -/* LCOV_EXCL_START */ - struct stat st; - static const char *devices[] = { -# ifndef USE_BLOCKING_RANDOM - "/dev/urandom", -# endif - "/dev/random", NULL - }; - const char **device = devices; - int fd; - -# ifdef BLOCK_ON_DEV_RANDOM - if (randombytes_block_on_dev_random() != 0) { - return -1; - } -# endif - do { - fd = open(*device, O_RDONLY); - if (fd != -1) { - if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) { -# if defined(F_SETFD) && defined(FD_CLOEXEC) - (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); -# endif - return fd; - } - (void) close(fd); - } else if (errno == EINTR) { - continue; - } - device++; - } while (*device != NULL); - - errno = EIO; - return -1; -/* LCOV_EXCL_STOP */ -} -# endif - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM -static int -_randombytes_linux_getrandom(void * const buf, const size_t size) -{ - int readnb; - - assert(size <= 256U); - do { - readnb = getrandom(buf, size, 0); - } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); - - return (readnb == (int) size) - 1; -} - -static int -randombytes_linux_getrandom(void * const buf_, size_t size) -{ - unsigned char *buf = (unsigned char *) buf_; - size_t chunk_size = 256U; - - do { - if (size < chunk_size) { - chunk_size = size; - assert(chunk_size > (size_t) 0U); - } - if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { - return -1; - } - size -= chunk_size; - buf += chunk_size; - } while (size > (size_t) 0U); - - return 0; -} -# endif - -static void -randombytes_salsa20_random_init(void) -{ - const int errno_save = errno; - - stream.nonce = sodium_hrtime(); - global.rdrand_available = sodium_runtime_has_rdrand(); - assert(stream.nonce != (uint64_t) 0U); - -# ifdef HAVE_SAFE_ARC4RANDOM - errno = errno_save; -# else - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - { - unsigned char fodder[16]; - - if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { - global.getrandom_available = 1; - errno = errno_save; - return; - } - global.getrandom_available = 0; - } -# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */ - - if ((global.random_data_source_fd = - randombytes_salsa20_random_random_dev_open()) == -1) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - errno = errno_save; -# endif /* HAVE_SAFE_ARC4RANDOM */ -} - -#endif /* _WIN32 */ - -/* - * (Re)seed the generator using the entropy source - */ - -static void -randombytes_salsa20_random_stir(void) -{ - memset(stream.rnd32, 0, sizeof stream.rnd32); - stream.rnd32_outleft = (size_t) 0U; - if (global.initialized == 0) { - randombytes_salsa20_random_init(); - global.initialized = 1; - } -#ifdef HAVE_GETPID - global.pid = getpid(); -#endif - -#ifndef _WIN32 - -# ifdef HAVE_SAFE_ARC4RANDOM - arc4random_buf(stream.key, sizeof stream.key); -# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) - if (global.getrandom_available != 0) { - if (randombytes_linux_getrandom(stream.key, sizeof stream.key) != 0) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - } else if (global.random_data_source_fd == -1 || - safe_read(global.random_data_source_fd, stream.key, - sizeof stream.key) != (ssize_t) sizeof stream.key) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -# else - if (global.random_data_source_fd == -1 || - safe_read(global.random_data_source_fd, stream.key, - sizeof stream.key) != (ssize_t) sizeof stream.key) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -# endif - -#else /* _WIN32 */ - if (! RtlGenRandom((PVOID) stream.key, (ULONG) sizeof stream.key)) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -#endif - - stream.initialized = 1; -} - -/* - * Reseed the generator if it hasn't been initialized yet - */ - -static void -randombytes_salsa20_random_stir_if_needed(void) -{ -#ifdef HAVE_GETPID - if (stream.initialized == 0) { - randombytes_salsa20_random_stir(); - } else if (global.pid != getpid()) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -#else - if (stream.initialized == 0) { - randombytes_salsa20_random_stir(); - } -#endif -} - -/* - * Close the stream, free global resources - */ - -#ifdef _WIN32 -static int -randombytes_salsa20_random_close(void) -{ - int ret = -1; - - if (global.initialized != 0) { - global.initialized = 0; - ret = 0; - } - sodium_memzero(&stream, sizeof stream); - - return ret; -} -#else -static int -randombytes_salsa20_random_close(void) -{ - int ret = -1; - - if (global.random_data_source_fd != -1 && - close(global.random_data_source_fd) == 0) { - global.random_data_source_fd = -1; - global.initialized = 0; -# ifdef HAVE_GETPID - global.pid = (pid_t) 0; -# endif - ret = 0; - } - -# ifdef HAVE_SAFE_ARC4RANDOM - ret = 0; -# endif - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - if (global.getrandom_available != 0) { - ret = 0; - } -# endif - - sodium_memzero(&stream, sizeof stream); - - return ret; -} -#endif - -/* - * RDRAND is only used to mitigate prediction if a key is compromised - */ - -static void -randombytes_salsa20_random_xorhwrand(void) -{ -/* LCOV_EXCL_START */ -#ifdef HAVE_RDRAND - unsigned int r; - - if (global.rdrand_available == 0) { - return; - } - (void) _rdrand32_step(&r); - * (uint32_t *) (void *) - &stream.key[crypto_stream_salsa20_KEYBYTES - 4] ^= (uint32_t) r; -#endif -/* LCOV_EXCL_STOP */ -} - -/* - * XOR the key with another same-length secret - */ - -static inline void -randombytes_salsa20_random_xorkey(const unsigned char * const mix) -{ - unsigned char *key = stream.key; - size_t i; - - for (i = (size_t) 0U; i < sizeof stream.key; i++) { - key[i] ^= mix[i]; - } -} - -/* - * Put `size` random bytes into `buf` and overwrite the key - */ - -static void -randombytes_salsa20_random_buf(void * const buf, const size_t size) -{ - size_t i; - int ret; - - randombytes_salsa20_random_stir_if_needed(); - COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES); -#if defined(ULONG_LONG_MAX) && defined(SIZE_MAX) -# if SIZE_MAX > ULONG_LONG_MAX - /* coverity[result_independent_of_operands] */ - assert(size <= ULONG_LONG_MAX); -# endif -#endif - ret = crypto_stream_salsa20((unsigned char *) buf, (unsigned long long) size, - (unsigned char *) &stream.nonce, stream.key); - assert(ret == 0); - for (i = 0U; i < sizeof size; i++) { - stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i]; - } - randombytes_salsa20_random_xorhwrand(); - stream.nonce++; - crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key, - (unsigned char *) &stream.nonce, stream.key); -} - -/* - * Pop a 32-bit value from the random pool - * - * Overwrite the key after the pool gets refilled. - */ - -static uint32_t -randombytes_salsa20_random(void) -{ - uint32_t val; - int ret; - - COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val)); - COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key)) - % sizeof val == (size_t) 0U); - if (stream.rnd32_outleft <= (size_t) 0U) { - randombytes_salsa20_random_stir_if_needed(); - COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES); - ret = crypto_stream_salsa20((unsigned char *) stream.rnd32, - (unsigned long long) sizeof stream.rnd32, - (unsigned char *) &stream.nonce, - stream.key); - assert(ret == 0); - stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key); - randombytes_salsa20_random_xorhwrand(); - randombytes_salsa20_random_xorkey(&stream.rnd32[stream.rnd32_outleft]); - memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key); - stream.nonce++; - } - stream.rnd32_outleft -= sizeof val; - memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val); - memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val); - - return val; -} - -static const char * -randombytes_salsa20_implementation_name(void) -{ - return "salsa20"; -} - -struct randombytes_implementation randombytes_salsa20_implementation = { - SODIUM_C99(.implementation_name =) randombytes_salsa20_implementation_name, - SODIUM_C99(.random =) randombytes_salsa20_random, - SODIUM_C99(.stir =) randombytes_salsa20_random_stir, - SODIUM_C99(.uniform =) NULL, - SODIUM_C99(.buf =) randombytes_salsa20_random_buf, - SODIUM_C99(.close =) randombytes_salsa20_random_close -}; +
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(_MSC_VER) && !defined(__BORLANDC__)
+# include <unistd.h>
+#endif
+
+#include <sys/types.h>
+#ifndef _WIN32
+# include <sys/stat.h>
+# include <sys/time.h>
+#endif
+#ifdef __linux__
+# ifdef __dietlibc__
+# define _LINUX_SOURCE
+# include <sys/random.h>
+# define HAVE_LINUX_COMPATIBLE_GETRANDOM
+# else /* __dietlibc__ */
+# include <sys/syscall.h>
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F))
+# define HAVE_LINUX_COMPATIBLE_GETRANDOM
+# endif
+# endif /* __dietlibc__ */
+#elif defined(__FreeBSD__)
+# include <sys/param.h>
+# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000
+# include <sys/random.h>
+# define HAVE_LINUX_COMPATIBLE_GETRANDOM
+# endif
+#endif
+#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__)
+# define BLOCK_ON_DEV_RANDOM
+#endif
+#ifdef BLOCK_ON_DEV_RANDOM
+# include <poll.h>
+#endif
+#ifdef HAVE_RDRAND
+# pragma GCC target("rdrnd")
+# include <immintrin.h>
+#endif
+
+#include "core.h"
+#include "crypto_core_salsa20.h"
+#include "crypto_stream_salsa20.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "randombytes_salsa20_random.h"
+#include "runtime.h"
+#include "utils.h"
+
+#ifdef _WIN32
+# include <windows.h>
+# include <sys/timeb.h>
+# define RtlGenRandom SystemFunction036
+# if defined(__cplusplus)
+extern "C"
+# endif
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+# pragma comment(lib, "advapi32.lib")
+# ifdef __BORLANDC__
+# define _ftime ftime
+# define _timeb timeb
+# endif
+#endif
+
+#define SALSA20_RANDOM_BLOCK_SIZE crypto_core_salsa20_OUTPUTBYTES
+
+#if defined(__OpenBSD__) || defined(__CloudABI__)
+# define HAVE_SAFE_ARC4RANDOM 1
+#endif
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX (SIZE_MAX / 2 - 1)
+#endif
+#ifndef S_ISNAM
+# ifdef __COMPCERT__
+# define S_ISNAM(X) 1
+# else
+# define S_ISNAM(X) 0
+# endif
+#endif
+
+#ifndef TLS
+# ifdef _WIN32
+# define TLS __declspec(thread)
+# else
+# define TLS
+# endif
+#endif
+
+typedef struct Salsa20RandomGlobal_ {
+ int initialized;
+ int random_data_source_fd;
+ int getrandom_available;
+ int rdrand_available;
+#ifdef HAVE_GETPID
+ pid_t pid;
+#endif
+} Salsa20RandomGlobal;
+
+typedef struct Salsa20Random_ {
+ int initialized;
+ size_t rnd32_outleft;
+ unsigned char key[crypto_stream_salsa20_KEYBYTES];
+ unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE];
+ uint64_t nonce;
+} Salsa20Random;
+
+static Salsa20RandomGlobal global = {
+ SODIUM_C99(.initialized =) 0,
+ SODIUM_C99(.random_data_source_fd =) -1
+};
+
+static TLS Salsa20Random stream = {
+ SODIUM_C99(.initialized =) 0,
+ SODIUM_C99(.rnd32_outleft =) (size_t) 0U
+};
+
+
+/*
+ * Get a high-resolution timestamp, as a uint64_t value
+ */
+
+#ifdef _WIN32
+static uint64_t
+sodium_hrtime(void)
+{
+ struct _timeb tb;
+# pragma warning(push)
+# pragma warning(disable: 4996)
+ _ftime(&tb);
+# pragma warning(pop)
+ return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U;
+}
+
+#else /* _WIN32 */
+
+static uint64_t
+sodium_hrtime(void)
+{
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec;
+}
+#endif
+
+/*
+ * Initialize the entropy source
+ */
+
+#ifdef _WIN32
+
+static void
+randombytes_salsa20_random_init(void)
+{
+ global.rdrand_available = sodium_runtime_has_rdrand();
+}
+
+#else /* _WIN32 */
+
+static ssize_t
+safe_read(const int fd, void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ ssize_t readnb;
+
+ assert(size > (size_t) 0U);
+ assert(size <= SSIZE_MAX);
+ do {
+ while ((readnb = read(fd, buf, size)) < (ssize_t) 0 &&
+ (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */
+ if (readnb < (ssize_t) 0) {
+ return readnb; /* LCOV_EXCL_LINE */
+ }
+ if (readnb == (ssize_t) 0) {
+ break; /* LCOV_EXCL_LINE */
+ }
+ size -= (size_t) readnb;
+ buf += readnb;
+ } while (size > (ssize_t) 0);
+
+ return (ssize_t) (buf - (unsigned char *) buf_);
+}
+
+# ifdef BLOCK_ON_DEV_RANDOM
+static int
+randombytes_block_on_dev_random(void)
+{
+ struct pollfd pfd;
+ int fd;
+ int pret;
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd == -1) {
+ return 0;
+ }
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ do {
+ pret = poll(&pfd, 1, -1);
+ } while (pret < 0 && (errno == EINTR || errno == EAGAIN));
+ if (pret != 1) {
+ (void) close(fd);
+ errno = EIO;
+ return -1;
+ }
+ return close(fd);
+}
+# endif
+
+# ifndef HAVE_SAFE_ARC4RANDOM
+static int
+randombytes_salsa20_random_random_dev_open(void)
+{
+/* LCOV_EXCL_START */
+ struct stat st;
+ static const char *devices[] = {
+# ifndef USE_BLOCKING_RANDOM
+ "/dev/urandom",
+# endif
+ "/dev/random", NULL
+ };
+ const char **device = devices;
+ int fd;
+
+# ifdef BLOCK_ON_DEV_RANDOM
+ if (randombytes_block_on_dev_random() != 0) {
+ return -1;
+ }
+# endif
+ do {
+ fd = open(*device, O_RDONLY);
+ if (fd != -1) {
+ if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) {
+# if defined(F_SETFD) && defined(FD_CLOEXEC)
+ (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+# endif
+ return fd;
+ }
+ (void) close(fd);
+ } else if (errno == EINTR) {
+ continue;
+ }
+ device++;
+ } while (*device != NULL);
+
+ errno = EIO;
+ return -1;
+/* LCOV_EXCL_STOP */
+}
+# endif
+
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+static int
+_randombytes_linux_getrandom(void * const buf, const size_t size)
+{
+ int readnb;
+
+ assert(size <= 256U);
+ do {
+ readnb = getrandom(buf, size, 0);
+ } while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
+
+ return (readnb == (int) size) - 1;
+}
+
+static int
+randombytes_linux_getrandom(void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ size_t chunk_size = 256U;
+
+ do {
+ if (size < chunk_size) {
+ chunk_size = size;
+ assert(chunk_size > (size_t) 0U);
+ }
+ if (_randombytes_linux_getrandom(buf, chunk_size) != 0) {
+ return -1;
+ }
+ size -= chunk_size;
+ buf += chunk_size;
+ } while (size > (size_t) 0U);
+
+ return 0;
+}
+# endif
+
+static void
+randombytes_salsa20_random_init(void)
+{
+ const int errno_save = errno;
+
+ global.rdrand_available = sodium_runtime_has_rdrand();
+
+# ifdef HAVE_SAFE_ARC4RANDOM
+ errno = errno_save;
+# else
+
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+ {
+ unsigned char fodder[16];
+
+ if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) {
+ global.getrandom_available = 1;
+ errno = errno_save;
+ return;
+ }
+ global.getrandom_available = 0;
+ }
+# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */
+
+ if ((global.random_data_source_fd =
+ randombytes_salsa20_random_random_dev_open()) == -1) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ errno = errno_save;
+# endif /* HAVE_SAFE_ARC4RANDOM */
+}
+
+#endif /* _WIN32 */
+
+/*
+ * (Re)seed the generator using the entropy source
+ */
+
+static void
+randombytes_salsa20_random_stir(void)
+{
+ stream.nonce = sodium_hrtime();
+ assert(stream.nonce != (uint64_t) 0U);
+ memset(stream.rnd32, 0, sizeof stream.rnd32);
+ stream.rnd32_outleft = (size_t) 0U;
+ if (global.initialized == 0) {
+ randombytes_salsa20_random_init();
+ global.initialized = 1;
+ }
+#ifdef HAVE_GETPID
+ global.pid = getpid();
+#endif
+
+#ifndef _WIN32
+
+# ifdef HAVE_SAFE_ARC4RANDOM
+ arc4random_buf(stream.key, sizeof stream.key);
+# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM)
+ if (global.getrandom_available != 0) {
+ if (randombytes_linux_getrandom(stream.key, sizeof stream.key) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ } else if (global.random_data_source_fd == -1 ||
+ safe_read(global.random_data_source_fd, stream.key,
+ sizeof stream.key) != (ssize_t) sizeof stream.key) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+# else
+ if (global.random_data_source_fd == -1 ||
+ safe_read(global.random_data_source_fd, stream.key,
+ sizeof stream.key) != (ssize_t) sizeof stream.key) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+# endif
+
+#else /* _WIN32 */
+ if (! RtlGenRandom((PVOID) stream.key, (ULONG) sizeof stream.key)) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#endif
+
+ stream.initialized = 1;
+}
+
+/*
+ * Reseed the generator if it hasn't been initialized yet
+ */
+
+static void
+randombytes_salsa20_random_stir_if_needed(void)
+{
+#ifdef HAVE_GETPID
+ if (stream.initialized == 0) {
+ randombytes_salsa20_random_stir();
+ } else if (global.pid != getpid()) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#else
+ if (stream.initialized == 0) {
+ randombytes_salsa20_random_stir();
+ }
+#endif
+}
+
+/*
+ * Close the stream, free global resources
+ */
+
+#ifdef _WIN32
+static int
+randombytes_salsa20_random_close(void)
+{
+ int ret = -1;
+
+ if (global.initialized != 0) {
+ global.initialized = 0;
+ ret = 0;
+ }
+ sodium_memzero(&stream, sizeof stream);
+
+ return ret;
+}
+#else
+static int
+randombytes_salsa20_random_close(void)
+{
+ int ret = -1;
+
+ if (global.random_data_source_fd != -1 &&
+ close(global.random_data_source_fd) == 0) {
+ global.random_data_source_fd = -1;
+ global.initialized = 0;
+# ifdef HAVE_GETPID
+ global.pid = (pid_t) 0;
+# endif
+ ret = 0;
+ }
+
+# ifdef HAVE_SAFE_ARC4RANDOM
+ ret = 0;
+# endif
+
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+ if (global.getrandom_available != 0) {
+ ret = 0;
+ }
+# endif
+
+ sodium_memzero(&stream, sizeof stream);
+
+ return ret;
+}
+#endif
+
+/*
+ * RDRAND is only used to mitigate prediction if a key is compromised
+ */
+
+static void
+randombytes_salsa20_random_xorhwrand(void)
+{
+/* LCOV_EXCL_START */
+#ifdef HAVE_RDRAND
+ unsigned int r;
+
+ if (global.rdrand_available == 0) {
+ return;
+ }
+ (void) _rdrand32_step(&r);
+ * (uint32_t *) (void *)
+ &stream.key[crypto_stream_salsa20_KEYBYTES - 4] ^= (uint32_t) r;
+#endif
+/* LCOV_EXCL_STOP */
+}
+
+/*
+ * XOR the key with another same-length secret
+ */
+
+static inline void
+randombytes_salsa20_random_xorkey(const unsigned char * const mix)
+{
+ unsigned char *key = stream.key;
+ size_t i;
+
+ for (i = (size_t) 0U; i < sizeof stream.key; i++) {
+ key[i] ^= mix[i];
+ }
+}
+
+/*
+ * Put `size` random bytes into `buf` and overwrite the key
+ */
+
+static void
+randombytes_salsa20_random_buf(void * const buf, const size_t size)
+{
+ size_t i;
+ int ret;
+
+ randombytes_salsa20_random_stir_if_needed();
+ COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES);
+#if defined(ULLONG_MAX) && defined(SIZE_MAX)
+# if SIZE_MAX > ULLONG_MAX
+ /* coverity[result_independent_of_operands] */
+ assert(size <= ULLONG_MAX);
+# endif
+#endif
+ ret = crypto_stream_salsa20((unsigned char *) buf, (unsigned long long) size,
+ (unsigned char *) &stream.nonce, stream.key);
+ assert(ret == 0);
+ for (i = 0U; i < sizeof size; i++) {
+ stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i];
+ }
+ randombytes_salsa20_random_xorhwrand();
+ stream.nonce++;
+ crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key,
+ (unsigned char *) &stream.nonce, stream.key);
+}
+
+/*
+ * Pop a 32-bit value from the random pool
+ *
+ * Overwrite the key after the pool gets refilled.
+ */
+
+static uint32_t
+randombytes_salsa20_random(void)
+{
+ uint32_t val;
+ int ret;
+
+ COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val));
+ COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key))
+ % sizeof val == (size_t) 0U);
+ if (stream.rnd32_outleft <= (size_t) 0U) {
+ randombytes_salsa20_random_stir_if_needed();
+ COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES);
+ ret = crypto_stream_salsa20((unsigned char *) stream.rnd32,
+ (unsigned long long) sizeof stream.rnd32,
+ (unsigned char *) &stream.nonce,
+ stream.key);
+ assert(ret == 0);
+ stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key);
+ randombytes_salsa20_random_xorhwrand();
+ randombytes_salsa20_random_xorkey(&stream.rnd32[stream.rnd32_outleft]);
+ memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key);
+ stream.nonce++;
+ }
+ stream.rnd32_outleft -= sizeof val;
+ memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val);
+ memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val);
+
+ return val;
+}
+
+static const char *
+randombytes_salsa20_implementation_name(void)
+{
+ return "salsa20";
+}
+
+struct randombytes_implementation randombytes_salsa20_implementation = {
+ SODIUM_C99(.implementation_name =) randombytes_salsa20_implementation_name,
+ SODIUM_C99(.random =) randombytes_salsa20_random,
+ SODIUM_C99(.stir =) randombytes_salsa20_random_stir,
+ SODIUM_C99(.uniform =) NULL,
+ SODIUM_C99(.buf =) randombytes_salsa20_random_buf,
+ SODIUM_C99(.close =) randombytes_salsa20_random_close
+};
diff --git a/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c index c24122f9f2..d1439bf7fc 100644 --- a/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c +++ b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c @@ -1,393 +1,393 @@ - -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdint.h> -#include <string.h> -#ifndef _WIN32 -# include <unistd.h> -#endif - -#include <stdlib.h> -#include <sys/types.h> -#ifndef _WIN32 -# include <sys/stat.h> -# include <sys/time.h> -#endif -#ifdef __linux__ -# ifdef __dietlibc__ -# define _LINUX_SOURCE -# include <sys/random.h> -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# else /* __dietlibc__ */ -# include <sys/syscall.h> -# if defined(SYS_getrandom) && defined(__NR_getrandom) -# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# endif -# endif /* __dietlibc */ -#elif defined(__FreeBSD__) -# include <sys/param.h> -# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 -# include <sys/random.h> -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# endif -#endif -#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__) -# define BLOCK_ON_DEV_RANDOM -#endif -#ifdef BLOCK_ON_DEV_RANDOM -# include <poll.h> -#endif - -#include "core.h" -#include "private/common.h" -#include "randombytes.h" -#include "randombytes_sysrandom.h" -#include "utils.h" - -#ifdef _WIN32 -/* `RtlGenRandom` is used over `CryptGenRandom` on Microsoft Windows based systems: - * - `CryptGenRandom` requires pulling in `CryptoAPI` which causes unnecessary - * memory overhead if this API is not being used for other purposes - * - `RtlGenRandom` is thus called directly instead. A detailed explanation - * can be found here: https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ - * - * In spite of the disclaimer on the `RtlGenRandom` documentation page that was - * written back in the Windows XP days, this function is here to stay. The CRT - * function `rand_s()` directly depends on it, so touching it would break many - * applications released since Windows XP. - * - * Also note that Rust, Firefox and BoringSSL (thus, Google Chrome and everything - * based on Chromium) also depend on it, and that libsodium allows the RNG to be - * replaced without patching nor recompiling the library. - */ -# include <windows.h> -# define RtlGenRandom SystemFunction036 -# if defined(__cplusplus) -extern "C" -# endif -BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); -# pragma comment(lib, "advapi32.lib") -#endif - -#if defined(__OpenBSD__) || defined(__CloudABI__) -# define HAVE_SAFE_ARC4RANDOM 1 -#endif - -#ifndef SSIZE_MAX -# define SSIZE_MAX (SIZE_MAX / 2 - 1) -#endif - -#ifdef HAVE_SAFE_ARC4RANDOM - -static uint32_t -randombytes_sysrandom(void) -{ - return arc4random(); -} - -static void -randombytes_sysrandom_stir(void) -{ -} - -static void -randombytes_sysrandom_buf(void * const buf, const size_t size) -{ - arc4random_buf(buf, size); -} - -static int -randombytes_sysrandom_close(void) -{ - return 0; -} - -#else /* __OpenBSD__ */ - -typedef struct SysRandom_ { - int random_data_source_fd; - int initialized; - int getrandom_available; -} SysRandom; - -static SysRandom stream = { - SODIUM_C99(.random_data_source_fd =) -1, - SODIUM_C99(.initialized =) 0, - SODIUM_C99(.getrandom_available =) 0 -}; - -# ifndef _WIN32 -static ssize_t -safe_read(const int fd, void * const buf_, size_t size) -{ - unsigned char *buf = (unsigned char *) buf_; - ssize_t readnb; - - assert(size > (size_t) 0U); - assert(size <= SSIZE_MAX); - do { - while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && - (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ - if (readnb < (ssize_t) 0) { - return readnb; /* LCOV_EXCL_LINE */ - } - if (readnb == (ssize_t) 0) { - break; /* LCOV_EXCL_LINE */ - } - size -= (size_t) readnb; - buf += readnb; - } while (size > (ssize_t) 0); - - return (ssize_t) (buf - (unsigned char *) buf_); -} - -# ifdef BLOCK_ON_DEV_RANDOM -static int -randombytes_block_on_dev_random(void) -{ - struct pollfd pfd; - int fd; - int pret; - - fd = open("/dev/random", O_RDONLY); - if (fd == -1) { - return 0; - } - pfd.fd = fd; - pfd.events = POLLIN; - pfd.revents = 0; - do { - pret = poll(&pfd, 1, -1); - } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); - if (pret != 1) { - (void) close(fd); - errno = EIO; - return -1; - } - return close(fd); -} -# endif /* BLOCK_ON_DEV_RANDOM */ - -static int -randombytes_sysrandom_random_dev_open(void) -{ -/* LCOV_EXCL_START */ - struct stat st; - static const char *devices[] = { -# ifndef USE_BLOCKING_RANDOM - "/dev/urandom", -# endif - "/dev/random", NULL - }; - const char **device = devices; - int fd; - -# ifdef BLOCK_ON_DEV_RANDOM - if (randombytes_block_on_dev_random() != 0) { - return -1; - } -# endif - do { - fd = open(*device, O_RDONLY); - if (fd != -1) { - if (fstat(fd, &st) == 0 && -# ifdef __COMPCERT__ - 1 -# elif defined(S_ISNAM) - (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) -# else - S_ISCHR(st.st_mode) -# endif - ) { -# if defined(F_SETFD) && defined(FD_CLOEXEC) - (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); -# endif - return fd; - } - (void) close(fd); - } else if (errno == EINTR) { - continue; - } - device++; - } while (*device != NULL); - - errno = EIO; - return -1; -/* LCOV_EXCL_STOP */ -} - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM -static int -_randombytes_linux_getrandom(void * const buf, const size_t size) -{ - int readnb; - - assert(size <= 256U); - do { - readnb = getrandom(buf, size, 0); - } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); - - return (readnb == (int) size) - 1; -} - -static int -randombytes_linux_getrandom(void * const buf_, size_t size) -{ - unsigned char *buf = (unsigned char *) buf_; - size_t chunk_size = 256U; - - do { - if (size < chunk_size) { - chunk_size = size; - assert(chunk_size > (size_t) 0U); - } - if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { - return -1; - } - size -= chunk_size; - buf += chunk_size; - } while (size > (size_t) 0U); - - return 0; -} -# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */ - -static void -randombytes_sysrandom_init(void) -{ - const int errno_save = errno; - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - { - unsigned char fodder[16]; - - if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { - stream.getrandom_available = 1; - errno = errno_save; - return; - } - stream.getrandom_available = 0; - } -# endif - - if ((stream.random_data_source_fd = - randombytes_sysrandom_random_dev_open()) == -1) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - errno = errno_save; -} - -# else /* _WIN32 */ - -static void -randombytes_sysrandom_init(void) -{ -} -# endif /* _WIN32 */ - -static void -randombytes_sysrandom_stir(void) -{ - if (stream.initialized == 0) { - randombytes_sysrandom_init(); - stream.initialized = 1; - } -} - -static void -randombytes_sysrandom_stir_if_needed(void) -{ - if (stream.initialized == 0) { - randombytes_sysrandom_stir(); - } -} - -static int -randombytes_sysrandom_close(void) -{ - int ret = -1; - -# ifndef _WIN32 - if (stream.random_data_source_fd != -1 && - close(stream.random_data_source_fd) == 0) { - stream.random_data_source_fd = -1; - stream.initialized = 0; - ret = 0; - } -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - if (stream.getrandom_available != 0) { - ret = 0; - } -# endif -# else /* _WIN32 */ - if (stream.initialized != 0) { - stream.initialized = 0; - ret = 0; - } -# endif /* _WIN32 */ - return ret; -} - -static void -randombytes_sysrandom_buf(void * const buf, const size_t size) -{ - randombytes_sysrandom_stir_if_needed(); -# if defined(ULONG_LONG_MAX) && defined(SIZE_MAX) -# if SIZE_MAX > ULONG_LONG_MAX - /* coverity[result_independent_of_operands] */ - assert(size <= ULONG_LONG_MAX); -# endif -# endif -# ifndef _WIN32 -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - if (stream.getrandom_available != 0) { - if (randombytes_linux_getrandom(buf, size) != 0) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - return; - } -# endif - if (stream.random_data_source_fd == -1 || - safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -# else /* _WIN32 */ - COMPILER_ASSERT(randombytes_BYTES_MAX <= 0xffffffffUL); - if (size > (size_t) 0xffffffffUL) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - if (! RtlGenRandom((PVOID) buf, (ULONG) size)) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -# endif /* _WIN32 */ -} - -static uint32_t -randombytes_sysrandom(void) -{ - uint32_t r; - - randombytes_sysrandom_buf(&r, sizeof r); - - return r; -} - -#endif /* __OpenBSD__ */ - -static const char * -randombytes_sysrandom_implementation_name(void) -{ - return "sysrandom"; -} - -struct randombytes_implementation randombytes_sysrandom_implementation = { - SODIUM_C99(.implementation_name =) randombytes_sysrandom_implementation_name, - SODIUM_C99(.random =) randombytes_sysrandom, - SODIUM_C99(.stir =) randombytes_sysrandom_stir, - SODIUM_C99(.uniform =) NULL, - SODIUM_C99(.buf =) randombytes_sysrandom_buf, - SODIUM_C99(.close =) randombytes_sysrandom_close -}; +
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#ifndef _WIN32
+# include <sys/stat.h>
+# include <sys/time.h>
+#endif
+#ifdef __linux__
+# ifdef __dietlibc__
+# define _LINUX_SOURCE
+# include <sys/random.h>
+# define HAVE_LINUX_COMPATIBLE_GETRANDOM
+# else /* __dietlibc__ */
+# include <sys/syscall.h>
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F))
+# define HAVE_LINUX_COMPATIBLE_GETRANDOM
+# endif
+# endif /* __dietlibc */
+#elif defined(__FreeBSD__)
+# include <sys/param.h>
+# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000
+# include <sys/random.h>
+# define HAVE_LINUX_COMPATIBLE_GETRANDOM
+# endif
+#endif
+#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__)
+# define BLOCK_ON_DEV_RANDOM
+#endif
+#ifdef BLOCK_ON_DEV_RANDOM
+# include <poll.h>
+#endif
+
+#include "core.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "randombytes_sysrandom.h"
+#include "utils.h"
+
+#ifdef _WIN32
+/* `RtlGenRandom` is used over `CryptGenRandom` on Microsoft Windows based systems:
+ * - `CryptGenRandom` requires pulling in `CryptoAPI` which causes unnecessary
+ * memory overhead if this API is not being used for other purposes
+ * - `RtlGenRandom` is thus called directly instead. A detailed explanation
+ * can be found here: https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
+ *
+ * In spite of the disclaimer on the `RtlGenRandom` documentation page that was
+ * written back in the Windows XP days, this function is here to stay. The CRT
+ * function `rand_s()` directly depends on it, so touching it would break many
+ * applications released since Windows XP.
+ *
+ * Also note that Rust, Firefox and BoringSSL (thus, Google Chrome and everything
+ * based on Chromium) also depend on it, and that libsodium allows the RNG to be
+ * replaced without patching nor recompiling the library.
+ */
+# include <windows.h>
+# define RtlGenRandom SystemFunction036
+# if defined(__cplusplus)
+extern "C"
+# endif
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+# pragma comment(lib, "advapi32.lib")
+#endif
+
+#if defined(__OpenBSD__) || defined(__CloudABI__)
+# define HAVE_SAFE_ARC4RANDOM 1
+#endif
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX (SIZE_MAX / 2 - 1)
+#endif
+
+#ifdef HAVE_SAFE_ARC4RANDOM
+
+static uint32_t
+randombytes_sysrandom(void)
+{
+ return arc4random();
+}
+
+static void
+randombytes_sysrandom_stir(void)
+{
+}
+
+static void
+randombytes_sysrandom_buf(void * const buf, const size_t size)
+{
+ arc4random_buf(buf, size);
+}
+
+static int
+randombytes_sysrandom_close(void)
+{
+ return 0;
+}
+
+#else /* __OpenBSD__ */
+
+typedef struct SysRandom_ {
+ int random_data_source_fd;
+ int initialized;
+ int getrandom_available;
+} SysRandom;
+
+static SysRandom stream = {
+ SODIUM_C99(.random_data_source_fd =) -1,
+ SODIUM_C99(.initialized =) 0,
+ SODIUM_C99(.getrandom_available =) 0
+};
+
+# ifndef _WIN32
+static ssize_t
+safe_read(const int fd, void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ ssize_t readnb;
+
+ assert(size > (size_t) 0U);
+ assert(size <= SSIZE_MAX);
+ do {
+ while ((readnb = read(fd, buf, size)) < (ssize_t) 0 &&
+ (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */
+ if (readnb < (ssize_t) 0) {
+ return readnb; /* LCOV_EXCL_LINE */
+ }
+ if (readnb == (ssize_t) 0) {
+ break; /* LCOV_EXCL_LINE */
+ }
+ size -= (size_t) readnb;
+ buf += readnb;
+ } while (size > (ssize_t) 0);
+
+ return (ssize_t) (buf - (unsigned char *) buf_);
+}
+
+# ifdef BLOCK_ON_DEV_RANDOM
+static int
+randombytes_block_on_dev_random(void)
+{
+ struct pollfd pfd;
+ int fd;
+ int pret;
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd == -1) {
+ return 0;
+ }
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ do {
+ pret = poll(&pfd, 1, -1);
+ } while (pret < 0 && (errno == EINTR || errno == EAGAIN));
+ if (pret != 1) {
+ (void) close(fd);
+ errno = EIO;
+ return -1;
+ }
+ return close(fd);
+}
+# endif /* BLOCK_ON_DEV_RANDOM */
+
+static int
+randombytes_sysrandom_random_dev_open(void)
+{
+/* LCOV_EXCL_START */
+ struct stat st;
+ static const char *devices[] = {
+# ifndef USE_BLOCKING_RANDOM
+ "/dev/urandom",
+# endif
+ "/dev/random", NULL
+ };
+ const char **device = devices;
+ int fd;
+
+# ifdef BLOCK_ON_DEV_RANDOM
+ if (randombytes_block_on_dev_random() != 0) {
+ return -1;
+ }
+# endif
+ do {
+ fd = open(*device, O_RDONLY);
+ if (fd != -1) {
+ if (fstat(fd, &st) == 0 &&
+# ifdef __COMPCERT__
+ 1
+# elif defined(S_ISNAM)
+ (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))
+# else
+ S_ISCHR(st.st_mode)
+# endif
+ ) {
+# if defined(F_SETFD) && defined(FD_CLOEXEC)
+ (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+# endif
+ return fd;
+ }
+ (void) close(fd);
+ } else if (errno == EINTR) {
+ continue;
+ }
+ device++;
+ } while (*device != NULL);
+
+ errno = EIO;
+ return -1;
+/* LCOV_EXCL_STOP */
+}
+
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+static int
+_randombytes_linux_getrandom(void * const buf, const size_t size)
+{
+ int readnb;
+
+ assert(size <= 256U);
+ do {
+ readnb = getrandom(buf, size, 0);
+ } while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
+
+ return (readnb == (int) size) - 1;
+}
+
+static int
+randombytes_linux_getrandom(void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ size_t chunk_size = 256U;
+
+ do {
+ if (size < chunk_size) {
+ chunk_size = size;
+ assert(chunk_size > (size_t) 0U);
+ }
+ if (_randombytes_linux_getrandom(buf, chunk_size) != 0) {
+ return -1;
+ }
+ size -= chunk_size;
+ buf += chunk_size;
+ } while (size > (size_t) 0U);
+
+ return 0;
+}
+# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */
+
+static void
+randombytes_sysrandom_init(void)
+{
+ const int errno_save = errno;
+
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+ {
+ unsigned char fodder[16];
+
+ if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) {
+ stream.getrandom_available = 1;
+ errno = errno_save;
+ return;
+ }
+ stream.getrandom_available = 0;
+ }
+# endif
+
+ if ((stream.random_data_source_fd =
+ randombytes_sysrandom_random_dev_open()) == -1) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ errno = errno_save;
+}
+
+# else /* _WIN32 */
+
+static void
+randombytes_sysrandom_init(void)
+{
+}
+# endif /* _WIN32 */
+
+static void
+randombytes_sysrandom_stir(void)
+{
+ if (stream.initialized == 0) {
+ randombytes_sysrandom_init();
+ stream.initialized = 1;
+ }
+}
+
+static void
+randombytes_sysrandom_stir_if_needed(void)
+{
+ if (stream.initialized == 0) {
+ randombytes_sysrandom_stir();
+ }
+}
+
+static int
+randombytes_sysrandom_close(void)
+{
+ int ret = -1;
+
+# ifndef _WIN32
+ if (stream.random_data_source_fd != -1 &&
+ close(stream.random_data_source_fd) == 0) {
+ stream.random_data_source_fd = -1;
+ stream.initialized = 0;
+ ret = 0;
+ }
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+ if (stream.getrandom_available != 0) {
+ ret = 0;
+ }
+# endif
+# else /* _WIN32 */
+ if (stream.initialized != 0) {
+ stream.initialized = 0;
+ ret = 0;
+ }
+# endif /* _WIN32 */
+ return ret;
+}
+
+static void
+randombytes_sysrandom_buf(void * const buf, const size_t size)
+{
+ randombytes_sysrandom_stir_if_needed();
+# if defined(ULLONG_MAX) && defined(SIZE_MAX)
+# if SIZE_MAX > ULLONG_MAX
+ /* coverity[result_independent_of_operands] */
+ assert(size <= ULLONG_MAX);
+# endif
+# endif
+# ifndef _WIN32
+# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
+ if (stream.getrandom_available != 0) {
+ if (randombytes_linux_getrandom(buf, size) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ return;
+ }
+# endif
+ if (stream.random_data_source_fd == -1 ||
+ safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+# else /* _WIN32 */
+ COMPILER_ASSERT(randombytes_BYTES_MAX <= 0xffffffffUL);
+ if (size > (size_t) 0xffffffffUL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (! RtlGenRandom((PVOID) buf, (ULONG) size)) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+# endif /* _WIN32 */
+}
+
+static uint32_t
+randombytes_sysrandom(void)
+{
+ uint32_t r;
+
+ randombytes_sysrandom_buf(&r, sizeof r);
+
+ return r;
+}
+
+#endif /* __OpenBSD__ */
+
+static const char *
+randombytes_sysrandom_implementation_name(void)
+{
+ return "sysrandom";
+}
+
+struct randombytes_implementation randombytes_sysrandom_implementation = {
+ SODIUM_C99(.implementation_name =) randombytes_sysrandom_implementation_name,
+ SODIUM_C99(.random =) randombytes_sysrandom,
+ SODIUM_C99(.stir =) randombytes_sysrandom_stir,
+ SODIUM_C99(.uniform =) NULL,
+ SODIUM_C99(.buf =) randombytes_sysrandom_buf,
+ SODIUM_C99(.close =) randombytes_sysrandom_close
+};
|