aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/rand/rand_windows.go42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go
new file mode 100644
index 000000000..9a840c32d
--- /dev/null
+++ b/src/crypto/rand/rand_windows.go
@@ -0,0 +1,42 @@
+package rand
+
+import "errors"
+
+func init() {
+ Reader = &reader{}
+}
+
+type reader struct {
+}
+
+var errRandom = errors.New("failed to obtain random data from rand_s")
+
+func (r *reader) Read(b []byte) (n int, err error) {
+ if len(b) == 0 {
+ return
+ }
+
+ var randomByte uint32
+ for i := range b {
+ // Call rand_s every four bytes because it's a C int (always 32-bit in
+ // Windows).
+ if i%4 == 0 {
+ errCode := libc_rand_s(&randomByte)
+ if errCode != 0 {
+ // According to the documentation, it can return an error.
+ return n, errRandom
+ }
+ } else {
+ randomByte >>= 8
+ }
+ b[i] = byte(randomByte)
+ }
+
+ return len(b), nil
+}
+
+// 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