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 | ||||||
|  |  | ||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem