diff --git a/src/library.js b/src/library.js index d7de58ebc763f..78368ba2b2d7d 100644 --- a/src/library.js +++ b/src/library.js @@ -1292,65 +1292,6 @@ addToLibrary({ #endif // PROXY_POSIX_SOCKETS == 0 - // random.h - - $initRandomFill: () => { - if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') { - // for modern web browsers -#if SHARED_MEMORY - // like with most Web APIs, we can't use Web Crypto API directly on shared memory, - // so we need to create an intermediate buffer and copy it to the destination - return (view) => ( - view.set(crypto.getRandomValues(new Uint8Array(view.byteLength))), - // Return the original view to match modern native implementations. - view - ); -#else - return (view) => crypto.getRandomValues(view); -#endif - } else -#if ENVIRONMENT_MAY_BE_NODE - if (ENVIRONMENT_IS_NODE) { - // for nodejs with or without crypto support included - try { - var crypto_module = require('crypto'); - var randomFillSync = crypto_module['randomFillSync']; - if (randomFillSync) { - // nodejs with LTS crypto support - return (view) => crypto_module['randomFillSync'](view); - } - // very old nodejs with the original crypto API - var randomBytes = crypto_module['randomBytes']; - return (view) => ( - view.set(randomBytes(view.byteLength)), - // Return the original view to match modern native implementations. - view - ); - } catch (e) { - // nodejs doesn't have crypto support - } - } -#endif // ENVIRONMENT_MAY_BE_NODE - // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096 -#if ASSERTIONS - abort('no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };'); -#else - abort('initRandomDevice'); -#endif - }, - - $randomFill__deps: ['$initRandomFill'], - $randomFill: (view) => { - // Lazily init on the first invocation. - return (randomFill = initRandomFill())(view); - }, - - getentropy__deps: ['$randomFill'], - getentropy: (buffer, size) => { - randomFill(HEAPU8.subarray(buffer, buffer + size)); - return 0; - }, - $timers: {}, // Helper function for setitimer that registers timers with the eventloop. diff --git a/src/library_sigs.js b/src/library_sigs.js index bf90eec02153b..33dda2c63ae02 100644 --- a/src/library_sigs.js +++ b/src/library_sigs.js @@ -972,7 +972,6 @@ sigs = { filledEllipseColor__sig: 'ipiiiii', filledEllipseRGBA__sig: 'ipiiiiiiii', getaddrinfo__sig: 'ipppp', - getentropy__sig: 'ipp', getnameinfo__sig: 'ipipipii', getprotobyname__sig: 'pp', getprotobynumber__sig: 'pi', diff --git a/src/library_wasi.js b/src/library_wasi.js index f75458f20ce3c..63a202eb52a39 100644 --- a/src/library_wasi.js +++ b/src/library_wasi.js @@ -41,12 +41,6 @@ var WasiLibrary = { sched_yield__nothrow: true, sched_yield: () => 0, - random_get__deps: ['getentropy'], - random_get: (buf, buf_len) => { - _getentropy(buf, buf_len); - return 0; - }, - $getEnvStrings__deps: ['$ENV', '$getExecutableName'], $getEnvStrings: () => { if (!getEnvStrings.strings) { @@ -568,6 +562,66 @@ var WasiLibrary = { #endif // SYSCALLS_REQUIRE_FILESYSTEM }, fd_sync__async: true, + + // random.h + + $initRandomFill: () => { + if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') { + // for modern web browsers +#if SHARED_MEMORY + // like with most Web APIs, we can't use Web Crypto API directly on shared memory, + // so we need to create an intermediate buffer and copy it to the destination + return (view) => ( + view.set(crypto.getRandomValues(new Uint8Array(view.byteLength))), + // Return the original view to match modern native implementations. + view + ); +#else + return (view) => crypto.getRandomValues(view); +#endif + } else +#if ENVIRONMENT_MAY_BE_NODE + if (ENVIRONMENT_IS_NODE) { + // for nodejs with or without crypto support included + try { + var crypto_module = require('crypto'); + var randomFillSync = crypto_module['randomFillSync']; + if (randomFillSync) { + // nodejs with LTS crypto support + return (view) => crypto_module['randomFillSync'](view); + } + // very old nodejs with the original crypto API + var randomBytes = crypto_module['randomBytes']; + return (view) => ( + view.set(randomBytes(view.byteLength)), + // Return the original view to match modern native implementations. + view + ); + } catch (e) { + // nodejs doesn't have crypto support + } + } +#endif // ENVIRONMENT_MAY_BE_NODE + // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096 +#if ASSERTIONS + abort('no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };'); +#else + abort('initRandomDevice'); +#endif + }, + + $randomFill__deps: ['$initRandomFill'], + $randomFill: (view) => { + // Lazily init on the first invocation. + return (randomFill = initRandomFill())(view); + }, + + random_get__proxy: 'none', + random_get__deps: ['$randomFill'], + random_get: (buffer, size) => { + randomFill(HEAPU8.subarray(buffer, buffer + size)); + return 0; + }, }; for (var x in WasiLibrary) { diff --git a/system/lib/libc/musl/src/misc/getentropy.c b/system/lib/libc/musl/src/misc/getentropy.c index 651ea95f14310..f5204186fca42 100644 --- a/system/lib/libc/musl/src/misc/getentropy.c +++ b/system/lib/libc/musl/src/misc/getentropy.c @@ -4,6 +4,10 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif + int getentropy(void *buffer, size_t len) { int cs, ret = 0; @@ -16,6 +20,9 @@ int getentropy(void *buffer, size_t len) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); +#ifdef __EMSCRIPTEN__ + ret = __wasi_syscall_ret(__wasi_random_get(buffer, len)); +#else while (len) { ret = getrandom(pos, len, 0); if (ret < 0) { @@ -26,6 +33,7 @@ int getentropy(void *buffer, size_t len) len -= ret; ret = 0; } +#endif pthread_setcancelstate(cs, 0); diff --git a/system/lib/standalone/standalone.c b/system/lib/standalone/standalone.c index 14936ea97dd61..52c3eb3360b36 100644 --- a/system/lib/standalone/standalone.c +++ b/system/lib/standalone/standalone.c @@ -136,12 +136,6 @@ weak int __syscall_lstat64(intptr_t path, intptr_t buf) { return -ENOSYS; } -// There is no good source of entropy without an import. Make this weak so that -// it can be replaced with a pRNG or a proper import. -weak int getentropy(void* buffer, size_t length) { - abort(); -} - // Emscripten additions size_t emscripten_get_heap_max() { diff --git a/test/other/codesize/test_codesize_cxx_wasmfs.gzsize b/test/other/codesize/test_codesize_cxx_wasmfs.gzsize index 1ffa5bc74e2d3..4a45c385de208 100644 --- a/test/other/codesize/test_codesize_cxx_wasmfs.gzsize +++ b/test/other/codesize/test_codesize_cxx_wasmfs.gzsize @@ -1 +1 @@ -3899 +3895 diff --git a/test/other/codesize/test_codesize_cxx_wasmfs.imports b/test/other/codesize/test_codesize_cxx_wasmfs.imports index 9e4e6b57b143b..04f0a4519e9fc 100644 --- a/test/other/codesize/test_codesize_cxx_wasmfs.imports +++ b/test/other/codesize/test_codesize_cxx_wasmfs.imports @@ -15,6 +15,6 @@ env.emscripten_date_now env.emscripten_err env.emscripten_out env.emscripten_resize_heap -env.getentropy wasi_snapshot_preview1.environ_get wasi_snapshot_preview1.environ_sizes_get +wasi_snapshot_preview1.random_get diff --git a/test/other/codesize/test_codesize_cxx_wasmfs.sent b/test/other/codesize/test_codesize_cxx_wasmfs.sent index 41cae8170634f..a0049ced118ca 100644 --- a/test/other/codesize/test_codesize_cxx_wasmfs.sent +++ b/test/other/codesize/test_codesize_cxx_wasmfs.sent @@ -17,4 +17,4 @@ emscripten_out emscripten_resize_heap environ_get environ_sizes_get -getentropy +random_get diff --git a/test/other/codesize/test_codesize_cxx_wasmfs.size b/test/other/codesize/test_codesize_cxx_wasmfs.size index aedf1b264e9ac..211ccd7532d49 100644 --- a/test/other/codesize/test_codesize_cxx_wasmfs.size +++ b/test/other/codesize/test_codesize_cxx_wasmfs.size @@ -1 +1 @@ -169486 +169554 diff --git a/test/other/codesize/test_codesize_files_wasmfs.gzsize b/test/other/codesize/test_codesize_files_wasmfs.gzsize index 96fd0f9dd03d9..47f06d4699cd1 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.gzsize +++ b/test/other/codesize/test_codesize_files_wasmfs.gzsize @@ -1 +1 @@ -2987 +2856 diff --git a/test/other/codesize/test_codesize_files_wasmfs.imports b/test/other/codesize/test_codesize_files_wasmfs.imports index 741d799597712..74ec884c2cde4 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.imports +++ b/test/other/codesize/test_codesize_files_wasmfs.imports @@ -1,16 +1,16 @@ a (emscripten_date_now) b (emscripten_err) -c (getentropy) -d (emscripten_resize_heap) -e (emscripten_out) -f (_wasmfs_stdin_get_char) -g (_wasmfs_get_preloaded_path_name) -h (_wasmfs_get_preloaded_parent_path) -i (_wasmfs_get_preloaded_file_size) -j (_wasmfs_get_preloaded_file_mode) -k (_wasmfs_get_preloaded_child_path) -l (_wasmfs_get_num_preloaded_files) -m (_wasmfs_get_num_preloaded_dirs) -n (_wasmfs_copy_preloaded_file_data) -o (_emscripten_memcpy_js) -p (_abort_js) +c (emscripten_resize_heap) +d (emscripten_out) +e (_wasmfs_stdin_get_char) +f (_wasmfs_get_preloaded_path_name) +g (_wasmfs_get_preloaded_parent_path) +h (_wasmfs_get_preloaded_file_size) +i (_wasmfs_get_preloaded_file_mode) +j (_wasmfs_get_preloaded_child_path) +k (_wasmfs_get_num_preloaded_files) +l (_wasmfs_get_num_preloaded_dirs) +m (_wasmfs_copy_preloaded_file_data) +n (_emscripten_memcpy_js) +o (_abort_js) +p (random_get) diff --git a/test/other/codesize/test_codesize_files_wasmfs.jssize b/test/other/codesize/test_codesize_files_wasmfs.jssize index 41fb47a7ed833..c840ab82f2352 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.jssize +++ b/test/other/codesize/test_codesize_files_wasmfs.jssize @@ -1 +1 @@ -6329 +5982 diff --git a/test/other/codesize/test_codesize_files_wasmfs.sent b/test/other/codesize/test_codesize_files_wasmfs.sent index 741d799597712..8c8815f7abc7a 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.sent +++ b/test/other/codesize/test_codesize_files_wasmfs.sent @@ -1,16 +1,15 @@ a (emscripten_date_now) b (emscripten_err) -c (getentropy) -d (emscripten_resize_heap) -e (emscripten_out) -f (_wasmfs_stdin_get_char) -g (_wasmfs_get_preloaded_path_name) -h (_wasmfs_get_preloaded_parent_path) -i (_wasmfs_get_preloaded_file_size) -j (_wasmfs_get_preloaded_file_mode) -k (_wasmfs_get_preloaded_child_path) -l (_wasmfs_get_num_preloaded_files) -m (_wasmfs_get_num_preloaded_dirs) -n (_wasmfs_copy_preloaded_file_data) -o (_emscripten_memcpy_js) -p (_abort_js) +c (emscripten_resize_heap) +d (emscripten_out) +e (_wasmfs_stdin_get_char) +f (_wasmfs_get_preloaded_path_name) +g (_wasmfs_get_preloaded_parent_path) +h (_wasmfs_get_preloaded_file_size) +i (_wasmfs_get_preloaded_file_mode) +j (_wasmfs_get_preloaded_child_path) +k (_wasmfs_get_num_preloaded_files) +l (_wasmfs_get_num_preloaded_dirs) +m (_wasmfs_copy_preloaded_file_data) +n (_emscripten_memcpy_js) +o (_abort_js) diff --git a/test/other/codesize/test_codesize_files_wasmfs.size b/test/other/codesize/test_codesize_files_wasmfs.size index 16020a6037c63..8dbc1b508195f 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.size +++ b/test/other/codesize/test_codesize_files_wasmfs.size @@ -1 +1 @@ -51099 +51157 diff --git a/test/other/codesize/test_codesize_minimal_O0.gzsize b/test/other/codesize/test_codesize_minimal_O0.gzsize index 88f43e582800d..3a5c1c66c27aa 100644 --- a/test/other/codesize/test_codesize_minimal_O0.gzsize +++ b/test/other/codesize/test_codesize_minimal_O0.gzsize @@ -1 +1 @@ -6576 +6577 diff --git a/tools/building.py b/tools/building.py index 5559b7c170603..12aa33689c17d 100644 --- a/tools/building.py +++ b/tools/building.py @@ -807,6 +807,7 @@ def metadce(js_file, wasm_file, debug_info, last): 'clock_res_get', 'clock_time_get', 'path_open', + 'random_get', } for item in graph: if 'import' in item and item['import'][1] in WASI_IMPORTS: diff --git a/tools/system_libs.py b/tools/system_libs.py index 41ac4ff590d7f..3d1efbe5e870d 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -1098,7 +1098,6 @@ def get_files(self): 'ppoll.c', 'syscall.c', 'popen.c', 'pclose.c', 'getgrouplist.c', 'initgroups.c', 'wordexp.c', 'timer_create.c', - 'getentropy.c', 'getauxval.c', 'lookup_name.c', # 'process' exclusion