mirror of
https://github.com/golang/go
synced 2024-11-19 21:04:43 -07:00
crypto/rand for Windows
R=rsc, brainman CC=golang-dev https://golang.org/cl/1773041
This commit is contained in:
parent
c9f83372d8
commit
ccd28e8eb6
@ -9,4 +9,21 @@ TARG=crypto/rand
|
||||
GOFILES=\
|
||||
rand.go\
|
||||
|
||||
GOFILES_freebsd=\
|
||||
rand_unix.go\
|
||||
|
||||
GOFILES_darwin=\
|
||||
rand_unix.go\
|
||||
|
||||
GOFILES_linux=\
|
||||
rand_unix.go\
|
||||
|
||||
GOFILES_nacl=\
|
||||
rand_unix.go\
|
||||
|
||||
GOFILES_windows=\
|
||||
rand_windows.go\
|
||||
|
||||
GOFILES+=$(GOFILES_$(GOOS))
|
||||
|
||||
include ../../../Make.pkg
|
||||
|
@ -7,124 +7,15 @@
|
||||
package rand
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Reader is a global, shared instance of a cryptographically
|
||||
// strong pseudo-random generator.
|
||||
// On Unix-like systems, Reader reads from /dev/urandom.
|
||||
// On Windows systems, Reader uses the CryptGenRandom API.
|
||||
var Reader io.Reader
|
||||
|
||||
// Read is a helper function that calls Reader.Read.
|
||||
func Read(b []byte) (n int, err os.Error) { return Reader.Read(b) }
|
||||
|
||||
// Easy implementation: read from /dev/urandom.
|
||||
// This is sufficient on Linux, OS X, and FreeBSD.
|
||||
|
||||
func init() { Reader = &devReader{name: "/dev/urandom"} }
|
||||
|
||||
// A devReader satisfies reads by reading the file named name.
|
||||
type devReader struct {
|
||||
name string
|
||||
f *os.File
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (r *devReader) Read(b []byte) (n int, err os.Error) {
|
||||
r.mu.Lock()
|
||||
if r.f == nil {
|
||||
f, err := os.Open(r.name, os.O_RDONLY, 0)
|
||||
if f == nil {
|
||||
return 0, err
|
||||
}
|
||||
r.f = f
|
||||
}
|
||||
r.mu.Unlock()
|
||||
return r.f.Read(b)
|
||||
}
|
||||
|
||||
// Alternate pseudo-random implementation for use on
|
||||
// systems without a reliable /dev/urandom. So far we
|
||||
// haven't needed it.
|
||||
|
||||
// newReader returns a new pseudorandom generator that
|
||||
// seeds itself by reading from entropy. If entropy == nil,
|
||||
// the generator seeds itself by reading from the system's
|
||||
// random number generator, typically /dev/random.
|
||||
// The Read method on the returned reader always returns
|
||||
// the full amount asked for, or else it returns an error.
|
||||
//
|
||||
// The generator uses the X9.31 algorithm with AES-128,
|
||||
// reseeding after every 1 MB of generated data.
|
||||
func newReader(entropy io.Reader) io.Reader {
|
||||
if entropy == nil {
|
||||
entropy = &devReader{name: "/dev/random"}
|
||||
}
|
||||
return &reader{entropy: entropy}
|
||||
}
|
||||
|
||||
type reader struct {
|
||||
mu sync.Mutex
|
||||
budget int // number of bytes that can be generated
|
||||
cipher *aes.Cipher
|
||||
entropy io.Reader
|
||||
time, seed, dst, key [aes.BlockSize]byte
|
||||
}
|
||||
|
||||
func (r *reader) Read(b []byte) (n int, err os.Error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
n = len(b)
|
||||
|
||||
for len(b) > 0 {
|
||||
if r.budget == 0 {
|
||||
_, err := io.ReadFull(r.entropy, r.seed[0:])
|
||||
if err != nil {
|
||||
return n - len(b), err
|
||||
}
|
||||
_, err = io.ReadFull(r.entropy, r.key[0:])
|
||||
if err != nil {
|
||||
return n - len(b), err
|
||||
}
|
||||
r.cipher, err = aes.NewCipher(r.key[0:])
|
||||
if err != nil {
|
||||
return n - len(b), err
|
||||
}
|
||||
r.budget = 1 << 20 // reseed after generating 1MB
|
||||
}
|
||||
r.budget -= aes.BlockSize
|
||||
|
||||
// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
|
||||
//
|
||||
// single block:
|
||||
// t = encrypt(time)
|
||||
// dst = encrypt(t^seed)
|
||||
// seed = encrypt(t^dst)
|
||||
ns := time.Nanoseconds()
|
||||
r.time[0] = byte(ns >> 56)
|
||||
r.time[1] = byte(ns >> 48)
|
||||
r.time[2] = byte(ns >> 40)
|
||||
r.time[3] = byte(ns >> 32)
|
||||
r.time[4] = byte(ns >> 24)
|
||||
r.time[5] = byte(ns >> 16)
|
||||
r.time[6] = byte(ns >> 8)
|
||||
r.time[7] = byte(ns)
|
||||
r.cipher.Encrypt(r.time[0:], r.time[0:])
|
||||
for i := 0; i < aes.BlockSize; i++ {
|
||||
r.dst[i] = r.time[i] ^ r.seed[i]
|
||||
}
|
||||
r.cipher.Encrypt(r.dst[0:], r.dst[0:])
|
||||
for i := 0; i < aes.BlockSize; i++ {
|
||||
r.seed[i] = r.time[i] ^ r.dst[i]
|
||||
}
|
||||
r.cipher.Encrypt(r.seed[0:], r.seed[0:])
|
||||
|
||||
m := copy(b, r.dst[0:])
|
||||
b = b[m:]
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
124
src/pkg/crypto/rand/rand_unix.go
Normal file
124
src/pkg/crypto/rand/rand_unix.go
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Unix cryptographically secure pseudorandom number
|
||||
// generator.
|
||||
|
||||
package rand
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Easy implementation: read from /dev/urandom.
|
||||
// This is sufficient on Linux, OS X, and FreeBSD.
|
||||
|
||||
func init() { Reader = &devReader{name: "/dev/urandom"} }
|
||||
|
||||
// A devReader satisfies reads by reading the file named name.
|
||||
type devReader struct {
|
||||
name string
|
||||
f *os.File
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (r *devReader) Read(b []byte) (n int, err os.Error) {
|
||||
r.mu.Lock()
|
||||
if r.f == nil {
|
||||
f, err := os.Open(r.name, os.O_RDONLY, 0)
|
||||
if f == nil {
|
||||
return 0, err
|
||||
}
|
||||
r.f = f
|
||||
}
|
||||
r.mu.Unlock()
|
||||
return r.f.Read(b)
|
||||
}
|
||||
|
||||
// Alternate pseudo-random implementation for use on
|
||||
// systems without a reliable /dev/urandom. So far we
|
||||
// haven't needed it.
|
||||
|
||||
// newReader returns a new pseudorandom generator that
|
||||
// seeds itself by reading from entropy. If entropy == nil,
|
||||
// the generator seeds itself by reading from the system's
|
||||
// random number generator, typically /dev/random.
|
||||
// The Read method on the returned reader always returns
|
||||
// the full amount asked for, or else it returns an error.
|
||||
//
|
||||
// The generator uses the X9.31 algorithm with AES-128,
|
||||
// reseeding after every 1 MB of generated data.
|
||||
func newReader(entropy io.Reader) io.Reader {
|
||||
if entropy == nil {
|
||||
entropy = &devReader{name: "/dev/random"}
|
||||
}
|
||||
return &reader{entropy: entropy}
|
||||
}
|
||||
|
||||
type reader struct {
|
||||
mu sync.Mutex
|
||||
budget int // number of bytes that can be generated
|
||||
cipher *aes.Cipher
|
||||
entropy io.Reader
|
||||
time, seed, dst, key [aes.BlockSize]byte
|
||||
}
|
||||
|
||||
func (r *reader) Read(b []byte) (n int, err os.Error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
n = len(b)
|
||||
|
||||
for len(b) > 0 {
|
||||
if r.budget == 0 {
|
||||
_, err := io.ReadFull(r.entropy, r.seed[0:])
|
||||
if err != nil {
|
||||
return n - len(b), err
|
||||
}
|
||||
_, err = io.ReadFull(r.entropy, r.key[0:])
|
||||
if err != nil {
|
||||
return n - len(b), err
|
||||
}
|
||||
r.cipher, err = aes.NewCipher(r.key[0:])
|
||||
if err != nil {
|
||||
return n - len(b), err
|
||||
}
|
||||
r.budget = 1 << 20 // reseed after generating 1MB
|
||||
}
|
||||
r.budget -= aes.BlockSize
|
||||
|
||||
// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
|
||||
//
|
||||
// single block:
|
||||
// t = encrypt(time)
|
||||
// dst = encrypt(t^seed)
|
||||
// seed = encrypt(t^dst)
|
||||
ns := time.Nanoseconds()
|
||||
r.time[0] = byte(ns >> 56)
|
||||
r.time[1] = byte(ns >> 48)
|
||||
r.time[2] = byte(ns >> 40)
|
||||
r.time[3] = byte(ns >> 32)
|
||||
r.time[4] = byte(ns >> 24)
|
||||
r.time[5] = byte(ns >> 16)
|
||||
r.time[6] = byte(ns >> 8)
|
||||
r.time[7] = byte(ns)
|
||||
r.cipher.Encrypt(r.time[0:], r.time[0:])
|
||||
for i := 0; i < aes.BlockSize; i++ {
|
||||
r.dst[i] = r.time[i] ^ r.seed[i]
|
||||
}
|
||||
r.cipher.Encrypt(r.dst[0:], r.dst[0:])
|
||||
for i := 0; i < aes.BlockSize; i++ {
|
||||
r.seed[i] = r.time[i] ^ r.dst[i]
|
||||
}
|
||||
r.cipher.Encrypt(r.seed[0:], r.seed[0:])
|
||||
|
||||
m := copy(b, r.dst[0:])
|
||||
b = b[m:]
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
42
src/pkg/crypto/rand/rand_windows.go
Executable file
42
src/pkg/crypto/rand/rand_windows.go
Executable file
@ -0,0 +1,42 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Windows cryptographically secure pseudorandom number
|
||||
// generator.
|
||||
|
||||
package rand
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Implemented by using Windows CryptoAPI 2.0.
|
||||
|
||||
func init() { Reader = &rngReader{} }
|
||||
|
||||
// A rngReader satisfies reads by reading from the Windows CryptGenRandom API.
|
||||
type rngReader struct {
|
||||
prov uint32
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (r *rngReader) Read(b []byte) (n int, err os.Error) {
|
||||
r.mu.Lock()
|
||||
if r.prov == 0 {
|
||||
const provType = syscall.PROV_RSA_FULL
|
||||
const flags = syscall.CRYPT_VERIFYCONTEXT | syscall.CRYPT_SILENT
|
||||
ok, errno := syscall.CryptAcquireContext(&r.prov, nil, nil, provType, flags)
|
||||
if !ok {
|
||||
return 0, os.NewSyscallError("CryptAcquireContext", errno)
|
||||
}
|
||||
}
|
||||
r.mu.Unlock()
|
||||
ok, errno := syscall.CryptGenRandom(r.prov, uint32(len(b)), &b[0])
|
||||
if !ok {
|
||||
return 0, os.NewSyscallError("CryptGenRandom", errno)
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
@ -7,10 +7,10 @@ package rsa
|
||||
import (
|
||||
"big"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"io"
|
||||
"testing"
|
||||
"testing/quick"
|
||||
@ -63,10 +63,7 @@ func TestDecryptPKCS1v15(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEncryptPKCS1v15(t *testing.T) {
|
||||
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to open /dev/urandom")
|
||||
}
|
||||
random := rand.Reader
|
||||
k := (rsaPrivateKey.N.BitLen() + 7) / 8
|
||||
|
||||
tryEncryptDecrypt := func(in []byte, blind bool) bool {
|
||||
@ -74,7 +71,7 @@ func TestEncryptPKCS1v15(t *testing.T) {
|
||||
in = in[0 : k-11]
|
||||
}
|
||||
|
||||
ciphertext, err := EncryptPKCS1v15(urandom, &rsaPrivateKey.PublicKey, in)
|
||||
ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in)
|
||||
if err != nil {
|
||||
t.Errorf("error encrypting: %s", err)
|
||||
return false
|
||||
@ -84,7 +81,7 @@ func TestEncryptPKCS1v15(t *testing.T) {
|
||||
if !blind {
|
||||
rand = nil
|
||||
} else {
|
||||
rand = urandom
|
||||
rand = random
|
||||
}
|
||||
plaintext, err := DecryptPKCS1v15(rand, rsaPrivateKey, ciphertext)
|
||||
if err != nil {
|
||||
@ -137,13 +134,10 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNonZeroRandomBytes(t *testing.T) {
|
||||
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to open /dev/urandom")
|
||||
}
|
||||
random := rand.Reader
|
||||
|
||||
b := make([]byte, 512)
|
||||
err = nonZeroRandomBytes(b, urandom)
|
||||
err := nonZeroRandomBytes(b, random)
|
||||
if err != nil {
|
||||
t.Errorf("returned error: %s", err)
|
||||
}
|
||||
|
@ -7,18 +7,15 @@ package rsa
|
||||
import (
|
||||
"big"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestKeyGeneration(t *testing.T) {
|
||||
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Errorf("failed to open /dev/urandom")
|
||||
}
|
||||
random := rand.Reader
|
||||
|
||||
priv, err := GenerateKey(urandom, 1024)
|
||||
priv, err := GenerateKey(random, 1024)
|
||||
if err != nil {
|
||||
t.Errorf("failed to generate key")
|
||||
}
|
||||
@ -33,7 +30,7 @@ func TestKeyGeneration(t *testing.T) {
|
||||
t.Errorf("got:%v, want:%v (%s)", m2, m, priv)
|
||||
}
|
||||
|
||||
m3, err := decrypt(urandom, priv, c)
|
||||
m3, err := decrypt(random, priv, c)
|
||||
if err != nil {
|
||||
t.Errorf("error while decrypting (blind): %s", err)
|
||||
}
|
||||
@ -76,10 +73,7 @@ func TestEncryptOAEP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDecryptOAEP(t *testing.T) {
|
||||
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to open /dev/urandom")
|
||||
}
|
||||
random := rand.Reader
|
||||
|
||||
sha1 := sha1.New()
|
||||
n := new(big.Int)
|
||||
@ -98,7 +92,7 @@ func TestDecryptOAEP(t *testing.T) {
|
||||
}
|
||||
|
||||
// Decrypt with blinding.
|
||||
out, err = DecryptOAEP(sha1, urandom, &private, message.out, nil)
|
||||
out, err = DecryptOAEP(sha1, random, &private, message.out, nil)
|
||||
if err != nil {
|
||||
t.Errorf("#%d,%d (blind) error: %s", i, j, err)
|
||||
} else if bytes.Compare(out, message.in) != 0 {
|
||||
|
@ -6,10 +6,10 @@ package x509
|
||||
|
||||
import (
|
||||
"big"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@ -145,10 +145,7 @@ var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be13
|
||||
"36dcd585d6ace53f546f961e05af"
|
||||
|
||||
func TestCreateSelfSignedCertificate(t *testing.T) {
|
||||
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Errorf("failed to open /dev/urandom")
|
||||
}
|
||||
random := rand.Reader
|
||||
|
||||
block, _ := pem.Decode([]byte(pemPrivateKey))
|
||||
priv, err := ParsePKCS1PrivateKey(block.Bytes)
|
||||
@ -174,7 +171,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
|
||||
DNSNames: []string{"test.example.com"},
|
||||
}
|
||||
|
||||
derBytes, err := CreateCertificate(urandom, &template, &template, &priv.PublicKey, priv)
|
||||
derBytes, err := CreateCertificate(random, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create certificate: %s", err)
|
||||
return
|
||||
|
@ -132,6 +132,9 @@ func getSysProcAddr(m uint32, pname string) uintptr {
|
||||
//sys CreateIoCompletionPort(filehandle int32, cphandle int32, key uint32, threadcnt uint32) (handle int32, errno int)
|
||||
//sys GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (ok bool, errno int)
|
||||
//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, errno int) = GetTempPathW
|
||||
//sys CryptAcquireContext(provhandle *uint32, container *uint16, provider *uint16, provtype uint32, flags uint32) (ok bool, errno int) = advapi32.CryptAcquireContextW
|
||||
//sys CryptReleaseContext(provhandle uint32, flags uint32) (ok bool, errno int) = advapi32.CryptReleaseContext
|
||||
//sys CryptGenRandom(provhandle uint32, buflen uint32, buf *byte) (ok bool, errno int) = advapi32.CryptGenRandom
|
||||
|
||||
// syscall interface implementation for other packages
|
||||
|
||||
|
@ -7,6 +7,7 @@ import "unsafe"
|
||||
|
||||
var (
|
||||
modkernel32 = loadDll("kernel32.dll")
|
||||
modadvapi32 = loadDll("advapi32.dll")
|
||||
modwsock32 = loadDll("wsock32.dll")
|
||||
modws2_32 = loadDll("ws2_32.dll")
|
||||
|
||||
@ -41,6 +42,9 @@ var (
|
||||
procCreateIoCompletionPort = getSysProcAddr(modkernel32, "CreateIoCompletionPort")
|
||||
procGetQueuedCompletionStatus = getSysProcAddr(modkernel32, "GetQueuedCompletionStatus")
|
||||
procGetTempPathW = getSysProcAddr(modkernel32, "GetTempPathW")
|
||||
procCryptAcquireContextW = getSysProcAddr(modadvapi32, "CryptAcquireContextW")
|
||||
procCryptReleaseContext = getSysProcAddr(modadvapi32, "CryptReleaseContext")
|
||||
procCryptGenRandom = getSysProcAddr(modadvapi32, "CryptGenRandom")
|
||||
procWSAStartup = getSysProcAddr(modwsock32, "WSAStartup")
|
||||
procWSACleanup = getSysProcAddr(modwsock32, "WSACleanup")
|
||||
procsocket = getSysProcAddr(modwsock32, "socket")
|
||||
@ -387,6 +391,39 @@ func GetTempPath(buflen uint32, buf *uint16) (n uint32, errno int) {
|
||||
return
|
||||
}
|
||||
|
||||
func CryptAcquireContext(provhandle *uint32, container *uint16, provider *uint16, provtype uint32, flags uint32) (ok bool, errno int) {
|
||||
r0, _, e1 := Syscall6(procCryptAcquireContextW, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
|
||||
ok = bool(r0 != 0)
|
||||
if !ok {
|
||||
errno = int(e1)
|
||||
} else {
|
||||
errno = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CryptReleaseContext(provhandle uint32, flags uint32) (ok bool, errno int) {
|
||||
r0, _, e1 := Syscall(procCryptReleaseContext, uintptr(provhandle), uintptr(flags), 0)
|
||||
ok = bool(r0 != 0)
|
||||
if !ok {
|
||||
errno = int(e1)
|
||||
} else {
|
||||
errno = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CryptGenRandom(provhandle uint32, buflen uint32, buf *byte) (ok bool, errno int) {
|
||||
r0, _, e1 := Syscall(procCryptGenRandom, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
|
||||
ok = bool(r0 != 0)
|
||||
if !ok {
|
||||
errno = int(e1)
|
||||
} else {
|
||||
errno = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func WSAStartup(verreq uint32, data *WSAData) (sockerrno int) {
|
||||
r0, _, _ := Syscall(procWSAStartup, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
|
||||
sockerrno = int(r0)
|
||||
|
@ -88,6 +88,34 @@ const (
|
||||
WAIT_TIMEOUT = 258
|
||||
)
|
||||
|
||||
const (
|
||||
// wincrypt.h
|
||||
PROV_RSA_FULL = 1
|
||||
PROV_RSA_SIG = 2
|
||||
PROV_DSS = 3
|
||||
PROV_FORTEZZA = 4
|
||||
PROV_MS_EXCHANGE = 5
|
||||
PROV_SSL = 6
|
||||
PROV_RSA_SCHANNEL = 12
|
||||
PROV_DSS_DH = 13
|
||||
PROV_EC_ECDSA_SIG = 14
|
||||
PROV_EC_ECNRA_SIG = 15
|
||||
PROV_EC_ECDSA_FULL = 16
|
||||
PROV_EC_ECNRA_FULL = 17
|
||||
PROV_DH_SCHANNEL = 18
|
||||
PROV_SPYRUS_LYNKS = 20
|
||||
PROV_RNG = 21
|
||||
PROV_INTEL_SEC = 22
|
||||
PROV_REPLACE_OWF = 23
|
||||
PROV_RSA_AES = 24
|
||||
CRYPT_VERIFYCONTEXT = 0xF0000000
|
||||
CRYPT_NEWKEYSET = 0x00000008
|
||||
CRYPT_DELETEKEYSET = 0x00000010
|
||||
CRYPT_MACHINE_KEYSET = 0x00000020
|
||||
CRYPT_SILENT = 0x00000040
|
||||
CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
|
||||
)
|
||||
|
||||
// Types
|
||||
|
||||
type _C_short int16
|
||||
|
Loading…
Reference in New Issue
Block a user