]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[rng] Add dummy entropy source
authorMichael Brown <mcb30@ipxe.org>
Mon, 23 Jan 2012 15:00:27 +0000 (15:00 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 23 Jan 2012 15:07:46 +0000 (15:07 +0000)
Cryptographic random number generation requires an entropy source,
which is used as the input to a Deterministic Random Bit Generator
(DRBG).

iPXE does not currently have a suitable entropy source.  Provide a
dummy source to allow the DRBG code to be implemented.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/entropy.c [new file with mode: 0644]
src/include/ipxe/entropy.h [new file with mode: 0644]

diff --git a/src/crypto/entropy.c b/src/crypto/entropy.c
new file mode 100644 (file)
index 0000000..86fa897
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Entropy source
+ *
+ */
+
+#include <string.h>
+#include <ipxe/entropy.h>
+
+/**
+ * Obtain entropy input
+ *
+ * @v entropy_bits     Minimum amount of entropy, in bits
+ * @v data             Data buffer
+ * @v min_len          Minimum length of entropy input, in bytes
+ * @v max_len          Maximum length of entropy input, in bytes
+ * @ret len            Length of entropy input, in bytes
+ */
+int get_entropy_input ( unsigned int entropy_bits, void *data, size_t min_len,
+                       size_t max_len ) {
+
+       /* Placeholder to allow remainder of RBG code to be tested */
+       ( void ) entropy_bits;
+       ( void ) min_len;
+       memset ( data, 0x01, max_len );
+
+       return max_len;
+}
diff --git a/src/include/ipxe/entropy.h b/src/include/ipxe/entropy.h
new file mode 100644 (file)
index 0000000..d9b7084
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef _IPXE_ENTROPY_H
+#define _IPXE_ENTROPY_H
+
+/** @file
+ *
+ * Entropy source
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <assert.h>
+
+/** min-entropy per entropy sample
+ *
+ * min-entropy is defined in ANS X9.82 Part 1-2006 Section 8.3 and in
+ * NIST SP 800-90 Appendix C.3 as
+ *
+ *    H_min = -log2 ( p_max )
+ *
+ * where p_max is the probability of the most likely sample value.
+ */
+#define MIN_ENTROPY_PER_SAMPLE 0.16
+
+/** Length of each entropy sample (in bits) */
+#define ENTROPY_SAMPLE_LEN_BITS 12
+
+/**
+ * Calculate entropy buffer size
+ *
+ * @v entropy_bits     Amount of entropy required, in bits
+ * @v min_len          Minimum buffer size, in bytes
+ * @v max_len          Maximum buffer size, in bytes
+ * @ret len            Buffer size, in bytes
+ */
+static inline __attribute__ (( const, always_inline )) size_t
+entropy_bufsize ( unsigned int entropy_bits, size_t min_len, size_t max_len ) {
+       unsigned int min_len_bits;
+       double min_samples;
+       double samples;
+       unsigned int samples_int;
+       unsigned int len_bits;
+       size_t len;
+
+       /* Sanity check */
+       linker_assert ( MIN_ENTROPY_PER_SAMPLE <= ENTROPY_SAMPLE_LEN_BITS,
+                       min_entropy_per_sample_is_impossibly_high );
+
+       /* Calculate number of samples required to contain sufficient entropy */
+       samples = ( ( entropy_bits * 1.0 ) / MIN_ENTROPY_PER_SAMPLE );
+
+       /* Increase to minimum length if necessary */
+       min_len_bits = ( min_len * 8 );
+       min_samples = ( ( min_len_bits * 1.0 ) / ENTROPY_SAMPLE_LEN_BITS );
+       if ( samples < min_samples )
+               samples = min_samples;
+
+       /* Round up to a whole number of samples.  We don't have the
+        * ceil() function available, so do the rounding by hand.
+        */
+       samples_int = samples;
+       if ( samples_int < samples )
+               samples_int++;
+       assert ( samples_int >= samples );
+
+       /* Calculate buffer length in bits */
+       len_bits = ( samples_int * ENTROPY_SAMPLE_LEN_BITS );
+
+       /* Calculate buffer length in bytes (rounding up) */
+       len = ( ( len_bits + 7 ) / 8 );
+
+       /* Check that buffer is within allowed lengths */
+       linker_assert ( len >= min_len, entropy_bufsize_too_short );
+       linker_assert ( len <= max_len, entropy_bufsize_too_long );
+
+       /* Floating-point operations are not allowed in iPXE since we
+        * never set up a suitable environment.  Abort the build
+        * unless the calculated length is a compile-time constant.
+        */
+       linker_assert ( __builtin_constant_p ( len ),
+                       entropy_bufsize_not_constant );
+
+       return len;
+}
+
+extern int get_entropy_input ( unsigned int entropy_bits, void *data,
+                              size_t min_len, size_t max_len );
+
+#endif /* _IPXE_ENTROPY_H */