rippled
Loading...
Searching...
No Matches
libxrpl/crypto/csprng.cpp
1#include <xrpl/basics/contract.h>
2#include <xrpl/crypto/csprng.h>
3
4#include <openssl/rand.h>
5#include <openssl/ssl.h>
6
7#include <array>
8#include <cstddef>
9#include <mutex>
10#include <random>
11#include <stdexcept>
12
13namespace xrpl {
14
16{
17 // This is not strictly necessary
18 if (RAND_poll() != 1)
19 Throw<std::runtime_error>("CSPRNG: Initial polling failed");
20}
21
23{
24 // This cleanup function is not needed in newer versions of OpenSSL
25#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
26 RAND_cleanup();
27#endif
28}
29
30void
32{
34
35 {
36 // On every platform we support, std::random_device
37 // is non-deterministic and should provide some good
38 // quality entropy.
40
41 for (auto& e : entropy)
42 e = rd();
43 }
44
46
47 // We add data to the pool, but we conservatively assume that
48 // it contributes no actual entropy.
49 RAND_add(entropy.data(), entropy.size() * sizeof(std::random_device::result_type), 0);
50
51 if (buffer != nullptr && count != 0)
52 RAND_add(buffer, count, 0);
53}
54
55void
57{
58 // RAND_bytes is thread-safe on OpenSSL 1.1.0 and later when compiled
59 // with thread support, so we don't need to grab a mutex.
60 // https://mta.openssl.org/pipermail/openssl-users/2020-November/013146.html
61#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || !defined(OPENSSL_THREADS)
63#endif
64
65 auto const result = RAND_bytes(reinterpret_cast<unsigned char*>(ptr), count);
66
67 if (result != 1)
68 Throw<std::runtime_error>("CSPRNG: Insufficient entropy");
69}
70
73{
74 result_type ret;
75 (*this)(&ret, sizeof(result_type));
76 return ret;
77}
78
81{
82 static csprng_engine engine;
83 return engine;
84}
85
86} // namespace xrpl
A cryptographically secure random number engine.
Definition csprng.h:16
void mix_entropy(void *buffer=nullptr, std::size_t count=0)
Mix entropy into the pool.
result_type operator()()
Generate a random integer.
std::uint64_t result_type
Definition csprng.h:21
std::mutex mutex_
Definition csprng.h:18
T data(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
T size(T... args)