Browse Source

[rng] Use fixed-point calculations for min-entropy quantities

We currently perform various min-entropy calculations using build-time
floating-point arithmetic.  No floating-point code ends up in the
final binary, since the results are eventually converted to integers
and asserted to be compile-time constants.

Though this mechanism is undoubtedly cute, it inhibits us from using
"-mno-sse" to prevent the use of SSE registers by the compiler.

Fix by using fixed-point arithmetic instead.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
0d35411f88

+ 2
- 2
src/arch/x86/include/ipxe/rtc_entropy.h View File

22
  *
22
  *
23
  * @ret min_entropy	min-entropy of each sample
23
  * @ret min_entropy	min-entropy of each sample
24
  */
24
  */
25
-static inline __always_inline double
25
+static inline __always_inline min_entropy_t
26
 ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
26
 ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
27
 
27
 
28
 	/* The min-entropy has been measured on several platforms
28
 	/* The min-entropy has been measured on several platforms
38
 	 * safety margin to allow for some potential non-independence
38
 	 * safety margin to allow for some potential non-independence
39
 	 * of samples.
39
 	 * of samples.
40
 	 */
40
 	 */
41
-	return 1.3;
41
+	return MIN_ENTROPY ( 1.3 );
42
 }
42
 }
43
 
43
 
44
 extern uint8_t rtc_sample ( void );
44
 extern uint8_t rtc_sample ( void );

+ 3
- 2
src/crypto/entropy.c View File

70
 	 * where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
70
 	 * where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
71
 	 * 2011 Draft) Section 8.5.2.1.3.1).
71
 	 * 2011 Draft) Section 8.5.2.1.3.1).
72
 	 */
72
 	 */
73
-	max_repetitions = ( 1 + ( 30 / min_entropy_per_sample() ) );
73
+	max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
74
+				  min_entropy_per_sample() ) );
74
 
75
 
75
 	/* Round up to a whole number of repetitions.  We don't have
76
 	/* Round up to a whole number of repetitions.  We don't have
76
 	 * the ceil() function available, so do the rounding by hand.
77
 	 * the ceil() function available, so do the rounding by hand.
237
 
238
 
238
 	/* Look up cutoff value in cutoff table */
239
 	/* Look up cutoff value in cutoff table */
239
 	n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
240
 	n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
240
-	h = min_entropy_per_sample();
241
+	h = ( min_entropy_per_sample() / MIN_ENTROPY_SCALE );
241
 	cutoff = adaptive_proportion_cutoff_lookup ( n, h );
242
 	cutoff = adaptive_proportion_cutoff_lookup ( n, h );
242
 
243
 
243
 	/* Fail unless cutoff value is a build-time constant */
244
 	/* Fail unless cutoff value is a build-time constant */

+ 2
- 2
src/include/ipxe/efi/efi_entropy.h View File

22
  *
22
  *
23
  * @ret min_entropy	min-entropy of each sample
23
  * @ret min_entropy	min-entropy of each sample
24
  */
24
  */
25
-static inline __always_inline double
25
+static inline __always_inline min_entropy_t
26
 ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
26
 ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
27
 
27
 
28
 	/* We use essentially the same mechanism as for the BIOS
28
 	/* We use essentially the same mechanism as for the BIOS
29
 	 * RTC-based entropy source, and so assume the same
29
 	 * RTC-based entropy source, and so assume the same
30
 	 * min-entropy per sample.
30
 	 * min-entropy per sample.
31
 	 */
31
 	 */
32
-	return 1.3;
32
+	return MIN_ENTROPY ( 1.3 );
33
 }
33
 }
34
 
34
 
35
 #endif /* _IPXE_EFI_ENTROPY_H */
35
 #endif /* _IPXE_EFI_ENTROPY_H */

+ 23
- 3
src/include/ipxe/entropy.h View File

52
 /** An entropy sample */
52
 /** An entropy sample */
53
 typedef uint8_t entropy_sample_t;
53
 typedef uint8_t entropy_sample_t;
54
 
54
 
55
+/** An amount of min-entropy
56
+ *
57
+ * Expressed as a fixed-point quantity in order to avoid floating
58
+ * point calculations.
59
+ */
60
+typedef unsigned int min_entropy_t;
61
+
62
+/** Fixed-point scale for min-entropy amounts */
63
+#define MIN_ENTROPY_SCALE ( 1 << 16 )
64
+
65
+/**
66
+ * Construct a min-entropy fixed-point value
67
+ *
68
+ * @v bits		min-entropy in bits
69
+ * @ret min_entropy	min-entropy as a fixed-point value
70
+ */
71
+#define MIN_ENTROPY( bits ) \
72
+	( ( min_entropy_t ) ( (bits) * MIN_ENTROPY_SCALE ) )
73
+
55
 /* Include all architecture-independent entropy API headers */
74
 /* Include all architecture-independent entropy API headers */
56
 #include <ipxe/null_entropy.h>
75
 #include <ipxe/null_entropy.h>
57
 #include <ipxe/efi/efi_entropy.h>
76
 #include <ipxe/efi/efi_entropy.h>
87
  *
106
  *
88
  * This must be a compile-time constant.
107
  * This must be a compile-time constant.
89
  */
108
  */
90
-double min_entropy_per_sample ( void );
109
+min_entropy_t min_entropy_per_sample ( void );
91
 
110
 
92
 /**
111
 /**
93
  * Get noise sample
112
  * Get noise sample
142
 
161
 
143
 	/* Sanity checks */
162
 	/* Sanity checks */
144
 	linker_assert ( ( min_entropy_per_sample() <=
163
 	linker_assert ( ( min_entropy_per_sample() <=
145
-			  ( 8 * sizeof ( noise_sample_t ) ) ),
164
+			  MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
146
 			min_entropy_per_sample_is_impossibly_high );
165
 			min_entropy_per_sample_is_impossibly_high );
147
 	linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ),
166
 	linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ),
148
 			entropy_buffer_too_small );
167
 			entropy_buffer_too_small );
151
 	min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
170
 	min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
152
 
171
 
153
 	/* Calculate number of samples required to contain sufficient entropy */
172
 	/* Calculate number of samples required to contain sufficient entropy */
154
-	min_samples = ( ( min_entropy_bits * 1.0 ) / min_entropy_per_sample() );
173
+	min_samples = ( MIN_ENTROPY ( min_entropy_bits ) /
174
+			min_entropy_per_sample() );
155
 
175
 
156
 	/* Round up to a whole number of samples.  We don't have the
176
 	/* Round up to a whole number of samples.  We don't have the
157
 	 * ceil() function available, so do the rounding by hand.
177
 	 * ceil() function available, so do the rounding by hand.

+ 2
- 2
src/include/ipxe/linux/linux_entropy.h View File

20
  *
20
  *
21
  * @ret min_entropy	min-entropy of each sample
21
  * @ret min_entropy	min-entropy of each sample
22
  */
22
  */
23
-static inline __always_inline double
23
+static inline __always_inline min_entropy_t
24
 ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
24
 ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
25
 
25
 
26
 	/* linux_get_noise() reads a single byte from /dev/random,
26
 	/* linux_get_noise() reads a single byte from /dev/random,
28
 	 * entropy is available.  We therefore assume that each sample
28
 	 * entropy is available.  We therefore assume that each sample
29
 	 * contains exactly 8 bits of entropy.
29
 	 * contains exactly 8 bits of entropy.
30
 	 */
30
 	 */
31
-	return 8.0;
31
+	return MIN_ENTROPY ( 8.0 );
32
 }
32
 }
33
 
33
 
34
 #endif /* _IPXE_LINUX_ENTROPY_H */
34
 #endif /* _IPXE_LINUX_ENTROPY_H */

+ 2
- 2
src/include/ipxe/null_entropy.h View File

30
 	/* Do nothing */
30
 	/* Do nothing */
31
 }
31
 }
32
 
32
 
33
-static inline __always_inline double
33
+static inline __always_inline min_entropy_t
34
 ENTROPY_INLINE ( null, min_entropy_per_sample ) ( void ) {
34
 ENTROPY_INLINE ( null, min_entropy_per_sample ) ( void ) {
35
 	/* Actual amount of min-entropy is zero.  To avoid
35
 	/* Actual amount of min-entropy is zero.  To avoid
36
 	 * division-by-zero errors and to allow compilation of
36
 	 * division-by-zero errors and to allow compilation of
37
 	 * entropy-consuming code, pretend to have 1 bit of entropy in
37
 	 * entropy-consuming code, pretend to have 1 bit of entropy in
38
 	 * each sample.
38
 	 * each sample.
39
 	 */
39
 	 */
40
-	return 1.0;
40
+	return MIN_ENTROPY ( 1.0 );
41
 }
41
 }
42
 
42
 
43
 static inline __always_inline int
43
 static inline __always_inline int

Loading…
Cancel
Save