Do not require /dev/urandom emulation in Javascript any more.

This commit is contained in:
Frank Denis 2015-01-17 21:42:50 +01:00
parent 201821065d
commit 9c0613525c
6 changed files with 92 additions and 40 deletions

View File

@ -1,6 +1,12 @@
lib_LTLIBRARIES = \
libsodium.la
if !EMSCRIPTEN
libsodium_la_SOURCES += \
randombytes/salsa20/randombytes_salsa20_random.c \
randombytes/sysrandom/randombytes_sysrandom.c
endif
libsodium_la_SOURCES = \
crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c \
crypto_auth/crypto_auth.c \
@ -149,8 +155,6 @@ libsodium_la_SOURCES = \
crypto_verify/64/ref/api.h \
crypto_verify/64/ref/verify_64.c \
randombytes/randombytes.c \
randombytes/salsa20/randombytes_salsa20_random.c \
randombytes/sysrandom/randombytes_sysrandom.c \
sodium/core.c \
sodium/runtime.c \
sodium/utils.c \

View File

@ -1,4 +1,8 @@
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
#endif
#include <sys/types.h>
#include <assert.h>
@ -8,8 +12,12 @@
#include "randombytes.h"
#include "randombytes_sysrandom.h"
#ifdef __EMSCRIPTEN__
static const randombytes_implementation *implementation = NULL;
#else
static const randombytes_implementation *implementation =
&randombytes_sysrandom_implementation;
#endif
int
randombytes_set_implementation(randombytes_implementation *impl)
@ -22,39 +30,105 @@ randombytes_set_implementation(randombytes_implementation *impl)
const char *
randombytes_implementation_name(void)
{
#ifdef __EMSCRIPTEN__
return "js";
#else
return implementation->implementation_name();
#endif
}
uint32_t
randombytes_random(void)
{
#ifdef __EMSCRIPTEN__
return EM_ASM_INT_V({
return Module.getRandomValue();
});
#else
return implementation->random();
#endif
}
void
randombytes_stir(void)
{
#ifdef __EMSCRIPTEN__
EM_ASM({
if (Module.getRandomValue === undefined) {
try {
var randomValuesStandard = function() {
var buf = new Uint16Array(1);
window.crypto.getRandomValues(buf);
return buf[0] >>> 0;
};
randomValuesStandard();
Module.getRandomValue = randomValuesStandard;
} catch (e) {
try {
var crypto = require('crypto');
var randomValueIOJS = function() {
var buf = crypto.randomBytes(2);
return (buf[0] << 8 | buf[1]) >>> 0;
};
randomValueIOJS();
Module.getRandomValue = randomValueIOJS;
} catch (e) {
throw 'No secure random number generator found';
}
}
}
});
#else
implementation->stir();
#endif
}
uint32_t
randombytes_uniform(const uint32_t upper_bound)
{
#ifdef __EMSCRIPTEN__
uint32_t min;
uint32_t r;
if (upper_bound < 2) {
return 0;
}
min = (uint32_t) (-upper_bound % upper_bound);
do {
r = randombytes_random();
} while (r < min);
return r % upper_bound;
#else
return implementation->uniform(upper_bound);
#endif
}
void
randombytes_buf(void * const buf, const size_t size)
{
#ifdef __EMSCRIPTEN__
unsigned char *p = buf;
size_t i;
for (i = (size_t) 0U; i < size; i++) {
p[i] = (unsigned char) randombytes_random();
}
#else
if (size > (size_t) 0U) {
implementation->buf(buf, size);
}
#endif
}
int
randombytes_close(void)
{
#ifdef __EMSCRIPTEN__
return 0;
#else
return implementation->close();
#endif
}
void

View File

@ -326,12 +326,10 @@ randombytes_salsa20_random_uniform(const uint32_t upper_bound)
return 0;
}
min = (uint32_t) (-upper_bound % upper_bound);
for (;;) {
do {
r = randombytes_salsa20_random();
if (r >= min) {
break;
}
} /* LCOV_EXCL_LINE */
} while (r < min); /* LCOV_EXCL_LINE */
return r % upper_bound;
}

View File

@ -241,10 +241,8 @@ randombytes_sysrandom_uniform(const uint32_t upper_bound)
min = (uint32_t) (-upper_bound % upper_bound);
for (;;) {
r = randombytes_sysrandom();
if (r >= min) {
break;
}
} /* LCOV_EXCL_LINE */
} while (r < min); /* LCOV_EXCL_LINE */
return r % upper_bound;
}

View File

@ -6,34 +6,7 @@ try {
}
Module['preRun'] = Module['preRun'] || [];
Module['preRun'].push(function(){
var randombyte = null;
try {
function randombyte_standard() {
var buf = new Int8Array(1);
window.crypto.getRandomValues(buf);
return buf[0];
}
randombyte_standard();
randombyte = randombyte_standard;
} catch (e) {
try {
var crypto = require('crypto');
function randombyte_node() {
return crypto.randomBytes(1)[0];
}
randombyte_node();
randombyte = randombyte_node;
} catch(e) {
throw 'No secure random number generator found';
}
}
FS.init();
FS.mkdir('/test-data');
FS.mount(NODEFS, { root: '.' }, '/test-data');
FS.analyzePath('/dev/random').exists && FS.unlink('/dev/random');
FS.analyzePath('/dev/urandom') && FS.unlink('/dev/urandom');
var devFolder = FS.findObject('/dev') ||
Module['FS_createFolder']('/', 'dev', true, true);
Module['FS_createDevice'](devFolder, 'random', randombyte);
Module['FS_createDevice'](devFolder, 'urandom', randombyte);
});

View File

@ -29,8 +29,11 @@ static int randombytes_tests(void)
{
unsigned int i;
assert(strcmp(randombytes_implementation_name(), "sysrandom") == 0);
#ifdef __EMSCRIPTEN__
assert(strcmp(randombytes_implementation_name(), "sysrandom"));
#else
assert(strcmp(randombytes_implementation_name(), "js"));
#endif
randombytes(x, 1U);
randombytes_close();
@ -47,8 +50,10 @@ static int randombytes_tests(void)
}
assert(randombytes_uniform(1U) == 0U);
randombytes_close();
#ifndef __EMSCRIPTEN__
randombytes_set_implementation(&randombytes_salsa20_implementation);
assert(strcmp(randombytes_implementation_name(), "salsa20") == 0);
#endif
randombytes_stir();
for (i = 0; i < 256; ++i) {
freq[i] = 0;