diff options
Diffstat (limited to 'src/mongo/platform')
-rw-r--r-- | src/mongo/platform/random.cpp | 49 | ||||
-rw-r--r-- | src/mongo/platform/windows_basic.h | 14 |
2 files changed, 53 insertions, 10 deletions
diff --git a/src/mongo/platform/random.cpp b/src/mongo/platform/random.cpp index 2ec9ddea610..c46747a4135 100644 --- a/src/mongo/platform/random.cpp +++ b/src/mongo/platform/random.cpp @@ -27,12 +27,18 @@ * then also delete it in the license file. */ +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault + +#include "mongo/platform/basic.h" + #include "mongo/platform/random.h" #include <stdio.h> #include <string.h> -#ifndef _WIN32 +#ifdef _WIN32 +#include <bcrypt.h> +#else #include <errno.h> #endif @@ -42,7 +48,8 @@ #include <fstream> #include <limits> -#include "mongo/platform/basic.h" +#include <mongo/util/log.h> +#include <mongo/util/assert_util.h> namespace mongo { @@ -99,17 +106,39 @@ SecureRandom::~SecureRandom() {} #ifdef _WIN32 class WinSecureRandom : public SecureRandom { - virtual ~WinSecureRandom() {} - int64_t nextInt64() { - uint32_t a, b; - if (rand_s(&a)) { - abort(); +public: + WinSecureRandom() { + auto ntstatus = ::BCryptOpenAlgorithmProvider( + &_algHandle, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + if (ntstatus != STATUS_SUCCESS) { + error() << "Failed to open crypto algorithm provider while creating secure random " + "object; NTSTATUS: " << ntstatus; + fassertFailed(28815); } - if (rand_s(&b)) { - abort(); + } + + virtual ~WinSecureRandom() { + auto ntstatus = ::BCryptCloseAlgorithmProvider(_algHandle, 0); + if (ntstatus != STATUS_SUCCESS) { + warning() << "Failed to close crypto algorithm provider destroying secure random " + "object; NTSTATUS: " << ntstatus; + } + } + + int64_t nextInt64() { + int64_t value; + auto ntstatus = + ::BCryptGenRandom(_algHandle, reinterpret_cast<PUCHAR>(&value), sizeof(value), 0); + if (ntstatus != STATUS_SUCCESS) { + error() << "Failed to generate random number from secure random object; NTSTATUS: " + << ntstatus; + fassertFailed(28814); } - return (static_cast<int64_t>(a) << 32) | b; + return value; } + +private: + BCRYPT_ALG_HANDLE _algHandle; }; SecureRandom* SecureRandom::create() { diff --git a/src/mongo/platform/windows_basic.h b/src/mongo/platform/windows_basic.h index 7e2b8ac17fc..ac6cb289dc8 100644 --- a/src/mongo/platform/windows_basic.h +++ b/src/mongo/platform/windows_basic.h @@ -82,10 +82,24 @@ // tell windows.h not to include a bunch of headers we don't need: #define WIN32_LEAN_AND_MEAN +// Tell windows.h not to define any NT status codes, so that we can +// get the definitions from ntstatus.h, which has a more complete list. +#define WIN32_NO_STATUS + #include <winsock2.h> //this must be included before the first windows.h include #include <ws2tcpip.h> #include <windows.h> +#undef WIN32_NO_STATUS + +// Obtain a definition for the ntstatus type. +#include <winternl.h> + +// Add back in the status definitions so that macro expansions for +// things like STILL_ACTIVE and WAIT_OBJECT_O can be resolved (they +// expand to STATUS_ codes). +#include <ntstatus.h> + // Should come either from the command line, or if not set there, the inclusion of sdkddkver.h // via windows.h above should set it based in _WIN32_WINNT, which is assuredly set by now. #if !defined(NTDDI_VERSION) |