llvm.org GIT mirror llvm / e21267a
Implement getRandomBytes() function This function allows getting arbitrary sized block of random bytes. Primary motivation is support for --build-id=uuid in lld. Differential revision: https://reviews.llvm.org/D23671 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279807 91177308-0d34-0410-b5e6-96231b3b80d8 Eugene Leviant 4 years ago
3 changed file(s) with 42 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1818 #include "llvm/Support/Compiler.h"
1919 #include "llvm/Support/DataTypes.h" // Needed for uint64_t on Windows.
2020 #include
21 #include
2122
2223 namespace llvm {
2324 class StringRef;
5253
5354 friend class Module;
5455 };
56
57 // Get random vector of specified size
58 std::error_code getRandomBytes(void *Buffer, size_t Size);
5559 }
5660
5761 #endif
1616 #include "llvm/Support/CommandLine.h"
1717 #include "llvm/Support/Debug.h"
1818 #include "llvm/Support/raw_ostream.h"
19 #ifdef LLVM_ON_WIN32
20 #include "Windows/WindowsSupport.h"
21 #else
22 #include "Unix/Unix.h"
23 #endif
1924
2025 using namespace llvm;
2126
5459 uint_fast64_t RandomNumberGenerator::operator()() {
5560 return Generator();
5661 }
62
63 // Get random vector of specified size
64 std::error_code llvm::getRandomBytes(void *Buffer, size_t Size) {
65 #ifdef LLVM_ON_WIN32
66 HCRYPTPROV hProvider;
67 if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL,
68 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
69 ScopedCryptContext ScopedHandle(hProvider);
70 if (CryptGenRandom(hProvider, Size, static_cast(Buffer)))
71 return std::error_code();
72 }
73 return std::error_code(GetLastError(), std::system_category());
74 #else
75 int Fd = open("/dev/urandom", O_RDONLY);
76 if (Fd != -1) {
77 std::error_code Ret;
78 ssize_t BytesRead = read(Fd, Buffer, Size);
79 if (BytesRead == -1)
80 Ret = std::error_code(errno, std::system_category());
81 else if (BytesRead != static_cast(Size))
82 Ret = std::error_code(EIO, std::system_category());
83 if (close(Fd) == -1)
84 Ret = std::error_code(errno, std::system_category());
85
86 return Ret;
87 }
88 return std::error_code(errno, std::system_category());
89 #endif
90 }
4747 # include
4848 #endif
4949
50 #ifdef HAVE_FCNTL_H
51 # include
52 #endif
53
5054 /// This function builds an error message into \p ErrMsg using the \p prefix
5155 /// string and the Unix error number given by \p errnum. If errnum is -1, the
5256 /// default then the value of errno is used.