From 59feac28b980fff18b0a058e5913bff801b4a293 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 10 Apr 2026 14:08:43 +0200 Subject: [PATCH] internal/syscall/unix: implement GetRandom for WASI targets Go 1.26's crypto/internal/sysrand uses internal/syscall/unix.GetRandom on Linux-like targets (including wasip2 which sets GOOS=linux). The existing stub panicked with 'todo: unix.GetRandom', causing crypto/ecdsa tests to fail on wasip2. Implement GetRandom on WASI targets (wasip1, wasip2) by calling the arc4random_buf libc function that TinyGo's runtime already provides. For other TinyGo targets, return ENOSYS so sysrand can fall back to /dev/urandom. --- src/internal/syscall/unix/getrandom.go | 8 ++++++- src/internal/syscall/unix/getrandom_wasi.go | 25 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/internal/syscall/unix/getrandom_wasi.go diff --git a/src/internal/syscall/unix/getrandom.go b/src/internal/syscall/unix/getrandom.go index 7ffab77e6..b2540b4a9 100644 --- a/src/internal/syscall/unix/getrandom.go +++ b/src/internal/syscall/unix/getrandom.go @@ -1,5 +1,9 @@ +//go:build !tinygo.wasm + package unix +import "syscall" + type GetRandomFlag uintptr const ( @@ -8,5 +12,7 @@ const ( ) func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { - panic("todo: unix.GetRandom") + // Not supported on most TinyGo targets. + // On real Linux the sysrand package will fall back to /dev/urandom. + return 0, syscall.ENOSYS } diff --git a/src/internal/syscall/unix/getrandom_wasi.go b/src/internal/syscall/unix/getrandom_wasi.go new file mode 100644 index 000000000..1aab2ab10 --- /dev/null +++ b/src/internal/syscall/unix/getrandom_wasi.go @@ -0,0 +1,25 @@ +//go:build tinygo.wasm + +package unix + +import "unsafe" + +type GetRandomFlag uintptr + +const ( + GRND_NONBLOCK GetRandomFlag = 0x0001 + GRND_RANDOM GetRandomFlag = 0x0002 +) + +func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + libc_arc4random_buf(unsafe.Pointer(&p[0]), uint(len(p))) + return len(p), nil +} + +// void arc4random_buf(void *buf, size_t buflen); +// +//export arc4random_buf +func libc_arc4random_buf(buf unsafe.Pointer, buflen uint)