diff options
author | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-08-26 08:14:54 +0000 |
---|---|---|
committer | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-08-26 08:14:54 +0000 |
commit | ea877d40b45ae3f77ceaa517ee8f878be45543bc (patch) | |
tree | d1d3ab2118198df0212c48e8203bf9342a21ec7a /llvm/lib/Support/RandomNumberGenerator.cpp | |
parent | 8f27f511922b5fe9d3e8d2a22a04fc0d3375b6fe (diff) | |
download | bcm5719-llvm-ea877d40b45ae3f77ceaa517ee8f878be45543bc.tar.gz bcm5719-llvm-ea877d40b45ae3f77ceaa517ee8f878be45543bc.zip |
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
llvm-svn: 279807
Diffstat (limited to 'llvm/lib/Support/RandomNumberGenerator.cpp')
-rw-r--r-- | llvm/lib/Support/RandomNumberGenerator.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/Support/RandomNumberGenerator.cpp b/llvm/lib/Support/RandomNumberGenerator.cpp index 81d0411d60b..087c6710dff 100644 --- a/llvm/lib/Support/RandomNumberGenerator.cpp +++ b/llvm/lib/Support/RandomNumberGenerator.cpp @@ -17,6 +17,11 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#ifdef LLVM_ON_WIN32 +#include "Windows/WindowsSupport.h" +#else +#include "Unix/Unix.h" +#endif using namespace llvm; @@ -55,3 +60,32 @@ RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { uint_fast64_t RandomNumberGenerator::operator()() { return Generator(); } + +// Get random vector of specified size +std::error_code llvm::getRandomBytes(void *Buffer, size_t Size) { +#ifdef LLVM_ON_WIN32 + HCRYPTPROV hProvider; + if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + ScopedCryptContext ScopedHandle(hProvider); + if (CryptGenRandom(hProvider, Size, static_cast<BYTE *>(Buffer))) + return std::error_code(); + } + return std::error_code(GetLastError(), std::system_category()); +#else + int Fd = open("/dev/urandom", O_RDONLY); + if (Fd != -1) { + std::error_code Ret; + ssize_t BytesRead = read(Fd, Buffer, Size); + if (BytesRead == -1) + Ret = std::error_code(errno, std::system_category()); + else if (BytesRead != static_cast<ssize_t>(Size)) + Ret = std::error_code(EIO, std::system_category()); + if (close(Fd) == -1) + Ret = std::error_code(errno, std::system_category()); + + return Ret; + } + return std::error_code(errno, std::system_category()); +#endif +} |