1 USING: accessors alien.c-types alien.data byte-arrays
2 combinators.short-circuit continuations destructors init kernel
3 locals namespaces random windows.advapi32 windows.errors
4 windows.kernel32 math.bitwise ;
7 TUPLE: windows-rng provider type ;
8 C: <windows-rng> windows-rng
10 TUPLE: windows-crypto-context handle ;
11 C: <windows-crypto-context> windows-crypto-context
13 M: windows-crypto-context dispose ( tuple -- )
14 handle>> 0 CryptReleaseContext win32-error=0/f ;
16 CONSTANT: factor-crypto-container "FactorCryptoContainer"
18 :: (acquire-crypto-context) ( provider type flags -- handle ret )
19 "HCRYPTPROV" <c-object> :> handle
21 factor-crypto-container
25 CryptAcquireContextW handle swap ;
27 : acquire-crypto-context ( provider type -- handle )
29 (acquire-crypto-context)
31 GetLastError NTE_BAD_KEYSET =
32 [ drop f ] [ win32-error-string throw ] if
37 : create-crypto-context ( provider type -- handle )
38 { CRYPT_MACHINE_KEYSET CRYPT_NEWKEYSET } flags
39 (acquire-crypto-context) win32-error=0/f *void* ;
41 ERROR: acquire-crypto-context-failed provider type ;
43 : attempt-crypto-context ( provider type -- handle )
45 [ acquire-crypto-context ]
46 [ create-crypto-context ]
47 [ acquire-crypto-context-failed ]
50 : windows-crypto-context ( provider type -- context )
51 attempt-crypto-context <windows-crypto-context> ;
53 M: windows-rng random-bytes* ( n tuple -- bytes )
55 [ provider>> ] [ type>> ] bi
56 windows-crypto-context &dispose
57 handle>> swap dup <byte-array>
58 [ CryptGenRandom win32-error=0/f ] keep
63 PROV_RSA_FULL <windows-rng> system-random-generator set-global
65 [ MS_STRONG_PROV PROV_RSA_FULL <windows-rng> ]
66 [ drop MS_ENH_RSA_AES_PROV PROV_RSA_AES <windows-rng> ] recover
67 secure-random-generator set-global
69 ] "random.windows" add-init-hook