diff options
-rw-r--r-- | src/crypto/rbg.c | 43 | ||||
-rw-r--r-- | src/include/ipxe/rbg.h | 23 |
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 */ |