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