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 8package rand 9 10import ( 11 "os" 12 "sync" 13 "syscall" 14) 15 16// Implemented by using Windows CryptoAPI 2.0. 17 18func init() { Reader = &rngReader{} } 19 20// A rngReader satisfies reads by reading from the Windows CryptGenRandom API. 21type rngReader struct { 22 prov syscall.Handle 23 mu sync.Mutex 24} 25 26func (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} 48