|
14 | 14 |
|
15 | 15 | #include <openssl/rand.h>
|
16 | 16 |
|
17 |
| -#include <openssl/thread.h> |
18 |
| - |
19 |
| - |
20 | 17 | #if defined(OPENSSL_WINDOWS)
|
21 | 18 |
|
| 19 | +#include <limits.h> |
22 | 20 | #include <stdlib.h>
|
23 | 21 | #include <Windows.h>
|
24 |
| -#include <Wincrypt.h> |
25 | 22 |
|
26 |
| -static char global_provider_init; |
27 |
| -static HCRYPTPROV global_provider; |
| 23 | +/* #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the |
| 24 | + * "Community Additions" comment on MSDN here: |
| 25 | + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */ |
| 26 | +#define SystemFunction036 NTAPI SystemFunction036 |
| 27 | +#include <NTSecAPI.h> |
| 28 | +#undef SystemFunction036 |
| 29 | + |
28 | 30 |
|
29 | 31 | void RAND_cleanup(void) {
|
30 |
| - CRYPTO_w_lock(CRYPTO_LOCK_RAND); |
31 |
| - CryptReleaseContext(global_provider, 0); |
32 |
| - global_provider_init = 0; |
33 |
| - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); |
34 | 32 | }
|
35 | 33 |
|
36 | 34 | int RAND_bytes(uint8_t *out, size_t requested) {
|
37 |
| - HCRYPTPROV provider = 0; |
38 |
| - int ok; |
39 |
| - |
40 |
| - CRYPTO_r_lock(CRYPTO_LOCK_RAND); |
41 |
| - if (!global_provider_init) { |
42 |
| - CRYPTO_r_unlock(CRYPTO_LOCK_RAND); |
43 |
| - CRYPTO_w_lock(CRYPTO_LOCK_RAND); |
44 |
| - if (!global_provider_init) { |
45 |
| - if (CryptAcquireContext(&global_provider, NULL, NULL, PROV_RSA_FULL, |
46 |
| - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { |
47 |
| - global_provider_init = 1; |
48 |
| - } |
| 35 | + while (requested > 0) { |
| 36 | + ULONG output_bytes_this_pass = ULONG_MAX; |
| 37 | + if (requested < output_bytes_this_pass) { |
| 38 | + output_bytes_this_pass = requested; |
49 | 39 | }
|
50 |
| - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); |
51 |
| - CRYPTO_r_lock(CRYPTO_LOCK_RAND); |
52 |
| - } |
53 |
| - |
54 |
| - ok = global_provider_init; |
55 |
| - provider = global_provider; |
56 |
| - CRYPTO_r_unlock(CRYPTO_LOCK_RAND); |
57 |
| - |
58 |
| - if (!ok) { |
59 |
| - abort(); |
60 |
| - return ok; |
61 |
| - } |
62 |
| - |
63 |
| - if (TRUE != CryptGenRandom(provider, requested, out)) { |
64 |
| - abort(); |
65 |
| - return 0; |
| 40 | + if (RtlGenRandom(out, output_bytes_this_pass) == FALSE) { |
| 41 | + abort(); |
| 42 | + return 0; |
| 43 | + } |
| 44 | + requested -= output_bytes_this_pass; |
| 45 | + out += output_bytes_this_pass; |
66 | 46 | }
|
67 |
| - |
68 | 47 | return 1;
|
69 | 48 | }
|
70 | 49 |
|
|
0 commit comments