Improve clarity

This commit is contained in:
Frank Denis 2017-11-26 13:05:47 +01:00
parent f5a4064646
commit 4098a12635

View File

@ -62,6 +62,13 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
#ifndef SSIZE_MAX #ifndef SSIZE_MAX
# define SSIZE_MAX (SIZE_MAX / 2 - 1) # define SSIZE_MAX (SIZE_MAX / 2 - 1)
#endif #endif
#ifndef S_ISNAM
# ifdef __COMPCERT__
# define S_ISNAM(X) 1
# else
# define S_ISNAM(X) 0
# endif
#endif
#ifndef TLS #ifndef TLS
# ifdef _WIN32 # ifdef _WIN32
@ -99,34 +106,53 @@ static TLS Salsa20Random stream = {
SODIUM_C99(.rnd32_outleft =) (size_t) 0U SODIUM_C99(.rnd32_outleft =) (size_t) 0U
}; };
/*
* Get a high-resolution timestamp, as a uint64_t value
*/
#ifdef _WIN32
static uint64_t static uint64_t
sodium_hrtime(void) sodium_hrtime(void)
{ {
uint64_t ts; struct _timeb tb;
#ifdef _WIN32
{
struct _timeb tb;
# pragma warning(push) # pragma warning(push)
# pragma warning(disable: 4996) # pragma warning(disable: 4996)
_ftime(&tb); _ftime(&tb);
# pragma warning(pop) # pragma warning(pop)
ts = ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U; return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U;
}
#else
{
struct timeval tv;
if (gettimeofday(&tv, NULL) != 0) {
sodium_misuse(); /* LCOV_EXCL_LINE */
}
ts = ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec;
}
#endif
return ts;
} }
#ifndef _WIN32 #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 static ssize_t
safe_read(const int fd, void * const buf_, size_t size) safe_read(const int fd, void * const buf_, size_t size)
{ {
@ -150,9 +176,7 @@ safe_read(const int fd, void * const buf_, size_t size)
return (ssize_t) (buf - (unsigned char *) buf_); return (ssize_t) (buf - (unsigned char *) buf_);
} }
#endif
#ifndef _WIN32
# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL) # if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
static int static int
randombytes_block_on_dev_random(void) randombytes_block_on_dev_random(void)
@ -203,13 +227,7 @@ randombytes_salsa20_random_random_dev_open(void)
do { do {
fd = open(*device, O_RDONLY); fd = open(*device, O_RDONLY);
if (fd != -1) { if (fd != -1) {
if (fstat(fd, &st) == 0 && if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) {
# if 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) # if defined(F_SETFD) && defined(FD_CLOEXEC)
(void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
# endif # endif
@ -302,27 +320,11 @@ randombytes_salsa20_random_init(void)
# endif /* HAVE_SAFE_ARC4RANDOM */ # endif /* HAVE_SAFE_ARC4RANDOM */
} }
#else /* _WIN32 */ #endif /* _WIN32 */
static void /*
randombytes_salsa20_random_init(void) * (Re)seed the generator using the entropy source
{ */
stream.nonce = sodium_hrtime();
assert(stream.nonce != (uint64_t) 0U);
global.rdrand_available = sodium_runtime_has_rdrand();
}
#endif
static 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];
}
}
static void static void
randombytes_salsa20_random_stir(void) randombytes_salsa20_random_stir(void)
@ -374,6 +376,10 @@ randombytes_salsa20_random_stir(void)
stream.initialized = 1; stream.initialized = 1;
} }
/*
* Reseed the generator if it hasn't been initialized yet
*/
static void static void
randombytes_salsa20_random_stir_if_needed(void) randombytes_salsa20_random_stir_if_needed(void)
{ {
@ -390,12 +396,30 @@ randombytes_salsa20_random_stir_if_needed(void)
#endif #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 static int
randombytes_salsa20_random_close(void) randombytes_salsa20_random_close(void)
{ {
int ret = -1; int ret = -1;
#ifndef _WIN32
if (global.random_data_source_fd != -1 && if (global.random_data_source_fd != -1 &&
close(global.random_data_source_fd) == 0) { close(global.random_data_source_fd) == 0) {
global.random_data_source_fd = -1; global.random_data_source_fd = -1;
@ -416,19 +440,16 @@ randombytes_salsa20_random_close(void)
} }
# endif # endif
#else /* _WIN32 */
if (global.initialized != 0) {
global.initialized = 0;
ret = 0;
}
#endif
sodium_memzero(&stream, sizeof stream); sodium_memzero(&stream, sizeof stream);
return ret; return ret;
} }
#endif
/*
* RDRAND is only used to mitigate prediction if a key is compromised
*/
/* RDRAND is only used to mitigate prediction if a key is compromised */
static void static void
randombytes_salsa20_random_xorhwrand(void) randombytes_salsa20_random_xorhwrand(void)
{ {
@ -444,6 +465,25 @@ randombytes_salsa20_random_xorhwrand(void)
#endif #endif
} }
/*
* 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 static void
randombytes_salsa20_random_buf(void * const buf, const size_t size) randombytes_salsa20_random_buf(void * const buf, const size_t size)
{ {
@ -470,6 +510,12 @@ randombytes_salsa20_random_buf(void * const buf, const size_t size)
(unsigned char *) &stream.nonce, 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 static uint32_t
randombytes_salsa20_random(void) randombytes_salsa20_random(void)
{ {