aboutsummaryrefslogtreecommitdiff
path: root/core/crypto
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2025-11-29 09:18:11 +0900
committerYawning Angel <yawning@schwanenlied.me>2025-11-29 10:45:53 +0900
commite1ba69ea5192a245263b6a5ea5b4359cae7c0220 (patch)
tree5d6b90e5ebe131495bf1b3cd5297a4c19df20790 /core/crypto
parent0bd6410ea3b2b76eeafaa52c0fa626b4477190e2 (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.odin6
-rw-r--r--core/crypto/rand_bsd.odin15
-rw-r--r--core/crypto/rand_darwin.odin17
-rw-r--r--core/crypto/rand_generic.odin16
-rw-r--r--core/crypto/rand_js.odin24
-rw-r--r--core/crypto/rand_linux.odin40
-rw-r--r--core/crypto/rand_wasi.odin13
-rw-r--r--core/crypto/rand_windows.odin26
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)
- }
- }
-}