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 ripple {
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(
50 entropy.data(),
51 entropy.size() * sizeof(std::random_device::result_type),
52 0);
53
54 if (buffer != nullptr && count != 0)
55 RAND_add(buffer, count, 0);
56}
57
58void
60{
61 // RAND_bytes is thread-safe on OpenSSL 1.1.0 and later when compiled
62 // with thread support, so we don't need to grab a mutex.
63 // https://mta.openssl.org/pipermail/openssl-users/2020-November/013146.html
64#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || !defined(OPENSSL_THREADS)
66#endif
67
68 auto const result =
69 RAND_bytes(reinterpret_cast<unsigned char*>(ptr), count);
70
71 if (result != 1)
72 Throw<std::runtime_error>("CSPRNG: Insufficient entropy");
73}
74
77{
78 result_type ret;
79 (*this)(&ret, sizeof(result_type));
80 return ret;
81}
82
85{
86 static csprng_engine engine;
87 return engine;
88}
89
90} // namespace ripple
A cryptographically secure random number engine.
Definition csprng.h:17
std::uint64_t result_type
Definition csprng.h:22
result_type operator()()
Generate a random integer.
std::mutex mutex_
Definition csprng.h:19
void mix_entropy(void *buffer=nullptr, std::size_t count=0)
Mix entropy into the pool.
T data(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
T size(T... args)