aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/crypto/rbg.c43
-rw-r--r--src/include/ipxe/rbg.h23
2 files changed, 43 insertions, 23 deletions
diff --git a/src/crypto/rbg.c b/src/crypto/rbg.c
index 4b45b3474..5e1c25f53 100644
--- a/src/crypto/rbg.c
+++ b/src/crypto/rbg.c
@@ -75,6 +75,9 @@ static int rbg_startup ( void ) {
int len;
int rc;
+ /* Record that startup has been attempted (even if unsuccessful) */
+ rbg.started = 1;
+
/* Try to obtain system UUID for use as personalisation
* string, in accordance with ANS X9.82 Part 3-2007 Section
* 8.5.2. If no UUID is available, proceed without a
@@ -98,6 +101,33 @@ static int rbg_startup ( void ) {
}
/**
+ * Generate bits using RBG
+ *
+ * @v additional Additional input
+ * @v additional_len Length of additional input
+ * @v prediction_resist Prediction resistance is required
+ * @v data Output buffer
+ * @v len Length of output buffer
+ * @ret rc Return status code
+ *
+ * This is the RBG_Generate function defined in ANS X9.82 Part 4
+ * (April 2011 Draft) Section 9.1.2.2.
+ */
+int rbg_generate ( const void *additional, size_t additional_len,
+ int prediction_resist, void *data, size_t len ) {
+
+ /* Attempt startup, if not already attempted */
+ if ( ! rbg.started )
+ rbg_startup();
+
+ /* Generate bits. The DRBG will itself return an error if it
+ * is not valid (e.g. due to an instantiation failure).
+ */
+ return drbg_generate ( &rbg.state, additional, additional_len,
+ prediction_resist, data, len );
+}
+
+/**
* Shut down RBG
*
*/
@@ -105,16 +135,21 @@ static void rbg_shutdown ( void ) {
/* Uninstantiate DRBG */
drbg_uninstantiate ( &rbg.state );
+
+ /* Clear startup attempted flag */
+ rbg.started = 0;
}
/** RBG startup function */
static void rbg_startup_fn ( void ) {
- /* Start up RBG. There is no way to report an error at this
- * stage, but a failed startup will result in an invalid DRBG
- * that refuses to generate bits.
+ /* Start up RBG (if not already started on demand). There is
+ * no way to report an error at this stage, but a failed
+ * startup will result in an invalid DRBG that refuses to
+ * generate bits.
*/
- rbg_startup();
+ if ( ! rbg.started )
+ rbg_startup();
}
/** RBG shutdown function */
diff --git a/src/include/ipxe/rbg.h b/src/include/ipxe/rbg.h
index 758238a65..4bf3055d1 100644
--- a/src/include/ipxe/rbg.h
+++ b/src/include/ipxe/rbg.h
@@ -16,28 +16,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct random_bit_generator {
/** DRBG state */
struct drbg_state state;
+ /** Startup has been attempted */
+ int started;
};
extern struct random_bit_generator rbg;
-/**
- * Generate bits using RBG
- *
- * @v additional Additional input
- * @v additional_len Length of additional input
- * @v prediction_resist Prediction resistance is required
- * @v data Output buffer
- * @v len Length of output buffer
- * @ret rc Return status code
- *
- * This is the RBG_Generate function defined in ANS X9.82 Part 4
- * (April 2011 Draft) Section 9.1.2.2.
- */
-static inline int rbg_generate ( const void *additional, size_t additional_len,
- int prediction_resist, void *data,
- size_t len ) {
- return drbg_generate ( &rbg.state, additional, additional_len,
- prediction_resist, data, len );
-}
+extern int rbg_generate ( const void *additional, size_t additional_len,
+ int prediction_resist, void *data, size_t len );
#endif /* _IPXE_RBG_H */