|
32 | 32 | #include <cstring> |
33 | 33 | #include <cstdio> |
34 | 34 |
|
| 35 | +#if defined(_WIN32) |
| 36 | + #include <windows.h> |
| 37 | + #include <wincrypt.h> |
| 38 | +#endif |
| 39 | + |
35 | 40 | // Stats |
36 | 41 | STATISTIC(statsGetBytes, "a. Number of calls to get_bytes ()"); |
37 | 42 | STATISTIC(statsGetChar, "b. Number of calls to get_char ()"); |
@@ -747,35 +752,51 @@ void PrngAESCtr::populate_pool () { |
747 | 752 | } |
748 | 753 |
|
749 | 754 | void PrngAESCtr::prng_seed () { |
750 | | -#if defined(__linux__) |
751 | | - std::ifstream devrandom ("/dev/urandom"); |
| 755 | + |
| 756 | + LLVMContext &ctx = llvm::getGlobalContext(); |
| 757 | + |
| 758 | +#if defined(_WIN32) |
| 759 | + HCRYPTPROV hProvider = 0; |
| 760 | + |
| 761 | + if (!::CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { |
| 762 | + ctx.emitError(Twine("Cannot acquire cryptographic context")); |
| 763 | + } |
| 764 | + |
| 765 | + if (!::CryptGenRandom(hProvider, 16, (unsigned char*)key)) |
| 766 | + { |
| 767 | + ::CryptReleaseContext(hProvider, 0); |
| 768 | + ctx.emitError(Twine("Cannot generate random")); |
| 769 | + } |
| 770 | + |
| 771 | + if (!::CryptReleaseContext(hProvider, 0)) { |
| 772 | + ctx.emitError(Twine("Cannot release cryptographic context")); |
| 773 | + } |
| 774 | + |
| 775 | + DEBUG_WITH_TYPE("cprng", dbgs() << "CPNRG seeded with Windows cryptographic API"); |
752 | 776 | #else |
753 | | - std::ifstream devrandom ("/dev/random"); |
754 | | -#endif |
755 | | - |
756 | | - LLVMContext &ctx = llvm::getGlobalContext(); |
757 | | - |
| 777 | + std::ifstream devrandom ("/dev/urandom"); |
| 778 | + |
758 | 779 | if (devrandom) { |
759 | 780 |
|
760 | 781 | devrandom.read (key, 16); |
761 | 782 |
|
762 | 783 | if (devrandom.gcount() != 16) { |
763 | | - ctx.emitError ( Twine("Cannot read enough bytes in /dev/random")); |
| 784 | + ctx.emitError ( Twine("Cannot read enough bytes in /dev/urandom")); |
764 | 785 | } |
765 | 786 |
|
766 | 787 | devrandom.close(); |
767 | | - DEBUG_WITH_TYPE ("cprng", dbgs() << "CPNRG seeded with /dev/random"); |
768 | | - |
769 | | - memset(ctr, 0, 16); |
770 | | - |
771 | | - // Once the seed is there, we compute the |
772 | | - // AES128 key-schedule |
773 | | - aes_compute_ks(ks, key); |
774 | | - |
775 | | - seeded = true; |
776 | 788 | } else { |
777 | | - ctx.emitError (Twine ("Cannot open /dev/random")); |
| 789 | + ctx.emitError (Twine ("Cannot open /dev/urandom")); |
778 | 790 | } |
| 791 | +#endif |
| 792 | + |
| 793 | + memset(ctr, 0, 16); |
| 794 | + |
| 795 | + // Once the seed is there, we compute the |
| 796 | + // AES128 key-schedule |
| 797 | + aes_compute_ks(ks, key); |
| 798 | + |
| 799 | + seeded = true; |
779 | 800 | } |
780 | 801 |
|
781 | 802 | void PrngAESCtr::inc_ctr() { |
|
0 commit comments