diff options
| author | Yawning Angel <yawning@schwanenlied.me> | 2025-11-29 09:18:11 +0900 |
|---|---|---|
| committer | Yawning Angel <yawning@schwanenlied.me> | 2025-11-29 10:45:53 +0900 |
| commit | e1ba69ea5192a245263b6a5ea5b4359cae7c0220 (patch) | |
| tree | 5d6b90e5ebe131495bf1b3cd5297a4c19df20790 /core/crypto | |
| parent | 0bd6410ea3b2b76eeafaa52c0fa626b4477190e2 (diff) | |
base/runtime: Add `rand_bytes` and `HAS_RAND_BYTES`
Having the OS/runtime provide a cryptographic entropy source is the
right thing to do, and we need it to initialize the default random
number generator.
Diffstat (limited to 'core/crypto')
| -rw-r--r-- | core/crypto/crypto.odin | 6 | ||||
| -rw-r--r-- | core/crypto/rand_bsd.odin | 15 | ||||
| -rw-r--r-- | core/crypto/rand_darwin.odin | 17 | ||||
| -rw-r--r-- | core/crypto/rand_generic.odin | 16 | ||||
| -rw-r--r-- | core/crypto/rand_js.odin | 24 | ||||
| -rw-r--r-- | core/crypto/rand_linux.odin | 40 | ||||
| -rw-r--r-- | core/crypto/rand_wasi.odin | 13 | ||||
| -rw-r--r-- | core/crypto/rand_windows.odin | 26 |
8 files changed, 5 insertions, 152 deletions
diff --git a/core/crypto/crypto.odin b/core/crypto/crypto.odin index 89e92e35f..7ccf126e6 100644 --- a/core/crypto/crypto.odin +++ b/core/crypto/crypto.odin @@ -4,6 +4,10 @@ package crypto import "base:runtime" import "core:mem" +// HAS_RAND_BYTES is true iff the runtime provides a cryptographic +// entropy source. +HAS_RAND_BYTES :: runtime.HAS_RAND_BYTES + // compare_constant_time returns 1 iff a and b are equal, 0 otherwise. // // The execution time of this routine is constant regardless of the contents @@ -54,7 +58,7 @@ rand_bytes :: proc (dst: []byte) { // zero-fill the buffer first mem.zero_explicit(raw_data(dst), len(dst)) - _rand_bytes(dst) + runtime.rand_bytes(dst) } // random_generator returns a `runtime.Random_Generator` backed by the diff --git a/core/crypto/rand_bsd.odin b/core/crypto/rand_bsd.odin deleted file mode 100644 index 78a6fcaaf..000000000 --- a/core/crypto/rand_bsd.odin +++ /dev/null @@ -1,15 +0,0 @@ -#+build freebsd, openbsd, netbsd -package crypto - -foreign import libc "system:c" - -HAS_RAND_BYTES :: true - -foreign libc { - arc4random_buf :: proc(buf: [^]byte, nbytes: uint) --- -} - -@(private) -_rand_bytes :: proc(dst: []byte) { - arc4random_buf(raw_data(dst), len(dst)) -} diff --git a/core/crypto/rand_darwin.odin b/core/crypto/rand_darwin.odin deleted file mode 100644 index df474bc4c..000000000 --- a/core/crypto/rand_darwin.odin +++ /dev/null @@ -1,17 +0,0 @@ -package crypto - -import "core:fmt" - -import CF "core:sys/darwin/CoreFoundation" -import Sec "core:sys/darwin/Security" - -HAS_RAND_BYTES :: true - -@(private) -_rand_bytes :: proc(dst: []byte) { - err := Sec.RandomCopyBytes(count=len(dst), bytes=raw_data(dst)) - if err != .Success { - msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err)) - fmt.panicf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg) - } -} diff --git a/core/crypto/rand_generic.odin b/core/crypto/rand_generic.odin deleted file mode 100644 index 8266f8ffc..000000000 --- a/core/crypto/rand_generic.odin +++ /dev/null @@ -1,16 +0,0 @@ -#+build !linux -#+build !windows -#+build !openbsd -#+build !freebsd -#+build !netbsd -#+build !darwin -#+build !js -#+build !wasi -package crypto - -HAS_RAND_BYTES :: false - -@(private) -_rand_bytes :: proc(dst: []byte) { - unimplemented("crypto: rand_bytes not supported on this OS") -} diff --git a/core/crypto/rand_js.odin b/core/crypto/rand_js.odin deleted file mode 100644 index 72093810e..000000000 --- a/core/crypto/rand_js.odin +++ /dev/null @@ -1,24 +0,0 @@ -package crypto - -foreign import "odin_env" -foreign odin_env { - @(link_name = "rand_bytes") - env_rand_bytes :: proc "contextless" (buf: []byte) --- -} - -HAS_RAND_BYTES :: true - -@(private) -_MAX_PER_CALL_BYTES :: 65536 // 64kiB - -@(private) -_rand_bytes :: proc(dst: []byte) { - dst := dst - - for len(dst) > 0 { - to_read := min(len(dst), _MAX_PER_CALL_BYTES) - env_rand_bytes(dst[:to_read]) - - dst = dst[to_read:] - } -} diff --git a/core/crypto/rand_linux.odin b/core/crypto/rand_linux.odin deleted file mode 100644 index 7e0edbb7e..000000000 --- a/core/crypto/rand_linux.odin +++ /dev/null @@ -1,40 +0,0 @@ -package crypto - -import "core:fmt" - -import "core:sys/linux" - -HAS_RAND_BYTES :: true - -@(private) -_MAX_PER_CALL_BYTES :: 33554431 // 2^25 - 1 - -@(private) -_rand_bytes :: proc (dst: []byte) { - dst := dst - l := len(dst) - - for l > 0 { - to_read := min(l, _MAX_PER_CALL_BYTES) - n_read, errno := linux.getrandom(dst[:to_read], {}) - #partial switch errno { - case .NONE: - // Do nothing - case .EINTR: - // Call interupted by a signal handler, just retry the - // request. - continue - case .ENOSYS: - // The kernel is apparently prehistoric (< 3.17 circa 2014) - // and does not support getrandom. - panic("crypto: getrandom not available in kernel") - case: - // All other failures are things that should NEVER happen - // unless the kernel interface changes (ie: the Linux - // developers break userland). - fmt.panicf("crypto: getrandom failed: %v", errno) - } - l -= n_read - dst = dst[n_read:] - } -} diff --git a/core/crypto/rand_wasi.odin b/core/crypto/rand_wasi.odin deleted file mode 100644 index 9653fb985..000000000 --- a/core/crypto/rand_wasi.odin +++ /dev/null @@ -1,13 +0,0 @@ -package crypto - -import "core:fmt" -import "core:sys/wasm/wasi" - -HAS_RAND_BYTES :: true - -@(private) -_rand_bytes :: proc(dst: []byte) { - if err := wasi.random_get(dst); err != nil { - fmt.panicf("crypto: wasi.random_get failed: %v", err) - } -} diff --git a/core/crypto/rand_windows.odin b/core/crypto/rand_windows.odin deleted file mode 100644 index 83a976e38..000000000 --- a/core/crypto/rand_windows.odin +++ /dev/null @@ -1,26 +0,0 @@ -package crypto - -import win32 "core:sys/windows" -import "core:os" -import "core:fmt" - -HAS_RAND_BYTES :: true - -@(private) -_rand_bytes :: proc(dst: []byte) { - ret := os.Platform_Error(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG)) - if ret != nil { - #partial switch ret { - case os.ERROR_INVALID_HANDLE: - // The handle to the first parameter is invalid. - // This should not happen here, since we explicitly pass nil to it - panic("crypto: BCryptGenRandom Invalid handle for hAlgorithm") - case os.ERROR_INVALID_PARAMETER: - // One of the parameters was invalid - panic("crypto: BCryptGenRandom Invalid parameter") - case: - // Unknown error - fmt.panicf("crypto: BCryptGenRandom failed: %d\n", ret) - } - } -} |