OpenVPN 3 Core Library
Loading...
Searching...
No Matches
mtrandapi.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// Non-cryptographic random number generator
13
14#ifndef OPENVPN_RANDOM_MTRANDAPI_H
15#define OPENVPN_RANDOM_MTRANDAPI_H
16
17#include <random>
18
22
23
24//
25// Prevent compiler from inlining MTRand byte-fill loops into
26// larger call chains, which confuses the optimiser and triggers
27// false-positive -Warray-bounds / -Wstringop-overflow warnings.
28// This issue appeared first with GCC 16.1 with -O2
29//
30#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 16
31#define MTRAND_GCC_NO_INLINE __attribute__((noinline))
32#else
33#define MTRAND_GCC_NO_INLINE
34#endif
35
36
37namespace openvpn {
38
39class MTRand : public WeakRandomAPI
40{
41 public:
42 OPENVPN_EXCEPTION(mtrand_error);
43
45 using rand_type = std::mt19937_64;
46
48 : rng(gen_seed(seed))
49 {
50 }
51
53 : rng(gen_seed())
54 {
55 }
56
57 MTRand(const rand_type::result_type seed)
58 : rng(seed)
59 {
60 }
61
62 // Random algorithm name
63 std::string name() const override
64 {
65 return "MTRand";
66 }
67
68 // Fill buffer with random bytes
69 MTRAND_GCC_NO_INLINE void rand_bytes(unsigned char *buf, size_t size) override
70 {
71 while (size--)
72 *buf++ = rbs.get_byte(rng);
73 }
74
80 MTRAND_GCC_NO_INLINE bool rand_bytes_noexcept(unsigned char *buf, size_t size) override
81 {
82 rand_bytes(buf, size);
83 return true;
84 }
85
86 rand_type::result_type rand()
87 {
88 return rng();
89 }
90
91 private:
92 static rand_type::result_type gen_seed(RandomAPI &seed)
93 {
94 return seed.rand_get<rand_type::result_type>();
95 }
96
97 static rand_type::result_type gen_seed()
98 {
99 std::random_device rd;
100 RandomByteStore<decltype(rd)> rbs;
101 rand_type::result_type ret;
102 rbs.fill(ret, rd);
103 return ret;
104 }
105
108};
109
110} // namespace openvpn
111
112#endif
static rand_type::result_type gen_seed(RandomAPI &seed)
Definition mtrandapi.hpp:92
MTRAND_GCC_NO_INLINE void rand_bytes(unsigned char *buf, size_t size) override
Fill a buffer with random bytes.
Definition mtrandapi.hpp:69
static rand_type::result_type gen_seed()
Definition mtrandapi.hpp:97
MTRand(RandomAPI &seed)
Definition mtrandapi.hpp:47
MTRAND_GCC_NO_INLINE bool rand_bytes_noexcept(unsigned char *buf, size_t size) override
Definition mtrandapi.hpp:80
std::string name() const override
Get the name of the random number generation algorithm.
Definition mtrandapi.hpp:63
OPENVPN_EXCEPTION(mtrand_error)
std::mt19937_64 rand_type
Definition mtrandapi.hpp:45
MTRand(const rand_type::result_type seed)
Definition mtrandapi.hpp:57
rand_type::result_type rand()
Definition mtrandapi.hpp:86
RandomByteStore< rand_type > rbs
The smart pointer class.
Definition rc.hpp:119
Abstract base class for random number generators.
Definition randapi.hpp:39
T rand_get()
Create a data object filled with random bytes.
Definition randapi.hpp:86
unsigned char get_byte(RAND_TYPE &rng)
void fill(T &obj, RAND_TYPE &rng)
Abstract base class for pseudo random number generators.
Definition randapi.hpp:243
#define MTRAND_GCC_NO_INLINE
Definition mtrandapi.hpp:33
Implementation of the base classes for random number generators.