1libhavege(3) LIBRARY FUNCTIONS libhavege(3)
2
3
4
6 libhavege, havege_create, havege_run, havege_rng, havege_destroy,
7 havege_status, havege_status_dump, havege_version - haveged RNG
8
10
11
12 #include <haveged/havege.h>
13 H_PARAMS params = {0};
14 h_status status;
15 char status_buf[512];
16
17 if (NULL==havege_version(HAVEGE_PREP_VERSION)) exit(1);
18 H_PTR handle = havege_create(¶ms);
19 havege_status(handle, &status);
20 havege_run(handle);
21 rc = havege_rng(handle, handle->io_buf, handle->i_readSz/sizeof(H_UINT));
22 havege_status_dump(handle, H_SD_TOPIC_BUILD, status_buf, sizeof(status_buf));
23 havege_destroy(handle);
24
25
27 The libhavege library provides the haveged random number generator and
28 it's associated tuning and testing facilities in a development sub-
29 package. All haveged conditional build features are preserved and all
30 haveged options not directly related to it's daemon or file system
31 interfaces are available. This means that the same haveged tuning and
32 testing components are present in the library with the equivalent con‐
33 trols provided by the haveged command line.
34
35
36
38 The libhavege library uses the opaque handle technique to manage it's
39 required resources. Errors are returned in the "error" member of the
40 handle. The havege_destroy() method should be called to dispose of any
41 resources claimed by havege_create().
42
43 H_PTR havege_create(H_PARAMS *params);
44
45 Create an anchor. Most members of the H_PARAMS input to this call cor‐
46 respond closely to haveged command line options (see haveged(8) for
47 details). The caller should check for a non-null return value with a
48 error value of H_NOERR. Any non-null return should be disposed of by a
49 call to havege_destroy() to free any resources. Possible error values:
50 H_NOERR, H_NOTESTSPEC, H_NOBUF, H_NOTESTMEM, H_NOINIT
51
52
53 void havege_destroy(H_PTR hptr);
54
55 Free all allocated anchor resources. If the multi-core option is used,
56 this method should be called from a signal handler to prevent zombie
57 processes. If called by the process that called haveged_create(), hptr
58 will be freed when all child processes (if any) have terminated. If
59 called by a child process, H_EXIT will be set and all children awakened
60 to exit.
61
62
63 int havege_rng(H_PTR hptr, H_UINT *buf, H_UINT sz);
64
65 Read random bytes from an active anchor. The RNG must have been previ‐
66 ously readied by a call to havege_run(). The read must take place
67 within the allocated buffer, hptr->io_buf. The range specified is the
68 number of H_UINT to read. If the multi-core option is used, this buffer
69 is memory mapped between collectors. Possible error values: H_NOERR,
70 H_NOTESRUN, H_NOPOST, H_NODONE, H_NORQST, H_NOCOMP, H_EXIT
71
72
73 int havege_run(H_PTR hptr);
74
75 Warm up the RNG and run the start-up tests. The operation succeeded if
76 the error member of the handle is H_NOERR. A failed handle should be
77 disposed of by a call to havege_destroy(). Possible error values:
78 H_NOERR, H_NOCOLLECT, H_NOWALK, H_NOTESTMEM, H_NOTASK, H_NOTESTTOT,
79 H_NOWAIT, H_NOTIMER, and any havege_rng() error.
80
81
82 void havege_status(H_PTR hptr, H_STATUS hsts);
83
84 Fills in the h_status structure with read-only information collected
85 from the package build, run-time tuning, and test components.
86
87
88 int havege_status_dump(H_PTR hptr, H_SD_TOPIC topic, char *buf, size_t
89 len);
90
91 Calls havege_status() and formats standard presentations of havege sta‐
92 tus in the supplied buffer. The standard formats are:
93
94 H_SD_TOPIC_BUILD
95
96 ver: %s; arch: %s; vend: %s; build: (%s); collect: %dK
97
98 H_SD_TOPIC_TUNE
99
100 cpu: (%s); data: %dK (%s); inst: %dK (%s); idx: %d/%d; sz: %d/%d
101
102 H_SD_TOPIC_TEST
103
104 [tot tests(%s): A:%d/%d B: %d/%d;][continuous tests(%s): A:%d/%d
105 B: %d/%d;][last entropy estimate %g]
106
107 H_SD_TOPIC_SUM
108
109 fills: %d, generated: %.4g %c bytes
110
111 const char *havege_version(const char *version);
112
113 Return/check library prep version. The prep version is the package ver‐
114 sion used to build the library. A null argument returns the prep ver‐
115 sion unconditionally. Using the definition of the prep string in
116 havege.h as input returns the prep version if the header file is com‐
117 patible with the library, or NULL if it is not. Intended to be called
118 before attempting any initialization.
119
120
122 The sizes of the processor level 1 instruction and data caches are used
123 to tune the HAVEGE algorithm for maximum sensitivity. If these sizes
124 not specified, haveged will attempt to determine the sizes dynamically
125 from the Linux sysfs and/or cpuid instruction with a fallback to a com‐
126 piled default if no better information is not available.
127
128 The haveged RNG includes a run time test facility based upon the test
129 suite defined in the AIS-31 specification from the The German Federal
130 Office for Information Security (Bundesamt für Sicherheit in der Infor‐
131 mationstechnik). The test suite consists of 11 statistical tests pack‐
132 aged into two test suites ("A" and "B"). The tests can be run at ini‐
133 tialization (a.k.a. a "tot" test), or continuously to monitor all out‐
134 put. Failure of a suite will abort operation unless the behavior is
135 explicitly waived in the test setup options.
136
137 Procedure A contains 6 test procedures designed to ensure statistically
138 inconspicuous behavior. The first test, "test0", checks the disjointed‐
139 ness of 65k six-bit strings. The remainder of the procedure consists of
140 257 repetitions of the FIPS140-1 tests, "test1" through "test4", and an
141 auto-correlation test, "test5". The fixed size of the Procedure A input
142 makes it ideal for continuous use, but the procedure is slow and
143 resource intensive. In particular, test5 is several orders of magnitude
144 slower than any other individual AIS test. As an alternative for those
145 who cannot tolerate this load, procedure A variants A<n> are provided
146 that execute all included tests but execute test5 only every 2^n repe‐
147 titions. Even with this accommodation, procedure A is much slower than
148 procedure B.
149
150
151 Procedure B contains 5 tests, "test6a", "test6b', "test7a", "test7b",
152 and "test8". The first 4 tests verify the expected frequencies for sam‐
153 ples 100,000 one-step, two-step, three-step, and four-step bit transi‐
154 tions. The last test provides an empirical entropy estimate of the
155 input. The input required to complete these tests is variable, result‐
156 ing in an ever-shifting bit alignment that guards against buffering
157 artifacts.
158
159
160 Each test procedure requires more than 1MB of data. Test input is man‐
161 aged by a bit index into the collection buffer. An independent index
162 manages where integer output is taken from the same buffer. A buffer
163 fill is triggered when the output index indicates all data has been
164 extracted from the buffer. Online testing takes place after the buffer
165 has been refilled but before the output index update allows output to
166 resume. If any online test fails while processing the buffer, the buf‐
167 fer will be refilled and reprocessed until any retry is complete and
168 the buffer contains no failed online tests or the online test procedure
169 has failed and the RNG is considered broken.
170
171
172 It is recommend to run both AIS test procedures at start-up to ensure
173 the RNG is properly initialized. If resources are in short supply,
174 omitting procedure A will save memory and time, with little risk in
175 circumstances where output is mixed with other sources in /dev/random
176 or other csprng. Continuous testing is also recommended where the
177 throughput penalty is acceptable. One recent assessment of testing
178 throughput costs is shown below.
179
180
181 haveged -n0 -oc | pv > /dev/null 400MiB/s
182
183 haveged -n0 -ocb | pv > /dev/null 70MiB/s
184
185 haveged -n0 -oca8b | pv > /dev/null 13MiB/s
186
187 haveged -n0 -oca8 | pv > /dev/null 8MiB/s
188
189 haveged -n0 -oca | pv > /dev/null 100kiB/s
190
191 Continuous testing also exposes another possible pitfall. Even an ideal
192 RNG has a 10e-4 chance of failing either test procedure. The strict
193 retry policy of AIS-31 is designed to guarantee an ideal RNG will
194 "almost never" fail a test procedure. A single retry is mandated only
195 to recover from a previous attempt that experienced a single individual
196 test failure. The haveged implementation logs all retries and termi‐
197 nates on test procedure failures unless the procedure has been flagged
198 as advisory by the "w" argument (see --onlinetest in haveged(8) ). Lit‐
199 tle evidence of the retry mechanism is seen unless large data sets are
200 processed. Procedure A is too slow to be practical in these situations,
201 so procedure B has been the best studied. Retries are observed at the
202 approximate rate of 0.7-0.8 failures/GB, mostly in the test7 multi-step
203 transition checks.
204
205 The probability that procedureB will fail two times in a row (in which
206 case the program will be terminated unless w option was specified) is
207 4e-7 which is expected to happen at an approximate rate of once per
208 3,000 TB. When producing large amounts of data in order of TBs it's
209 recommended to use -w option to make sure that program will not prema‐
210 turely terminate because of a failed retry and carefully examine the
211 stderr output for any problems.
212
213
215 Tuning information may be extracted from the following virtual file
216 paths if tuning is required and the path exists.
217
218 /proc/cpuinfo
219
220 /proc/self/status
221
222 /sys/devices/system/cpu/online
223
224 /sys/devices/system/cpu/cpu%d/cache/index%d/level
225
226
228 To enable diagnostic output, supply a msg_out callback when creating
229 the handle. All possible errors are enumerated in havege.h and repro‐
230 duced here for reference.
231
232 01 H_NOHANDLE
233 No memory for handle
234
235 02 H_NOBUF
236 Output buffer allocation failed
237
238 03 H_NOINIT
239 Semaphore init failed
240
241 04 H_NOCOLLECT
242 Collector allocation failed
243
244 05 H_NOWALK
245 Walk buffer allocation failed
246
247 06 H_NOTESTSPEC
248 Invalid test specification
249
250 07 H_NOTESTINIT
251 Test setup failed
252
253 08 H_NOTESTMEM
254 Unable to allocate test memory
255
256 09 H_NOTESTTOT
257 Power on (i.e. 'tot') test failed
258
259 10 H_NOTESTRUN
260 Continuous test failed
261
262 11 H_NOCORES
263 Too many cores specified
264
265 12 H_NOTASK
266 Unable to create child task
267
268 13 H_NOWAIT
269 sem_wait failed
270
271 14 H_NOPOST
272 sem_post failed
273
274 15 H_NODONE
275 sem_post done failed
276
277 16 H_NORQST
278 sem_post request failed
279
280 17 H_NOCOMP
281 wait for completion failed
282
283 18 H_EXIT
284 Exit signal
285
286 19 H_NOTIMER
287 Timer failed
288
290 The following minimal program writes the contents of 16 collection buf‐
291 fers of random data to stdout with continuous testing.
292
293 #include <stdio.h>
294 #include <haveged/havege.h>
295 int main(void)
296 {
297 H_PTR havege_state;
298 H_PARAMS havege_parameters = {0};
299 int i, rc;
300
301 if (NULL==havege_version(HAVEGE_PREP_VERSION)) {
302 fprintf(stderr, "Incompatible library %s\n", havege_version(NULL));
303 return 1;
304 }
305 havege_parameters.testSpec="ta8bcb";
306 havege_state = havege_create(&havege_parameters);
307 rc = havege_state==NULL? H_NOHANDLE : havege_state->error;
308 if (H_NOERR==rc) {
309 if (0==havege_run(havege_state)) {
310 H_UINT *buf = havege_state->io_buf;
311 int size = havege_state->i_readSz /sizeof(H_UINT);
312 char info[256];
313
314 for(i=0;i<16;i++) {
315 rc = havege_rng(havege_state, buf, size);
316 if (rc != size) {
317 fprintf(stderr, "RNG read failed %d\n", havege_state->error);
318 break;
319 }
320 rc = fwrite(buf, 1, size*sizeof(H_UINT), stdout);
321 if ( rc < size ) {
322 fprintf(stderr, "Write failed\n");
323 break;
324 }
325 }
326 i = havege_status_dump(havege_state, H_SD_TOPIC_TEST, info, sizeof(info));
327 info[i++] = '\n';
328 havege_status_dump(havege_state, H_SD_TOPIC_SUM, info+i, sizeof(info)-i);
329 fprintf(stderr, "%s\n", info);
330 }
331 else fprintf(stderr, "Initialize failed %d\n", havege_state->error);
332 havege_destroy(havege_state);
333 }
334 else fprintf(stderr, "Create failed %d\n", rc);
335 return rc;
336 }
337
338 Defaults are provided for all inputs to havege_create() as documented
339 in havege.h. In this case for example, (16*4kb=65kb) will be written to
340 stdout because the default size for i_readsz in 4kb.
341
342
344 haveged(8)
345
346
348 haveged(8) references provides a basic reading list. The following
349 links are suggested as sources for further exploration.
350
351 The origins of the HAVEGE concept can be found at:
352 http://www.irisa.fr/caps/projects/hipsor/
353
354 Tuning concepts inspired by (the complexity) at:
355 http://www.open-mpi.org/projects/hwloc/
356
357 Reference documentation for the AIS-31 test suite can be found at:
358 https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Zerti‐
359 fizierung/Interpretationen/AIS_31_Functionality_classes_for_ran‐
360 dom_number_generators_e.pdf?__blob=publicationFile
361
362 Implementation and design information available at:
363 http://www.issihosts.com/haveged/
364
365
366
368 Gary Wuertz <gary@issiweb.com> and Jirka Hladky <hladky jiri AT gmail
369 DOT com>
370
371
372
373version 1.1 February 10, 2014 libhavege(3)