github.com/insolar/x-crypto@v0.0.0-20191031140942-75fab8a325f6/rand/rand_windows.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Windows cryptographically secure pseudorandom number 6 // generator. 7 8 package rand 9 10 import ( 11 "os" 12 "sync" 13 "syscall" 14 ) 15 16 // Implemented by using Windows CryptoAPI 2.0. 17 18 func init() { Reader = &rngReader{} } 19 20 // A rngReader satisfies reads by reading from the Windows CryptGenRandom API. 21 type rngReader struct { 22 prov syscall.Handle 23 mu sync.Mutex 24 } 25 26 func (r *rngReader) Read(b []byte) (n int, err error) { 27 r.mu.Lock() 28 if r.prov == 0 { 29 const provType = syscall.PROV_RSA_FULL 30 const flags = syscall.CRYPT_VERIFYCONTEXT | syscall.CRYPT_SILENT 31 err := syscall.CryptAcquireContext(&r.prov, nil, nil, provType, flags) 32 if err != nil { 33 r.mu.Unlock() 34 return 0, os.NewSyscallError("CryptAcquireContext", err) 35 } 36 } 37 r.mu.Unlock() 38 39 if len(b) == 0 { 40 return 0, nil 41 } 42 err = syscall.CryptGenRandom(r.prov, uint32(len(b)), &b[0]) 43 if err != nil { 44 return 0, os.NewSyscallError("CryptGenRandom", err) 45 } 46 return len(b), nil 47 }