X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FRandom.cpp;h=d4fb39b4ea3a4eaaa1d9140dfe422bcdd610a090;hp=9b960de0530e21ade261511173dc8a01b6c2562c;hb=d5f5bc4fd1f1e6eebc3e30d00512d853eb6dc611;hpb=6caa3d95ee837703f8f094ffbff5592627417711 diff --git a/folly/Random.cpp b/folly/Random.cpp index 9b960de0..d4fb39b4 100644 --- a/folly/Random.cpp +++ b/folly/Random.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,17 @@ #include #include -#include -#include #include #include #include #include +#include #include #include +#include +#include +#include #ifdef _MSC_VER # include @@ -37,11 +39,24 @@ namespace { 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, + CRYPT_VERIFYCONTEXT)) { + 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::max()); PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data)); @@ -108,14 +123,14 @@ void BufferedRandomDevice::getSlow(unsigned char* data, size_t size) { ptr_ += size; } + } // namespace void Random::secureRandom(void* data, size_t size) { - static thread_local BufferedRandomDevice bufferedRandomDevice; - bufferedRandomDevice.get(data, size); + static ThreadLocal bufferedRandomDevice; + bufferedRandomDevice->get(data, size); } - class ThreadLocalPRNG::LocalInstancePRNG { public: LocalInstancePRNG() : rng(Random::create()) { } @@ -124,8 +139,8 @@ class ThreadLocalPRNG::LocalInstancePRNG { }; ThreadLocalPRNG::ThreadLocalPRNG() { - static thread_local ThreadLocalPRNG::LocalInstancePRNG localInstance; - local_ = &localInstance; + static folly::ThreadLocal localInstance; + local_ = localInstance.get(); } uint32_t ThreadLocalPRNG::getImpl(LocalInstancePRNG* local) {