Coverage Report

Created: 2024-05-03 06:05

/builds/xfbs/passgen/include/passgen/util/random.h
Line
Count
Source
1
/// @file random.h
2
/// @author Patrick M. Elsen <pelsen@xfbs.net>
3
/// @brief Generate random data from various sources.
4
///
5
/// Functions used to extract random data. Provides an interface around a
6
/// random data device, typically `/dev/urandom`, that can be used safely.
7
#pragma once
8
#include <stdbool.h>
9
#include <stdint.h>
10
#include <stdio.h>
11
12
/// Size of the random data ring buffer.
13
/// Requests for more than this result in a direct call to the @ref passgen_random_close_fun,
14
/// requests smaller than this are read from the buffer.
15
42
#define PASSGEN_RANDOM_BUFFER_LENGTH 1024
16
17
/// Type of function used to read more random data.
18
typedef size_t passgen_random_read_func(void *dest, size_t size, void *data);
19
20
/// Type of function used to close the randomness source.
21
typedef void passgen_random_close_func(void *data);
22
23
/// Randomness source.
24
typedef struct {
25
    /// Ring buffer to hold random data in.
26
    uint8_t buffer[PASSGEN_RANDOM_BUFFER_LENGTH];
27
28
    /// Current position in the ring buffer.
29
    size_t pos;
30
31
    /// Device to read random data from.
32
    void *data;
33
34
    /// Function used to read more random data.
35
    passgen_random_read_func *read;
36
37
    /// Function used to close randomness source.
38
    passgen_random_close_func *close;
39
} passgen_random;
40
41
/// Allocates and opens new random object.
42
///
43
/// @param desc String description of which randomness source to allocate. When `NULL`, uses
44
/// system randomness source.
45
/// @returns Returns `NULL` on error.
46
/// @memberof passgen_random
47
///
48
/// @par Example
49
///
50
/// ```c
51
/// passgen_random *random_default = passgen_random_new(NULL);
52
/// passgen_random *random_system = passgen_random_new("system");
53
/// passgen_random *random_xorshift = passgen_random_new("xorshift:1234");
54
/// passgen_random *random_file = passgen_random_new("file:/dev/urandom");
55
/// passgen_random *random_zero = passgen_random_new("zero");
56
/// passgen_random_free(random_default);
57
/// passgen_random_free(random_system);
58
/// passgen_random_free(random_xorshift);
59
/// passgen_random_free(random_file);
60
/// passgen_random_free(random_zero);
61
/// ```
62
passgen_random *passgen_random_new(const char *desc);
63
64
/// Allocates and opens a new random object using @p path as random device.
65
/// Not recommended to use `/dev/random` as randomness device, use the default
66
/// `/dev/urandom` instead.
67
///
68
/// @memberof passgen_random
69
passgen_random *passgen_random_new_path(const char *path);
70
71
/// Allocates and opens a new random object with @p file as randomness source.
72
///
73
/// @memberof passgen_random
74
passgen_random *passgen_random_new_file(FILE *file);
75
76
/// Allocates and opens a new random object using the xorshift PRNG.
77
///
78
/// @memberof passgen_random
79
passgen_random *passgen_random_new_xorshift(uint64_t seed);
80
81
/// Allocates and opens a new random object using the zero randomness generator.
82
///
83
/// @memberof passgen_random
84
passgen_random *passgen_random_new_zero();
85
86
/// Opens a new, existing random object. Returns `NULL` on failure. Uses
87
/// `/dev/urandom` as random device.
88
///
89
/// @par Example
90
///
91
/// ```c
92
/// passgen_random random;
93
///
94
/// assert(passgen_random_open(&random) != NULL);
95
///
96
/// // use random
97
///
98
/// passgen_random_close(&random);
99
/// ```
100
///
101
/// @memberof passgen_random
102
passgen_random *passgen_random_open(passgen_random *random, const char *desc);
103
104
/// Opens a new, existing random object using @p path as random device.
105
///
106
/// @memberof passgen_random
107
passgen_random *
108
passgen_random_open_path(passgen_random *random, const char *path);
109
110
/// Opens a new random object with @p file as randomness source.
111
///
112
/// @memberof passgen_random
113
passgen_random *
114
passgen_random_open_file(passgen_random *random, FILE *file);
115
116
/// Opens a new random object using the xorshift PRNG.
117
///
118
/// @memberof passgen_random
119
passgen_random *
120
passgen_random_open_xorshift(passgen_random *random, uint64_t seed);
121
122
/// Opens a new random object using the zero randomness generator
123
///
124
/// @memberof passgen_random
125
passgen_random *
126
passgen_random_open_zero(passgen_random *random);
127
128
/// Close @p random. Use this with object opened by passgen_random_open().
129
///
130
/// @memberof passgen_random
131
void passgen_random_close(passgen_random *random);
132
133
/// Close and free @p random. Use this with objects allocated by
134
/// passgen_random_new().
135
///
136
/// @memberof passgen_random
137
void passgen_random_free(passgen_random *random);
138
139
/// Read random data from @a random.
140
///
141
/// @param dest destination to write to, must be large enough and not NULL.
142
/// @param bytes how many bytes to write.
143
///
144
/// @memberof passgen_random
145
void passgen_random_read(passgen_random *random, void *dest, size_t bytes);
146
147
/// Read a `uint8_t` from @p random.
148
///
149
/// @memberof passgen_random
150
uint8_t passgen_random_u8(passgen_random *random);
151
152
/// Read a `uint16_t` from @p random.
153
///
154
/// @memberof passgen_random
155
uint16_t passgen_random_u16(passgen_random *random);
156
157
/// Read a `uint32_t` from @p random.
158
///
159
/// @memberof passgen_random
160
uint32_t passgen_random_u32(passgen_random *random);
161
162
/// Read a `uint64_t` from @p random.
163
///
164
/// @memberof passgen_random
165
uint64_t passgen_random_u64(passgen_random *random);
166
167
/// Generate a random boolean.
168
///
169
/// @memberof passgen_random
170
bool passgen_random_bool(passgen_random *random);
171
172
/// Read a `uint8_t` that is strictly smaller than @p max from @p random.
173
///
174
/// @param max must be nonzero.
175
/// @memberof passgen_random
176
uint8_t passgen_random_u8_max(passgen_random *random, uint8_t max);
177
178
/// Read a `uint16_t` that is strictly smaller than @p max from @p random.
179
///
180
/// @param max must be nonzero.
181
/// @memberof passgen_random
182
uint16_t passgen_random_u16_max(passgen_random *random, uint16_t max);
183
184
/// Read a `uint32_t` that is strictly smaller than @p max from @p random.
185
///
186
/// @param max must be nonzero.
187
/// @memberof passgen_random
188
uint32_t passgen_random_u32_max(passgen_random *random, uint32_t max);
189
190
/// Read a `uint64_t` that is strictly smaller than @p max from @p random.
191
///
192
/// @param max must be nonzero.
193
/// @memberof passgen_random
194
uint64_t passgen_random_u64_max(passgen_random *random, uint64_t max);