|
17 | 17 | #include "llvm/Support/CommandLine.h"
|
18 | 18 | #include "llvm/Support/Debug.h"
|
19 | 19 | #include "llvm/Support/raw_ostream.h"
|
| 20 | +#ifdef LLVM_ON_WIN32 |
| 21 | +#include "Windows/WindowsSupport.h" |
| 22 | +#else |
| 23 | +#include "Unix/Unix.h" |
| 24 | +#endif |
20 | 25 |
|
21 | 26 | using namespace llvm;
|
22 | 27 |
|
@@ -55,3 +60,32 @@ RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {
|
55 | 60 | uint_fast64_t RandomNumberGenerator::operator()() {
|
56 | 61 | return Generator();
|
57 | 62 | }
|
| 63 | + |
| 64 | +// Get random vector of specified size |
| 65 | +std::error_code llvm::getRandomBytes(void *Buffer, size_t Size) { |
| 66 | +#ifdef LLVM_ON_WIN32 |
| 67 | + HCRYPTPROV hProvider; |
| 68 | + if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, |
| 69 | + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { |
| 70 | + ScopedCryptContext ScopedHandle(hProvider); |
| 71 | + if (CryptGenRandom(hProvider, Size, static_cast<BYTE *>(Buffer))) |
| 72 | + return std::error_code(); |
| 73 | + } |
| 74 | + return std::error_code(GetLastError(), std::system_category()); |
| 75 | +#else |
| 76 | + int Fd = open("/dev/urandom", O_RDONLY); |
| 77 | + if (Fd != -1) { |
| 78 | + std::error_code Ret; |
| 79 | + ssize_t BytesRead = read(Fd, Buffer, Size); |
| 80 | + if (BytesRead == -1) |
| 81 | + Ret = std::error_code(errno, std::system_category()); |
| 82 | + else if (BytesRead != static_cast<ssize_t>(Size)) |
| 83 | + Ret = std::error_code(EIO, std::system_category()); |
| 84 | + if (close(Fd) == -1) |
| 85 | + Ret = std::error_code(errno, std::system_category()); |
| 86 | + |
| 87 | + return Ret; |
| 88 | + } |
| 89 | + return std::error_code(errno, std::system_category()); |
| 90 | +#endif |
| 91 | +} |
0 commit comments