]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[rng] Use fixed-point calculations for min-entropy quantities
authorMichael Brown <mcb30@ipxe.org>
Tue, 20 Mar 2018 18:42:39 +0000 (20:42 +0200)
committerMichael Brown <mcb30@ipxe.org>
Tue, 20 Mar 2018 18:56:01 +0000 (20:56 +0200)
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>
src/arch/x86/include/ipxe/rtc_entropy.h
src/crypto/entropy.c
src/include/ipxe/efi/efi_entropy.h
src/include/ipxe/entropy.h
src/include/ipxe/linux/linux_entropy.h
src/include/ipxe/null_entropy.h

index e214745d0fb2d9e1356a04dd395041d1ff90bd4a..581abcd3eed5bd46982f569cbccdac018c15844b 100644 (file)
@@ -22,7 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * @ret min_entropy    min-entropy of each sample
  */
-static inline __always_inline double
+static inline __always_inline min_entropy_t
 ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
 
        /* The min-entropy has been measured on several platforms
@@ -38,7 +38,7 @@ ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
         * safety margin to allow for some potential non-independence
         * of samples.
         */
-       return 1.3;
+       return MIN_ENTROPY ( 1.3 );
 }
 
 extern uint8_t rtc_sample ( void );
index 5acbc02584a52d79862981158b2af12cefa748e2..ced6fd9210f90721a2c7c5ff8e8926f53f5f03da 100644 (file)
@@ -70,7 +70,8 @@ repetition_count_cutoff ( void ) {
         * where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
         * 2011 Draft) Section 8.5.2.1.3.1).
         */
-       max_repetitions = ( 1 + ( 30 / min_entropy_per_sample() ) );
+       max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
+                                 min_entropy_per_sample() ) );
 
        /* Round up to a whole number of repetitions.  We don't have
         * the ceil() function available, so do the rounding by hand.
@@ -237,7 +238,7 @@ adaptive_proportion_cutoff ( void ) {
 
        /* Look up cutoff value in cutoff table */
        n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
-       h = min_entropy_per_sample();
+       h = ( min_entropy_per_sample() / MIN_ENTROPY_SCALE );
        cutoff = adaptive_proportion_cutoff_lookup ( n, h );
 
        /* Fail unless cutoff value is a build-time constant */
index 39a667355cfbb4f1d305fd1e447a3c7b721d427a..5b16fd7f91341ab6b4befb70d847d7cce5afc9f6 100644 (file)
@@ -22,14 +22,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * @ret min_entropy    min-entropy of each sample
  */
-static inline __always_inline double
+static inline __always_inline min_entropy_t
 ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
 
        /* We use essentially the same mechanism as for the BIOS
         * RTC-based entropy source, and so assume the same
         * min-entropy per sample.
         */
-       return 1.3;
+       return MIN_ENTROPY ( 1.3 );
 }
 
 #endif /* _IPXE_EFI_ENTROPY_H */
index beeb3abfabfdf8cf8545f35c79c5891c057ec61b..d2e3ce5013155add9f03dd85a44b6b8cfbbb1e00 100644 (file)
@@ -52,6 +52,25 @@ typedef uint8_t noise_sample_t;
 /** An entropy sample */
 typedef uint8_t entropy_sample_t;
 
+/** An amount of min-entropy
+ *
+ * Expressed as a fixed-point quantity in order to avoid floating
+ * point calculations.
+ */
+typedef unsigned int min_entropy_t;
+
+/** Fixed-point scale for min-entropy amounts */
+#define MIN_ENTROPY_SCALE ( 1 << 16 )
+
+/**
+ * Construct a min-entropy fixed-point value
+ *
+ * @v bits             min-entropy in bits
+ * @ret min_entropy    min-entropy as a fixed-point value
+ */
+#define MIN_ENTROPY( bits ) \
+       ( ( min_entropy_t ) ( (bits) * MIN_ENTROPY_SCALE ) )
+
 /* Include all architecture-independent entropy API headers */
 #include <ipxe/null_entropy.h>
 #include <ipxe/efi/efi_entropy.h>
@@ -87,7 +106,7 @@ void entropy_disable ( void );
  *
  * This must be a compile-time constant.
  */
-double min_entropy_per_sample ( void );
+min_entropy_t min_entropy_per_sample ( void );
 
 /**
  * Get noise sample
@@ -142,7 +161,7 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
 
        /* Sanity checks */
        linker_assert ( ( min_entropy_per_sample() <=
-                         ( 8 * sizeof ( noise_sample_t ) ) ),
+                         MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
                        min_entropy_per_sample_is_impossibly_high );
        linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ),
                        entropy_buffer_too_small );
@@ -151,7 +170,8 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
        min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
 
        /* Calculate number of samples required to contain sufficient entropy */
-       min_samples = ( ( min_entropy_bits * 1.0 ) / min_entropy_per_sample() );
+       min_samples = ( MIN_ENTROPY ( min_entropy_bits ) /
+                       min_entropy_per_sample() );
 
        /* Round up to a whole number of samples.  We don't have the
         * ceil() function available, so do the rounding by hand.
index afef6fe195f05776348343414ae898fb5fe490e0..ea8c1f16cc782ef2eea842c7d9a85f3ce5679116 100644 (file)
@@ -20,7 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * @ret min_entropy    min-entropy of each sample
  */
-static inline __always_inline double
+static inline __always_inline min_entropy_t
 ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
 
        /* linux_get_noise() reads a single byte from /dev/random,
@@ -28,7 +28,7 @@ ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
         * entropy is available.  We therefore assume that each sample
         * contains exactly 8 bits of entropy.
         */
-       return 8.0;
+       return MIN_ENTROPY ( 8.0 );
 }
 
 #endif /* _IPXE_LINUX_ENTROPY_H */
index 91adefa697f31f5c43a8b10fa0c8837223d8fa4a..5a6bb621839aeb22de1f504ba082acbf72d7ca74 100644 (file)
@@ -30,14 +30,14 @@ ENTROPY_INLINE ( null, entropy_disable ) ( void ) {
        /* Do nothing */
 }
 
-static inline __always_inline double
+static inline __always_inline min_entropy_t
 ENTROPY_INLINE ( null, min_entropy_per_sample ) ( void ) {
        /* Actual amount of min-entropy is zero.  To avoid
         * division-by-zero errors and to allow compilation of
         * entropy-consuming code, pretend to have 1 bit of entropy in
         * each sample.
         */
-       return 1.0;
+       return MIN_ENTROPY ( 1.0 );
 }
 
 static inline __always_inline int