summaryrefslogtreecommitdiff
path: root/src/mongo/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/platform')
-rw-r--r--src/mongo/platform/random.cpp49
-rw-r--r--src/mongo/platform/windows_basic.h14
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)