summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Random.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@innovatetechnologi.es>2018-05-21 15:48:17 +0200
committerLéo Lam <leo@innovatetechnologi.es>2018-05-31 17:54:43 +0200
commitfff1db973096a893475f3ec96ee6f28e35c4a67c (patch)
tree5b92984b635bab59a2639cc06ce9860a534df23e /Source/Core/Common/Random.cpp
parentdd77ace56ada6cd7c394b39105a61b61905e5822 (diff)
Common: Add Random utilities
This makes it easier to generate random numbers or fill a buffer with random data in a cryptographically secure way. This also replaces existing usages of RNG functions in the codebase: * <random> is pretty hard to use correctly, and std::random_device does not give enough guarantees about its results (it's implementation-defined, non cryptographically secure and could be deterministic on some platforms). Doing things correctly is error prone and verbose. * rand() is terrible and should not be used especially in crypto code.
Diffstat (limited to 'Source/Core/Common/Random.cpp')
-rw-r--r--Source/Core/Common/Random.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/Source/Core/Common/Random.cpp b/Source/Core/Common/Random.cpp
new file mode 100644
index 0000000000..c512e7695d
--- /dev/null
+++ b/Source/Core/Common/Random.cpp
@@ -0,0 +1,49 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/Random.h"
+
+#include <mbedtls/entropy.h>
+#include <mbedtls/hmac_drbg.h>
+
+#include "Common/Assert.h"
+
+namespace Common::Random
+{
+class CSPRNG final
+{
+public:
+ CSPRNG()
+ {
+ mbedtls_entropy_init(&m_entropy);
+ mbedtls_hmac_drbg_init(&m_context);
+ const int ret = mbedtls_hmac_drbg_seed(&m_context, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
+ mbedtls_entropy_func, &m_entropy, nullptr, 0);
+ ASSERT(ret == 0);
+ }
+
+ ~CSPRNG()
+ {
+ mbedtls_hmac_drbg_free(&m_context);
+ mbedtls_entropy_free(&m_entropy);
+ }
+
+ void Generate(void* buffer, std::size_t size)
+ {
+ const int ret = mbedtls_hmac_drbg_random(&m_context, static_cast<u8*>(buffer), size);
+ ASSERT(ret == 0);
+ }
+
+private:
+ mbedtls_entropy_context m_entropy;
+ mbedtls_hmac_drbg_context m_context;
+};
+
+static thread_local CSPRNG s_csprng;
+
+void Generate(void* buffer, std::size_t size)
+{
+ s_csprng.Generate(buffer, size);
+}
+} // namespace Common::Random