#include <folly/Random.h>
#include <atomic>
-#include <unistd.h>
-#include <sys/time.h>
#include <mutex>
#include <random>
#include <array>
#include <glog/logging.h>
+#include <folly/CallOnce.h>
#include <folly/File.h>
#include <folly/FileUtil.h>
#include <folly/ThreadLocal.h>
+#include <folly/portability/SysTime.h>
+#include <folly/portability/Unistd.h>
#ifdef _MSC_VER
# include <wincrypt.h>
void readRandomDevice(void* data, size_t size) {
#ifdef _MSC_VER
- static std::once_flag flag;
+ static folly::once_flag flag;
static HCRYPTPROV cryptoProv;
- std::call_once(flag, [&] {
- PCHECK(CryptAcquireContext(&cryptoProv, nullptr, nullptr,
- PROV_RSA_FULL, 0));
+ folly::call_once(flag, [&] {
+ if (!CryptAcquireContext(&cryptoProv, nullptr, nullptr, PROV_RSA_FULL, 0)) {
+ if (GetLastError() == NTE_BAD_KEYSET) {
+ // Mostly likely cause of this is that no key container
+ // exists yet, so try to create one.
+ PCHECK(CryptAcquireContext(
+ &cryptoProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_NEWKEYSET));
+ } else {
+ LOG(FATAL) << "Failed to acquire the default crypto context.";
+ }
+ }
});
CHECK(size <= std::numeric_limits<DWORD>::max());
PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data));