summaryrefslogtreecommitdiff
path: root/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c')
-rw-r--r--src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c b/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
index 374ff4d..2b44469 100644
--- a/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
+++ b/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
@@ -41,7 +41,7 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
typedef struct Salsa20Random_ {
unsigned char key[crypto_stream_salsa20_KEYBYTES];
- unsigned char rnd32[SALSA20_RANDOM_BLOCK_SIZE];
+ unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE];
uint64_t nonce;
size_t rnd32_outleft;
#ifndef _MSC_VER
@@ -67,7 +67,10 @@ sodium_hrtime(void)
#ifdef _WIN32
struct _timeb tb;
+# pragma warning(push)
+# pragma warning(disable: 4996)
_ftime(&tb);
+# pragma warning(pop)
tv.tv_sec = (long) tb.time;
tv.tv_usec = ((int) tb.millitm) * 1000;
ret = 0;
@@ -91,12 +94,12 @@ safe_read(const int fd, void * const buf_, size_t count)
assert(count > (size_t) 0U);
do {
while ((readnb = read(fd, buf, count)) < (ssize_t) 0 &&
- errno == EINTR);
+ errno == EINTR); /* LCOV_EXCL_LINE */
if (readnb < (ssize_t) 0) {
- return readnb;
+ return readnb; /* LCOV_EXCL_LINE */
}
if (readnb == (ssize_t) 0) {
- break;
+ break; /* LCOV_EXCL_LINE */
}
count -= (size_t) readnb;
buf += readnb;
@@ -110,6 +113,7 @@ safe_read(const int fd, void * const buf_, size_t count)
static int
randombytes_salsa20_random_random_dev_open(void)
{
+/* LCOV_EXCL_START */
struct stat st;
static const char *devices[] = {
# ifndef USE_BLOCKING_RANDOM
@@ -131,6 +135,7 @@ randombytes_salsa20_random_random_dev_open(void)
} while (*device != NULL);
return -1;
+/* LCOV_EXCL_STOP */
}
static void
@@ -143,7 +148,7 @@ randombytes_salsa20_random_init(void)
if ((stream.random_data_source_fd =
randombytes_salsa20_random_random_dev_open()) == -1) {
- abort();
+ abort(); /* LCOV_EXCL_LINE */
}
errno = errno_save;
}
@@ -181,11 +186,11 @@ randombytes_salsa20_random_stir(void)
#ifndef _WIN32
if (safe_read(stream.random_data_source_fd, m0,
sizeof m0) != (ssize_t) sizeof m0) {
- abort();
+ abort(); /* LCOV_EXCL_LINE */
}
#else /* _WIN32 */
if (! RtlGenRandom((PVOID) m0, (ULONG) sizeof m0)) {
- abort();
+ abort(); /* LCOV_EXCL_LINE */
}
#endif
COMPILER_ASSERT(sizeof stream.key == crypto_auth_hmacsha512256_BYTES);
@@ -214,14 +219,26 @@ randombytes_salsa20_random_stir_if_needed(void)
#endif
}
+static void
+randombytes_salsa20_random_rekey(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 uint32_t
randombytes_salsa20_random_getword(void)
{
uint32_t val;
int ret;
- COMPILER_ASSERT(sizeof stream.rnd32 >= sizeof val);
- COMPILER_ASSERT(sizeof stream.rnd32 % sizeof val == (size_t) 0U);
+ 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);
@@ -230,11 +247,13 @@ randombytes_salsa20_random_getword(void)
(unsigned char *) &stream.nonce,
stream.key);
assert(ret == 0);
+ stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key);
+ randombytes_salsa20_random_rekey(&stream.rnd32[stream.rnd32_outleft]);
stream.nonce++;
- stream.rnd32_outleft = sizeof stream.rnd32;
}
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;
}
@@ -278,10 +297,11 @@ randombytes_salsa20_random_buf(void * const buf, const size_t size)
assert(size <= ULONG_LONG_MAX);
#endif
ret = crypto_stream_salsa20((unsigned char *) buf, (unsigned long long) size,
- (unsigned char *) &stream.nonce,
- stream.key);
+ (unsigned char *) &stream.nonce, stream.key);
assert(ret == 0);
stream.nonce++;
+ crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key,
+ (unsigned char *) &stream.nonce, stream.key);
}
/*
@@ -304,7 +324,7 @@ randombytes_salsa20_random_uniform(const uint32_t upper_bound)
if (r >= min) {
break;
}
- }
+ } /* LCOV_EXCL_LINE */
return r % upper_bound;
}