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,7 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
22 22
  *
23 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 26
 ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
27 27
 
28 28
 	/* The min-entropy has been measured on several platforms
@@ -38,7 +38,7 @@ ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
38 38
 	 * safety margin to allow for some potential non-independence
39 39
 	 * of samples.
40 40
 	 */
41
-	return 1.3;
41
+	return MIN_ENTROPY ( 1.3 );
42 42
 }
43 43
 
44 44
 extern uint8_t rtc_sample ( void );

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

@@ -70,7 +70,8 @@ repetition_count_cutoff ( void ) {
70 70
 	 * where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
71 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 76
 	/* Round up to a whole number of repetitions.  We don't have
76 77
 	 * the ceil() function available, so do the rounding by hand.
@@ -237,7 +238,7 @@ adaptive_proportion_cutoff ( void ) {
237 238
 
238 239
 	/* Look up cutoff value in cutoff table */
239 240
 	n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
240
-	h = min_entropy_per_sample();
241
+	h = ( min_entropy_per_sample() / MIN_ENTROPY_SCALE );
241 242
 	cutoff = adaptive_proportion_cutoff_lookup ( n, h );
242 243
 
243 244
 	/* Fail unless cutoff value is a build-time constant */

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

@@ -22,14 +22,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
22 22
  *
23 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 26
 ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
27 27
 
28 28
 	/* We use essentially the same mechanism as for the BIOS
29 29
 	 * RTC-based entropy source, and so assume the same
30 30
 	 * min-entropy per sample.
31 31
 	 */
32
-	return 1.3;
32
+	return MIN_ENTROPY ( 1.3 );
33 33
 }
34 34
 
35 35
 #endif /* _IPXE_EFI_ENTROPY_H */

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

@@ -52,6 +52,25 @@ typedef uint8_t noise_sample_t;
52 52
 /** An entropy sample */
53 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 74
 /* Include all architecture-independent entropy API headers */
56 75
 #include <ipxe/null_entropy.h>
57 76
 #include <ipxe/efi/efi_entropy.h>
@@ -87,7 +106,7 @@ void entropy_disable ( void );
87 106
  *
88 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 112
  * Get noise sample
@@ -142,7 +161,7 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
142 161
 
143 162
 	/* Sanity checks */
144 163
 	linker_assert ( ( min_entropy_per_sample() <=
145
-			  ( 8 * sizeof ( noise_sample_t ) ) ),
164
+			  MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
146 165
 			min_entropy_per_sample_is_impossibly_high );
147 166
 	linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ),
148 167
 			entropy_buffer_too_small );
@@ -151,7 +170,8 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
151 170
 	min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
152 171
 
153 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 176
 	/* Round up to a whole number of samples.  We don't have the
157 177
 	 * ceil() function available, so do the rounding by hand.

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

@@ -20,7 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
20 20
  *
21 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 24
 ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
25 25
 
26 26
 	/* linux_get_noise() reads a single byte from /dev/random,
@@ -28,7 +28,7 @@ ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
28 28
 	 * entropy is available.  We therefore assume that each sample
29 29
 	 * contains exactly 8 bits of entropy.
30 30
 	 */
31
-	return 8.0;
31
+	return MIN_ENTROPY ( 8.0 );
32 32
 }
33 33
 
34 34
 #endif /* _IPXE_LINUX_ENTROPY_H */

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

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

Loading…
Cancel
Save