rippled
Loading...
Searching...
No Matches
libxrpl
crypto
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
13
namespace
xrpl
{
14
15
csprng_engine::csprng_engine
()
16
{
17
// This is not strictly necessary
18
if
(RAND_poll() != 1)
19
Throw<std::runtime_error>(
"CSPRNG: Initial polling failed"
);
20
}
21
22
csprng_engine::~csprng_engine
()
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
30
void
31
csprng_engine::mix_entropy
(
void
* buffer,
std::size_t
count)
32
{
33
std::array<std::random_device::result_type, 128>
entropy{};
34
35
{
36
// On every platform we support, std::random_device
37
// is non-deterministic and should provide some good
38
// quality entropy.
39
std::random_device
rd;
40
41
for
(
auto
& e : entropy)
42
e = rd();
43
}
44
45
std::lock_guard
const
lock(
mutex_
);
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
55
void
56
csprng_engine::operator()
(
void
* ptr,
std::size_t
count)
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)
62
std::lock_guard
lock(
mutex_
);
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
71
csprng_engine::result_type
72
csprng_engine::operator()
()
73
{
74
result_type
ret = 0;
75
(*this)(&ret,
sizeof
(
result_type
));
76
return
ret;
77
}
78
79
csprng_engine
&
80
crypto_prng
()
81
{
82
static
csprng_engine
engine;
83
return
engine;
84
}
85
86
}
// namespace xrpl
array
xrpl::csprng_engine
A cryptographically secure random number engine.
Definition
csprng.h:16
xrpl::csprng_engine::mix_entropy
void mix_entropy(void *buffer=nullptr, std::size_t count=0)
Mix entropy into the pool.
Definition
libxrpl/crypto/csprng.cpp:31
xrpl::csprng_engine::operator()
result_type operator()()
Generate a random integer.
Definition
libxrpl/crypto/csprng.cpp:72
xrpl::csprng_engine::csprng_engine
csprng_engine()
Definition
libxrpl/crypto/csprng.cpp:15
xrpl::csprng_engine::result_type
std::uint64_t result_type
Definition
csprng.h:21
xrpl::csprng_engine::~csprng_engine
~csprng_engine()
Definition
libxrpl/crypto/csprng.cpp:22
xrpl::csprng_engine::mutex_
std::mutex mutex_
Definition
csprng.h:18
cstddef
std::uint64_t
std::lock_guard
mutex
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::crypto_prng
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
Definition
libxrpl/crypto/csprng.cpp:80
std::random_device
random
std::size_t
stdexcept
Generated by
1.9.8