From: Brendan Hansen Date: Sun, 14 May 2023 21:50:54 +0000 (-0500) Subject: changed: using cryptographic random number generation X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=16994f83411ac6f66d56341ab9c7326fd95d2d08;p=onyx.git changed: using cryptographic random number generation --- diff --git a/CHANGELOG b/CHANGELOG index 94cb8316..6e9c5f21 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,9 @@ Changes: * API for time remains the same, but reduced dependencies on external time things, like strftime, localtime and mktime. * Ergnomic improvements to `onyx pkg`. +* Not relying on time for random number seeding, if cryptographic random number generation is possible. + - Using `getrandom` on Linux, and `BcryptGenRandom` on Windows. + - Using `random_get` on WASI. Bugfixes: * Fixed missing `use core` in `optional.onyx`. diff --git a/core/random/random.onyx b/core/random/random.onyx index 400df811..c8bbe7d3 100644 --- a/core/random/random.onyx +++ b/core/random/random.onyx @@ -1,6 +1,7 @@ package core.random use core +use runtime #doc "The state of a random number generator." Random :: struct { @@ -116,10 +117,18 @@ string :: (bytes_long: u32, alpha_numeric := false, allocator := context.allocat RANDOM_MULTIPLIER :: 25214903917 RANDOM_INCREMENT :: cast(i64) 11 - #if #defined(core.os.time) { - __initial_value :: #(core.os.time()) + #if #defined(runtime.platform.__random_get) { + __initial_value :: #(do { + v: u64; + runtime.platform.__random_get(.{ ~~&v, sizeof typeof v }); + return v; + }) } else { - __initial_value :: #(8675309) + #if #defined(core.os.time) { + __initial_value :: #(core.os.time()) + } else { + __initial_value :: #(8675309) + } } } diff --git a/core/runtime/platform/onyx/platform.onyx b/core/runtime/platform/onyx/platform.onyx index 5936fcc4..5827d082 100644 --- a/core/runtime/platform/onyx/platform.onyx +++ b/core/runtime/platform/onyx/platform.onyx @@ -76,6 +76,7 @@ ProcessData :: #distinct u64 // Misc __file_get_standard :: (fd: i32, out: &FileData) -> bool --- + __random_get :: (buf: [] u8) -> void --- } __start :: () { diff --git a/core/runtime/platform/wasi/platform.onyx b/core/runtime/platform/wasi/platform.onyx index 9082bcf4..e11ddbe2 100644 --- a/core/runtime/platform/wasi/platform.onyx +++ b/core/runtime/platform/wasi/platform.onyx @@ -14,7 +14,8 @@ use wasi { poll_oneoff, fd_write, fd_datasync, fd_read, args_get, args_sizes_get, proc_exit, - clock_time_get, Timestamp + clock_time_get, Timestamp, + random_get, } use runtime { __runtime_initialize, @@ -91,6 +92,10 @@ __time :: () -> i64 { return time / 1000000; } +__random_get :: (buf: [] u8) { + random_get(buf.data, buf.length); +} + // Sets up everything needed for execution. __start :: () { diff --git a/runtime/onyx_runtime.c b/runtime/onyx_runtime.c index a85e9f6a..7f4b023d 100644 --- a/runtime/onyx_runtime.c +++ b/runtime/onyx_runtime.c @@ -70,6 +70,7 @@ ONYX_LIBRARY { ONYX_FUNC(__sleep) ONYX_FUNC(__time) ONYX_FUNC(__lookup_env) + ONYX_FUNC(__random_get) ONYX_FUNC(__register_cleanup) ONYX_FUNC(__net_create_socket) diff --git a/runtime/src/ort_os.h b/runtime/src/ort_os.h index bfc7c3ca..af5292cd 100644 --- a/runtime/src/ort_os.h +++ b/runtime/src/ort_os.h @@ -84,6 +84,20 @@ ONYX_DEF(__lookup_env, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { } +ONYX_DEF(__random_get, (WASM_PTR, WASM_I32), ()) { + #ifdef _BH_LINUX + getrandom(ONYX_PTR(params->data[0].of.i32), params->data[1].of.i32, 0); + #endif + + #ifdef _BH_WINDOWS + BCRYPT_ALG_HANDLE alg; + BCryptOpenAlgorithmProvider(&alg, L"SHA256", NULL, 0); + BCryptGenRandom(alg, ONYX_PTR(params->data[0].of.i32), params->data[1].of.i32, 0); + BCryptCloseAlgorithmProvider(alg, 0); + #endif + + return NULL; +} diff --git a/shared/include/onyx_library.h b/shared/include/onyx_library.h index 573de304..feb859dd 100644 --- a/shared/include/onyx_library.h +++ b/shared/include/onyx_library.h @@ -84,6 +84,8 @@ typedef struct WasmFuncDefinition { } \ struct WasmFuncDefinition *ONYX_MODULE_NAME_GEN(ONYX_LIBRARY_NAME)[] = +#define WASM_PTR WASM_I32 + // Shorter names #ifndef ONYX_NO_SHORT_NAMES #undef BOOL @@ -96,7 +98,7 @@ typedef struct WasmFuncDefinition { #define LONG WASM_I64 #define FLOAT WASM_F32 #define DOUBLE WASM_F64 -#define PTR WASM_I32 +#define PTR WASM_PTR #endif #define ONYX_PTR(p) ((void*) (p != 0 ? (runtime->wasm_memory_data(runtime->wasm_memory) + p) : NULL)) diff --git a/shared/include/small_windows.h b/shared/include/small_windows.h index 28cea0bd..93cc4bba 100644 --- a/shared/include/small_windows.h +++ b/shared/include/small_windows.h @@ -53,6 +53,7 @@ typedef HANDLE HGLOBAL; typedef HANDLE HLOCAL; typedef HANDLE GLOBALHANDLE; typedef HANDLE LOCALHANDLE; +typedef HANDLE BCRYPT_ALG_HANDLE; typedef void *HGDIOBJ; #define DECLARE_HANDLE(name) typedef HANDLE name @@ -442,3 +443,23 @@ GB_DLL_IMPORT short WINAPI htons(short hostshort); GB_DLL_IMPORT int WINAPI htonl(int hostint); GB_DLL_IMPORT short WINAPI ntohs(short netshort); GB_DLL_IMPORT int WINAPI ntohl(int netint); + + +GB_DLL_IMPORT NTSTATUS BCryptGenRandom( + BCRYPT_ALG_HANDLE hAlgorithm, + unsigned char * pbBuffer, + unsigned long cbBuffer, + unsigned long wFlags +); + +GB_DLL_IMPORT NTSTATUS BCryptOpenAlgorithmProvider( + BCRYPT_ALG_HANDLE *phAlgorithm, + const wchar_t * pszAlgId, + const wchar_t * pszImplementation, + unsigned long dwFlags +); + +GB_DLL_IMPORT NTSTATUS BCryptCloseAlgorithmProvider( + BCRYPT_ALG_HANDLE hAlgorithm, + unsigned long dwFlags +);