runtime: add runtime.rand function
This function is needed for Go 1.22, and is used from various packages like math/rand. When there is no random number generator available, it falls back to a static sequence of numbers. I think this is fine, because as far as I can see it is only used for non-cryptographic needs.
Этот коммит содержится в:
родитель
204659bdcd
коммит
e9003e2deb
11 изменённых файлов: 102 добавлений и 1 удалений
|
@ -838,6 +838,7 @@ endif
|
||||||
@cp -rp lib/musl/src/include build/release/tinygo/lib/musl/src
|
@cp -rp lib/musl/src/include build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src
|
@cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/legacy build/release/tinygo/lib/musl/src
|
@cp -rp lib/musl/src/legacy build/release/tinygo/lib/musl/src
|
||||||
|
@cp -rp lib/musl/src/linux build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src
|
@cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src
|
@cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
|
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
|
||||||
|
|
|
@ -119,6 +119,7 @@ var Musl = Library{
|
||||||
"internal/syscall_ret.c",
|
"internal/syscall_ret.c",
|
||||||
"internal/vdso.c",
|
"internal/vdso.c",
|
||||||
"legacy/*.c",
|
"legacy/*.c",
|
||||||
|
"linux/*.c",
|
||||||
"malloc/*.c",
|
"malloc/*.c",
|
||||||
"malloc/mallocng/*.c",
|
"malloc/mallocng/*.c",
|
||||||
"mman/*.c",
|
"mman/*.c",
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
//go:build nrf || stm32 || (sam && atsamd51) || (sam && atsame5x) || esp32c3
|
//go:build nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3
|
||||||
|
|
||||||
|
// If you update the above build constraint, you'll probably also need to update
|
||||||
|
// src/runtime/rand_hwrng.go.
|
||||||
|
|
||||||
package rand
|
package rand
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ func rand_fastrand64() uint64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is used by hash/maphash.
|
// This function is used by hash/maphash.
|
||||||
|
// This function isn't required anymore since Go 1.22, so should be removed once
|
||||||
|
// that becomes the minimum requirement.
|
||||||
func fastrand() uint32 {
|
func fastrand() uint32 {
|
||||||
xorshift32State = xorshift32(xorshift32State)
|
xorshift32State = xorshift32(xorshift32State)
|
||||||
return xorshift32State
|
return xorshift32State
|
||||||
|
@ -34,6 +36,8 @@ func xorshift32(x uint32) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is used by hash/maphash.
|
// This function is used by hash/maphash.
|
||||||
|
// This function isn't required anymore since Go 1.22, so should be removed once
|
||||||
|
// that becomes the minimum requirement.
|
||||||
func fastrand64() uint64 {
|
func fastrand64() uint64 {
|
||||||
xorshift64State = xorshiftMult64(xorshift64State)
|
xorshift64State = xorshiftMult64(xorshift64State)
|
||||||
return xorshift64State
|
return xorshift64State
|
||||||
|
@ -56,3 +60,16 @@ func memhash(p unsafe.Pointer, seed, s uintptr) uintptr {
|
||||||
}
|
}
|
||||||
return uintptr(hash32(p, s, seed))
|
return uintptr(hash32(p, s, seed))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function that's called from various packages starting with Go 1.22.
|
||||||
|
func rand() uint64 {
|
||||||
|
// Return a random number from hardware, falling back to software if
|
||||||
|
// unavailable.
|
||||||
|
n, ok := hardwareRand()
|
||||||
|
if !ok {
|
||||||
|
// Fallback to static random number.
|
||||||
|
// Not great, but we can't do much better than this.
|
||||||
|
n = fastrand64()
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
|
@ -112,3 +112,14 @@ func findGlobals(found func(start, end uintptr)) {
|
||||||
cmd = (*segmentLoadCommand)(unsafe.Add(unsafe.Pointer(cmd), cmd.cmdsize))
|
cmd = (*segmentLoadCommand)(unsafe.Add(unsafe.Pointer(cmd), cmd.cmdsize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
n |= uint64(libc_arc4random())
|
||||||
|
n |= uint64(libc_arc4random()) << 32
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// uint32_t arc4random(void);
|
||||||
|
//
|
||||||
|
//export arc4random
|
||||||
|
func libc_arc4random() uint32
|
||||||
|
|
|
@ -120,3 +120,16 @@ func libc_getpagesize() int
|
||||||
func syscall_Getpagesize() int {
|
func syscall_Getpagesize() int {
|
||||||
return libc_getpagesize()
|
return libc_getpagesize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
read := libc_getrandom(unsafe.Pointer(&n), 8, 0)
|
||||||
|
if read != 8 {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ssize_t getrandom(void buf[.buflen], size_t buflen, unsigned int flags);
|
||||||
|
//
|
||||||
|
//export getrandom
|
||||||
|
func libc_getrandom(buf unsafe.Pointer, buflen uintptr, flags uint32) uint32
|
||||||
|
|
16
src/runtime/rand_hwrng.go
Обычный файл
16
src/runtime/rand_hwrng.go
Обычный файл
|
@ -0,0 +1,16 @@
|
||||||
|
//go:build baremetal && (nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3)
|
||||||
|
|
||||||
|
// If you update the above build constraint, you'll probably also need to update
|
||||||
|
// src/crypto/rand/rand_baremetal.go.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import "machine"
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
n1, err1 := machine.GetRNG()
|
||||||
|
n2, err2 := machine.GetRNG()
|
||||||
|
n = uint64(n1)<<32 | uint64(n2)
|
||||||
|
ok = err1 == nil && err2 == nil
|
||||||
|
return
|
||||||
|
}
|
7
src/runtime/rand_norng.go
Обычный файл
7
src/runtime/rand_norng.go
Обычный файл
|
@ -0,0 +1,7 @@
|
||||||
|
//go:build baremetal && !(nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3)
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
return 0, false // no RNG available
|
||||||
|
}
|
|
@ -308,3 +308,8 @@ func svcOutputDebugString(str *uint8, size uint64) uint64
|
||||||
//
|
//
|
||||||
//export svcGetInfo
|
//export svcGetInfo
|
||||||
func svcGetInfo(output *uint64, id0 uint32, handle uint32, id1 uint64) uint64
|
func svcGetInfo(output *uint64, id0 uint32, handle uint32, id1 uint64) uint64
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
// TODO: see whether there is a RNG and use it.
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
|
@ -85,3 +85,14 @@ func procPin() {
|
||||||
//go:linkname procUnpin sync/atomic.runtime_procUnpin
|
//go:linkname procUnpin sync/atomic.runtime_procUnpin
|
||||||
func procUnpin() {
|
func procUnpin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
n |= uint64(libc_arc4random())
|
||||||
|
n |= uint64(libc_arc4random()) << 32
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// uint32_t arc4random(void);
|
||||||
|
//
|
||||||
|
//export arc4random
|
||||||
|
func libc_arc4random() uint32
|
||||||
|
|
|
@ -228,3 +228,19 @@ func procPin() {
|
||||||
//go:linkname procUnpin sync/atomic.runtime_procUnpin
|
//go:linkname procUnpin sync/atomic.runtime_procUnpin
|
||||||
func procUnpin() {
|
func procUnpin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
|
var n1, n2 uint32
|
||||||
|
errCode1 := libc_rand_s(&n1)
|
||||||
|
errCode2 := libc_rand_s(&n2)
|
||||||
|
n = uint64(n1)<<32 | uint64(n2)
|
||||||
|
ok = errCode1 == 0 && errCode2 == 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cryptographically secure random number generator.
|
||||||
|
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170
|
||||||
|
// errno_t rand_s(unsigned int* randomValue);
|
||||||
|
//
|
||||||
|
//export rand_s
|
||||||
|
func libc_rand_s(randomValue *uint32) int32
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче