github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/crypto/rand/rand_windows.go (about) 1 package rand 2 3 import "errors" 4 5 func init() { 6 Reader = &reader{} 7 } 8 9 type reader struct { 10 } 11 12 var errRandom = errors.New("failed to obtain random data from rand_s") 13 14 func (r *reader) Read(b []byte) (n int, err error) { 15 if len(b) == 0 { 16 return 17 } 18 19 var randomByte uint32 20 for i := range b { 21 // Call rand_s every four bytes because it's a C int (always 32-bit in 22 // Windows). 23 if i%4 == 0 { 24 errCode := libc_rand_s(&randomByte) 25 if errCode != 0 { 26 // According to the documentation, it can return an error. 27 return n, errRandom 28 } 29 } else { 30 randomByte >>= 8 31 } 32 b[i] = byte(randomByte) 33 } 34 35 return len(b), nil 36 } 37 38 // Cryptographically secure random number generator. 39 // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170 40 // errno_t rand_s(unsigned int* randomValue); 41 // 42 //export rand_s 43 func libc_rand_s(randomValue *uint32) int32