iPXE
entropy.h
Go to the documentation of this file.
1#ifndef _IPXE_ENTROPY_H
2#define _IPXE_ENTROPY_H
3
4/** @file
5 *
6 * Entropy source
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_SECBOOT ( PERMITTED );
12
13#include <stdint.h>
14#include <string.h>
15#include <assert.h>
16#include <ipxe/hash_df.h>
17#include <ipxe/sha256.h>
18#include <ipxe/tables.h>
19#include <config/entropy.h>
20
21/** A noise sample */
23
24/** An entropy sample */
26
27/** An amount of min-entropy
28 *
29 * Expressed as a fixed-point quantity in order to avoid floating
30 * point calculations.
31 */
32typedef unsigned int min_entropy_t;
33
34/** Fixed-point scale for min-entropy amounts */
35#define MIN_ENTROPY_SCALE ( 1 << 16 )
36
37/**
38 * Construct a min-entropy fixed-point value
39 *
40 * @v bits min-entropy in bits
41 * @ret min_entropy min-entropy as a fixed-point value
42 */
43#define MIN_ENTROPY( bits ) \
44 ( ( min_entropy_t ) ( (bits) * MIN_ENTROPY_SCALE ) )
45
46/**
47 * Repetition count test state
48 *
49 * This is the state for the repetition Count Test defined in ANS
50 * X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
51 */
53 /**
54 * A = the most recently seen sample value
55 */
57 /**
58 * B = the number of times that value A has been seen in a row
59 */
60 unsigned int repetition_count;
61 /**
62 * C = the cutoff value above which the repetition test should fail
63 *
64 * Filled in by entropy_init().
65 */
66 unsigned int cutoff;
67};
68
69/**
70 * Adaptive proportion test state
71 *
72 * This is the state for the Adaptive Proportion Test for the Most
73 * Common Value defined in ANS X9.82 Part 2 (October 2011 Draft)
74 * Section 8.5.2.1.3.
75 */
77 /**
78 * A = the sample value currently being counted
79 */
81 /**
82 * S = the number of samples examined in this run of the test so far
83 */
84 unsigned int sample_count;
85 /**
86 * B = the current number of times that S (sic) has been seen
87 * in the W (sic) samples examined so far
88 */
89 unsigned int repetition_count;
90 /**
91 * C = the cutoff value above which the repetition test should fail
92 *
93 * Filled in by entropy_init().
94 */
95 unsigned int cutoff;
96};
97
98/**
99 * Startup test state
100 *
101 * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
102 * that at least one full cycle of the continuous tests must be
103 * performed at start-up.
104 */
106 /** Number of startup tests performed */
107 unsigned int tested;
108 /**
109 * Number of startup tests required for one full cycle
110 *
111 * Filled in by entropy_init().
112 */
113 unsigned int count;
114};
115
116/** An entropy source */
118 /** Name */
119 const char *name;
120 /**
121 * min-entropy per sample
122 *
123 * min-entropy is defined in ANS X9.82 Part 1-2006 Section 8.3 and in
124 * NIST SP 800-90 Appendix C.3 as
125 *
126 * H_min = -log2 ( p_max )
127 *
128 * where p_max is the probability of the most likely sample value.
129 *
130 * Filled in by entropy_init().
131 */
133 /** Repetition count test state */
135 /** Adaptive proportion test state */
137 /** Startup test state */
139 /**
140 * Failure status (if any)
141 *
142 * Any failure of an entropy source is regarded as permanent.
143 */
144 int rc;
145
146 /**
147 * Enable entropy gathering
148 *
149 * @ret rc Return status code
150 */
151 int ( * enable ) ( void );
152 /**
153 * Disable entropy gathering
154 *
155 */
156 void ( * disable ) ( void );
157 /**
158 * Get noise sample
159 *
160 * @ret noise Noise sample
161 * @ret rc Return status code
162 *
163 * This is the GetNoise function defined in ANS X9.82 Part 2
164 * (October 2011 Draft) Section 6.5.2.
165 */
166 int ( * get_noise ) ( noise_sample_t *noise );
167};
168
169/** Entropy source table */
170#define ENTROPY_SOURCES __table ( struct entropy_source, "entropy_sources" )
171
172/** Declare an entropy source */
173#define __entropy_source( order ) __table_entry ( ENTROPY_SOURCES, order )
174
175/** @defgroup entropy_source_order Entropy source order
176 *
177 * @{
178 */
179
180#define ENTROPY_PREFERRED 01 /**< Preferred entropy source */
181#define ENTROPY_NORMAL 02 /**< Normal entropy source */
182#define ENTROPY_FALLBACK 03 /**< Fallback entropy source */
183
184/** @} */
185
186extern int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
187 size_t tmp_len );
188
189/** Use SHA-256 as the underlying hash algorithm for Hash_df
190 *
191 * Hash_df using SHA-256 is an Approved algorithm in ANS X9.82.
192 */
193#define entropy_hash_df_algorithm sha256_algorithm
194
195/** Underlying hash algorithm output length (in bytes) */
196#define ENTROPY_HASH_DF_OUTLEN_BYTES SHA256_DIGEST_SIZE
197
198/**
199 * Get noise sample
200 *
201 * @v source Entropy source
202 * @ret noise Noise sample
203 * @ret rc Return status code
204 *
205 * This is the GetNoise function defined in ANS X9.82 Part 2
206 * (October 2011 Draft) Section 6.5.2.
207 */
208static inline __attribute__ (( always_inline )) int
209get_noise ( struct entropy_source *source, noise_sample_t *noise ) {
210
211 return source->get_noise ( noise );
212}
213
214/**
215 * Obtain entropy input
216 *
217 * @v min_entropy_bits Minimum amount of entropy, in bits
218 * @v data Data buffer
219 * @v min_len Minimum length of entropy input, in bytes
220 * @v max_len Maximum length of entropy input, in bytes
221 * @ret len Length of entropy input, in bytes, or negative error
222 *
223 * This is the implementation of the Get_entropy_input function (using
224 * an entropy source as the source of entropy input and condensing
225 * each entropy source output after each GetEntropy call) as defined
226 * in ANS X9.82 Part 4 (April 2011 Draft) Section 13.3.4.2.
227 *
228 * This function is inlined since the entropy amount and length inputs
229 * are always compile-time constants.
230 */
231static inline __attribute__ (( always_inline )) int
232get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
233 size_t max_len ) {
234 size_t tmp_len = ( ( ( min_entropy_bits * 2 ) + 7 ) / 8 );
235 uint8_t tmp_buf[ tmp_len ];
236 uint8_t *tmp = ( ( tmp_len > max_len ) ? tmp_buf : data );
237 unsigned int n;
238 int rc;
239
240 /* Sanity check */
241 build_assert ( min_entropy_bits <= ( 8 * max_len ) );
242
243 /* Round up minimum entropy to an integral number of bytes */
244 min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
245
246 /* (Unnumbered). The output length of the hash function shall
247 * meet or exceed the security strength indicated by the
248 * min_entropy parameter.
249 */
251 min_entropy_bits );
252
253 /* 1. If ( min_length > max_length ), then return ( FAILURE, Null ) */
254 build_assert ( min_len <= max_len );
255
256 /* 2. n = 2 * min_entropy */
257 n = ( 2 * min_entropy_bits );
258
259 /* 3. entropy_total = 0
260 * 4. tmp = a fixed n-bit value, such as 0^n
261 * 5. While ( entropy_total < min_entropy )
262 * 5.1. ( status, entropy_bitstring, assessed_entropy )
263 * = GetEntropy()
264 * 5.2. If status indicates an error, return ( status, Null )
265 * 5.3. nonce = MakeNextNonce()
266 * 5.4. tmp = tmp XOR df ( ( nonce || entropy_bitstring ), n )
267 * 5.5. entropy_total = entropy_total + assessed_entropy
268 *
269 * (The implementation of these steps is inside the function
270 * get_entropy_input_tmp().)
271 */
272 build_assert ( __builtin_constant_p ( tmp_len ) );
273 build_assert ( n == ( 8 * tmp_len ) );
274 if ( ( rc = get_entropy_input_tmp ( MIN_ENTROPY ( min_entropy_bits ),
275 tmp, tmp_len ) ) != 0 ) {
276 return rc;
277 }
278
279 /* 6. If ( n < min_length ), then tmp = tmp || 0^(min_length-n)
280 * 7. If ( n > max_length ), then tmp = df ( tmp, max_length )
281 * 8. Return ( SUCCESS, tmp )
282 */
283 if ( tmp_len < min_len ) {
284 /* (Data is already in-place.) */
285 build_assert ( data == tmp );
286 memset ( ( data + tmp_len ), 0, ( min_len - tmp_len ) );
287 return min_len;
288 } else if ( tmp_len > max_len ) {
289 build_assert ( tmp == tmp_buf );
291 data, max_len );
292 return max_len;
293 } else {
294 /* (Data is already in-place.) */
295 build_assert ( data == tmp );
296 return tmp_len;
297 }
298}
299
300/**
301 * Calculate cutoff value for the repetition count test
302 *
303 * @v min_entropy_per_sample Min-entropy per sample
304 * @ret cutoff Cutoff value
305 *
306 * This is the cutoff value for the Repetition Count Test defined in
307 * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
308 */
309static inline __attribute__ (( always_inline )) unsigned int
311 double max_repetitions;
312 unsigned int cutoff;
313
314 /* The cutoff formula for the repetition test is:
315 *
316 * C = ( 1 + ( -log2(W) / H_min ) )
317 *
318 * where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
319 * 2011 Draft) Section 8.5.2.1.3.1).
320 */
321 max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
322 min_entropy_per_sample ) );
323
324 /* Round up to a whole number of repetitions. We don't have
325 * the ceil() function available, so do the rounding by hand.
326 */
327 cutoff = max_repetitions;
328 if ( cutoff < max_repetitions )
329 cutoff++;
330 build_assert ( cutoff >= max_repetitions );
331
332 /* Floating-point operations are not allowed in iPXE since we
333 * never set up a suitable environment. Abort the build
334 * unless the calculated number of repetitions is a
335 * compile-time constant.
336 */
337 build_assert ( __builtin_constant_p ( cutoff ) );
338
339 return cutoff;
340}
341
342/**
343 * Window size for the adaptive proportion test
344 *
345 * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.1 allows
346 * five possible window sizes: 16, 64, 256, 4096 and 65536.
347 *
348 * We expect to generate relatively few (<256) entropy samples during
349 * a typical iPXE run; the use of a large window size would mean that
350 * the test would never complete a single cycle. We use a window size
351 * of 64, which is the smallest window size that permits values of
352 * H_min down to one bit per sample.
353 */
354#define ADAPTIVE_PROPORTION_WINDOW_SIZE 64
355
356/**
357 * Combine adaptive proportion test window size and min-entropy
358 *
359 * @v n N (window size)
360 * @v h H (min-entropy)
361 * @ret n_h (N,H) combined value
362 */
363#define APC_N_H( n, h ) ( ( (n) << 8 ) | (h) )
364
365/**
366 * Define a row of the adaptive proportion cutoff table
367 *
368 * @v h H (min-entropy)
369 * @v c16 Cutoff for N=16
370 * @v c64 Cutoff for N=64
371 * @v c256 Cutoff for N=256
372 * @v c4096 Cutoff for N=4096
373 * @v c65536 Cutoff for N=65536
374 */
375#define APC_TABLE_ROW( h, c16, c64, c256, c4096, c65536) \
376 case APC_N_H ( 16, h ) : return c16; \
377 case APC_N_H ( 64, h ) : return c64; \
378 case APC_N_H ( 256, h ) : return c256; \
379 case APC_N_H ( 4096, h ) : return c4096; \
380 case APC_N_H ( 65536, h ) : return c65536;
381
382/** Value used to represent "N/A" in adaptive proportion cutoff table */
383#define APC_NA 0
384
385/**
386 * Look up value in adaptive proportion test cutoff table
387 *
388 * @v n N (window size)
389 * @v h H (min-entropy)
390 * @ret cutoff Cutoff
391 *
392 * This is the table of cutoff values defined in ANS X9.82 Part 2
393 * (October 2011 Draft) Section 8.5.2.1.3.1.2.
394 */
395static inline __attribute__ (( always_inline )) unsigned int
396entropy_adaptive_proportion_cutoff_lookup ( unsigned int n, unsigned int h ) {
397 switch ( APC_N_H ( n, h ) ) {
398 APC_TABLE_ROW ( 1, APC_NA, 51, 168, 2240, 33537 );
399 APC_TABLE_ROW ( 2, APC_NA, 35, 100, 1193, 17053 );
400 APC_TABLE_ROW ( 3, 10, 24, 61, 643, 8705 );
401 APC_TABLE_ROW ( 4, 8, 16, 38, 354, 4473 );
402 APC_TABLE_ROW ( 5, 6, 12, 25, 200, 2321 );
403 APC_TABLE_ROW ( 6, 5, 9, 17, 117, 1220 );
404 APC_TABLE_ROW ( 7, 4, 7, 15, 71, 653 );
405 APC_TABLE_ROW ( 8, 4, 5, 9, 45, 358 );
406 APC_TABLE_ROW ( 9, 3, 4, 7, 30, 202 );
407 APC_TABLE_ROW ( 10, 3, 4, 5, 21, 118 );
408 APC_TABLE_ROW ( 11, 2, 3, 4, 15, 71 );
409 APC_TABLE_ROW ( 12, 2, 3, 4, 11, 45 );
410 APC_TABLE_ROW ( 13, 2, 2, 3, 9, 30 );
411 APC_TABLE_ROW ( 14, 2, 2, 3, 7, 21 );
412 APC_TABLE_ROW ( 15, 1, 2, 2, 6, 15 );
413 APC_TABLE_ROW ( 16, 1, 2, 2, 5, 11 );
414 APC_TABLE_ROW ( 17, 1, 1, 2, 4, 9 );
415 APC_TABLE_ROW ( 18, 1, 1, 2, 4, 7 );
416 APC_TABLE_ROW ( 19, 1, 1, 1, 3, 6 );
417 APC_TABLE_ROW ( 20, 1, 1, 1, 3, 5 );
418 default:
419 return APC_NA;
420 }
421}
422
423/**
424 * Calculate cutoff value for the adaptive proportion test
425 *
426 * @v min_entropy_per_sample Min-entropy per sample
427 * @ret cutoff Cutoff value
428 *
429 * This is the cutoff value for the Adaptive Proportion Test defined
430 * in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.2.
431 */
432static inline __attribute__ (( always_inline )) unsigned int
434 unsigned int h;
435 unsigned int n;
436 unsigned int cutoff;
437
438 /* Look up cutoff value in cutoff table */
440 h = ( min_entropy_per_sample / MIN_ENTROPY_SCALE );
442
443 /* Fail unless cutoff value is a compile-time constant */
444 build_assert ( __builtin_constant_p ( cutoff ) );
445
446 /* Fail if cutoff value is N/A */
447 build_assert ( cutoff != APC_NA );
448
449 return cutoff;
450}
451
452/**
453 * Calculate number of samples required for startup tests
454 *
455 * @v repetition_count_cutoff Repetition count test cutoff value
456 * @v adaptive_proportion_cutoff Adaptive proportion test cutoff value
457 * @ret num_samples Number of samples required
458 *
459 * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
460 * that at least one full cycle of the continuous tests must be
461 * performed at start-up.
462 */
463static inline __attribute__ (( always_inline )) unsigned int
464entropy_startup_test_count ( unsigned int repetition_count_cutoff,
465 unsigned int adaptive_proportion_cutoff ) {
466 unsigned int num_samples;
467
468 /* At least max(N,C) samples shall be generated by the noise
469 * source for start-up testing.
470 */
471 num_samples = repetition_count_cutoff;
472 if ( num_samples < adaptive_proportion_cutoff )
473 num_samples = adaptive_proportion_cutoff;
474 build_assert ( __builtin_constant_p ( num_samples ) );
475
476 return num_samples;
477}
478
479/**
480 * Initialise entropy source
481 *
482 * @v source Entropy source
483 * @v min_entropy_per_sample Min-entropy per sample
484 *
485 * The cutoff value calculations for the repetition count test and the
486 * adaptive proportion test are provided as static inline functions
487 * since the results will always be compile-time constants.
488 */
489static inline __attribute__ (( always_inline )) void
491 min_entropy_t min_entropy_per_sample ) {
492 unsigned int repetition_count_cutoff;
493 unsigned int adaptive_proportion_cutoff;
494 unsigned int startup_test_count;
495
496 /* Sanity check */
497 build_assert ( min_entropy_per_sample > MIN_ENTROPY ( 0 ) );
498 build_assert ( min_entropy_per_sample <=
499 MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) );
500
501 /* Calculate test cutoff values */
502 repetition_count_cutoff =
503 entropy_repetition_count_cutoff ( min_entropy_per_sample );
504 adaptive_proportion_cutoff =
505 entropy_adaptive_proportion_cutoff ( min_entropy_per_sample );
506 startup_test_count =
507 entropy_startup_test_count ( repetition_count_cutoff,
508 adaptive_proportion_cutoff );
509
510 /* Record min-entropy per sample and test cutoff values */
511 source->min_entropy_per_sample = min_entropy_per_sample;
512 source->repetition_count_test.cutoff = repetition_count_cutoff;
513 source->adaptive_proportion_test.cutoff = adaptive_proportion_cutoff;
514 source->startup_test.count = startup_test_count;
515}
516
517extern int entropy_enable ( struct entropy_source *source );
518extern void entropy_disable ( struct entropy_source *source );
519extern int get_noise ( struct entropy_source *source, noise_sample_t *noise );
520
521#endif /* _IPXE_ENTROPY_H */
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
Assertions.
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition assert.h:77
Entropy API configuration.
uint8_t data[48]
Additional event data.
Definition ena.h:11
int get_entropy_input_tmp(min_entropy_t min_entropy, uint8_t *tmp, size_t tmp_len)
Obtain entropy input temporary buffer.
Definition entropy.c:426
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
void hash_df(struct digest_algorithm *hash, const void *input, size_t input_len, void *output, size_t output_len)
Distribute entropy throughout a buffer.
Definition hash_df.c:85
Hash-based derivation function (Hash_df)
#define __attribute__(x)
Definition compiler.h:10
static void entropy_init(struct entropy_source *source, min_entropy_t min_entropy_per_sample)
Initialise entropy source.
Definition entropy.h:490
#define MIN_ENTROPY(bits)
Construct a min-entropy fixed-point value.
Definition entropy.h:43
uint8_t entropy_sample_t
An entropy sample.
Definition entropy.h:25
static unsigned int entropy_adaptive_proportion_cutoff(min_entropy_t min_entropy_per_sample)
Calculate cutoff value for the adaptive proportion test.
Definition entropy.h:433
static int get_entropy_input(unsigned int min_entropy_bits, void *data, size_t min_len, size_t max_len)
Obtain entropy input.
Definition entropy.h:232
void entropy_disable(struct entropy_source *source)
Disable entropy gathering.
Definition entropy.c:386
static unsigned int entropy_adaptive_proportion_cutoff_lookup(unsigned int n, unsigned int h)
Look up value in adaptive proportion test cutoff table.
Definition entropy.h:396
#define MIN_ENTROPY_SCALE
Fixed-point scale for min-entropy amounts.
Definition entropy.h:35
#define APC_N_H(n, h)
Combine adaptive proportion test window size and min-entropy.
Definition entropy.h:363
#define entropy_hash_df_algorithm
Use SHA-256 as the underlying hash algorithm for Hash_df.
Definition entropy.h:193
int get_entropy_input_tmp(min_entropy_t min_entropy, uint8_t *tmp, size_t tmp_len)
Obtain entropy input temporary buffer.
Definition entropy.c:426
#define APC_TABLE_ROW(h, c16, c64, c256, c4096, c65536)
Define a row of the adaptive proportion cutoff table.
Definition entropy.h:375
uint8_t noise_sample_t
A noise sample.
Definition entropy.h:22
static unsigned int entropy_startup_test_count(unsigned int repetition_count_cutoff, unsigned int adaptive_proportion_cutoff)
Calculate number of samples required for startup tests.
Definition entropy.h:464
#define ENTROPY_HASH_DF_OUTLEN_BYTES
Underlying hash algorithm output length (in bytes)
Definition entropy.h:196
int entropy_enable(struct entropy_source *source)
Enable entropy gathering.
Definition entropy.c:303
#define APC_NA
Value used to represent "N/A" in adaptive proportion cutoff table.
Definition entropy.h:383
unsigned int min_entropy_t
An amount of min-entropy.
Definition entropy.h:32
static unsigned int entropy_repetition_count_cutoff(min_entropy_t min_entropy_per_sample)
Calculate cutoff value for the repetition count test.
Definition entropy.h:310
static int get_noise(struct entropy_source *source, noise_sample_t *noise)
Get noise sample.
Definition entropy.h:209
#define ADAPTIVE_PROPORTION_WINDOW_SIZE
Window size for the adaptive proportion test.
Definition entropy.h:354
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
unsigned long tmp
Definition linux_pci.h:65
uint8_t h
Definition registers.h:4
SHA-256 algorithm.
Adaptive proportion test state.
Definition entropy.h:76
noise_sample_t current_counted_sample
A = the sample value currently being counted.
Definition entropy.h:80
unsigned int cutoff
C = the cutoff value above which the repetition test should fail.
Definition entropy.h:95
unsigned int repetition_count
B = the current number of times that S (sic) has been seen in the W (sic) samples examined so far.
Definition entropy.h:89
unsigned int sample_count
S = the number of samples examined in this run of the test so far.
Definition entropy.h:84
Repetition count test state.
Definition entropy.h:52
noise_sample_t most_recent_sample
A = the most recently seen sample value.
Definition entropy.h:56
unsigned int cutoff
C = the cutoff value above which the repetition test should fail.
Definition entropy.h:66
unsigned int repetition_count
B = the number of times that value A has been seen in a row.
Definition entropy.h:60
An entropy source.
Definition entropy.h:117
struct entropy_repetition_count_test repetition_count_test
Repetition count test state.
Definition entropy.h:134
min_entropy_t min_entropy_per_sample
min-entropy per sample
Definition entropy.h:132
int rc
Failure status (if any)
Definition entropy.h:144
struct entropy_startup_test startup_test
Startup test state.
Definition entropy.h:138
void(* disable)(void)
Disable entropy gathering.
Definition entropy.h:156
const char * name
Name.
Definition entropy.h:119
int(* get_noise)(noise_sample_t *noise)
Get noise sample.
Definition entropy.h:166
struct entropy_adaptive_proportion_test adaptive_proportion_test
Adaptive proportion test state.
Definition entropy.h:136
int(* enable)(void)
Enable entropy gathering.
Definition entropy.h:151
Startup test state.
Definition entropy.h:105
unsigned int count
Number of startup tests required for one full cycle.
Definition entropy.h:113
unsigned int tested
Number of startup tests performed.
Definition entropy.h:107
Linker tables.