From 0b57cec536236d46e3dba9bd041533462f33dbb7 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 20 Dec 2019 19:53:05 +0000 Subject: Move all sources from the llvm project into contrib/llvm-project. This uses the new layout of the upstream repository, which was recently migrated to GitHub, and converted into a "monorepo". That is, most of the earlier separate sub-projects with their own branches and tags were consolidated into one top-level directory, and are now branched and tagged together. Updating the vendor area to match this layout is next. --- .../llvm/lib/Support/RandomNumberGenerator.cpp | 84 ++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 contrib/llvm-project/llvm/lib/Support/RandomNumberGenerator.cpp (limited to 'contrib/llvm-project/llvm/lib/Support/RandomNumberGenerator.cpp') diff --git a/contrib/llvm-project/llvm/lib/Support/RandomNumberGenerator.cpp b/contrib/llvm-project/llvm/lib/Support/RandomNumberGenerator.cpp new file mode 100644 index 000000000000..09fad1979985 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/RandomNumberGenerator.cpp @@ -0,0 +1,84 @@ +//===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements deterministic random number generation (RNG). +// The current implementation is NOT cryptographically secure as it uses +// the C++11 facilities. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/RandomNumberGenerator.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#ifdef _WIN32 +#include "Windows/WindowsSupport.h" +#else +#include "Unix/Unix.h" +#endif + +using namespace llvm; + +#define DEBUG_TYPE "rng" + +static cl::opt Seed("rng-seed", cl::value_desc("seed"), cl::Hidden, + cl::desc("Seed for the random number generator"), + cl::init(0)); + +RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { + LLVM_DEBUG(if (Seed == 0) dbgs() + << "Warning! Using unseeded random number generator.\n"); + + // Combine seed and salts using std::seed_seq. + // Data: Seed-low, Seed-high, Salt + // Note: std::seed_seq can only store 32-bit values, even though we + // are using a 64-bit RNG. This isn't a problem since the Mersenne + // twister constructor copies these correctly into its initial state. + std::vector Data; + Data.resize(2 + Salt.size()); + Data[0] = Seed; + Data[1] = Seed >> 32; + + llvm::copy(Salt, Data.begin() + 2); + + std::seed_seq SeedSeq(Data.begin(), Data.end()); + Generator.seed(SeedSeq); +} + +RandomNumberGenerator::result_type RandomNumberGenerator::operator()() { + return Generator(); +} + +// Get random vector of specified size +std::error_code llvm::getRandomBytes(void *Buffer, size_t Size) { +#ifdef _WIN32 + HCRYPTPROV hProvider; + if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + ScopedCryptContext ScopedHandle(hProvider); + if (CryptGenRandom(hProvider, Size, static_cast(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(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 +} -- cgit v1.2.3