summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2018-03-20 19:42:39 +0100
committerMichael Brown2018-03-20 19:56:01 +0100
commit0d35411f88dd37dda755d52b4549337f8299c698 (patch)
tree9129fb0cee236f97af83024b5910cb2cb2b83b08 /src/include
parent[golan] Set log_max_qp to 1 (diff)
downloadipxe-0d35411f88dd37dda755d52b4549337f8299c698.tar.gz
ipxe-0d35411f88dd37dda755d52b4549337f8299c698.tar.xz
ipxe-0d35411f88dd37dda755d52b4549337f8299c698.zip
[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>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ipxe/efi/efi_entropy.h4
-rw-r--r--src/include/ipxe/entropy.h26
-rw-r--r--src/include/ipxe/linux/linux_entropy.h4
-rw-r--r--src/include/ipxe/null_entropy.h4
4 files changed, 29 insertions, 9 deletions
diff --git a/src/include/ipxe/efi/efi_entropy.h b/src/include/ipxe/efi/efi_entropy.h
index 39a66735..5b16fd7f 100644
--- a/src/include/ipxe/efi/efi_entropy.h
+++ b/src/include/ipxe/efi/efi_entropy.h
@@ -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 */
diff --git a/src/include/ipxe/entropy.h b/src/include/ipxe/entropy.h
index beeb3abf..d2e3ce50 100644
--- a/src/include/ipxe/entropy.h
+++ b/src/include/ipxe/entropy.h
@@ -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.
diff --git a/src/include/ipxe/linux/linux_entropy.h b/src/include/ipxe/linux/linux_entropy.h
index afef6fe1..ea8c1f16 100644
--- a/src/include/ipxe/linux/linux_entropy.h
+++ b/src/include/ipxe/linux/linux_entropy.h
@@ -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 */
diff --git a/src/include/ipxe/null_entropy.h b/src/include/ipxe/null_entropy.h
index 91adefa6..5a6bb621 100644
--- a/src/include/ipxe/null_entropy.h
+++ b/src/include/ipxe/null_entropy.h
@@ -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