diff options
| author | Léo Lam <leo@innovatetechnologi.es> | 2018-05-21 15:48:17 +0200 |
|---|---|---|
| committer | Léo Lam <leo@innovatetechnologi.es> | 2018-05-31 17:54:43 +0200 |
| commit | fff1db973096a893475f3ec96ee6f28e35c4a67c (patch) | |
| tree | 5b92984b635bab59a2639cc06ce9860a534df23e /Source/Core/Common/Random.cpp | |
| parent | dd77ace56ada6cd7c394b39105a61b61905e5822 (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.cpp | 49 |
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 |
