From 5e0b254fc61c328d1ae2729b0cc7392165790f3c Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 1 May 2004 00:00:02 +0000 Subject: [PATCH] Add a mutex for the shared static storage used by Yarrow * crypto_libinit.c (initialized): Variable deleted. (cryptoint_initialize_library, cryptoint_cleanup_library): Use new macros for automatic shared library init/fini functions. (prng_cleanup): Declaration deleted. (krb5int_prng_init, krb5int_prng_cleanup): Declare. (cryptoint_initialize_library): Call krb5int_prng_init. (krb5int_crypto_init): New function, checks that cryptoint_initialize_library was called successfully. (cryptoint_cleanup_library): Call krb5int_prng_cleanup only if the initializer ran. * crypto_libinit.h: Deleted. * prng.c: Include k5-thread.h. (init_once, init_error, yarrow_lock): New variables. (krb5int_prng_init): New function; finish initializing the mutex lock. (do_yarrow_init): New function. (krb5_c_random_add_entropy): Call it once only. Lock the mutex before processing the input. (krb5_c_random_make_octets): Lock the mutex before extracting random bytes. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16290 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/crypto/ChangeLog | 21 +++++++++ src/lib/crypto/crypto_libinit.c | 28 ++++++------ src/lib/crypto/crypto_libinit.h | 7 --- src/lib/crypto/prng.c | 77 +++++++++++++++++++++++---------- 4 files changed, 89 insertions(+), 44 deletions(-) delete mode 100644 src/lib/crypto/crypto_libinit.h diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index e792bf430..7916871df 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,5 +1,26 @@ 2004-04-30 Ken Raeburn + * crypto_libinit.c (initialized): Variable deleted. + (cryptoint_initialize_library, cryptoint_cleanup_library): Use new + macros for automatic shared library init/fini functions. + (prng_cleanup): Declaration deleted. + (krb5int_prng_init, krb5int_prng_cleanup): Declare. + (cryptoint_initialize_library): Call krb5int_prng_init. + (krb5int_crypto_init): New function, checks that + cryptoint_initialize_library was called successfully. + (cryptoint_cleanup_library): Call krb5int_prng_cleanup only if the + initializer ran. + * crypto_libinit.h: Deleted. + * prng.c: Include k5-thread.h. + (init_once, init_error, yarrow_lock): New variables. + (krb5int_prng_init): New function; finish initializing the mutex + lock. + (do_yarrow_init): New function. + (krb5_c_random_add_entropy): Call it once only. Lock the mutex + before processing the input. + (krb5_c_random_make_octets): Lock the mutex before extracting + random bytes. + * libk5crypto.exports: Drop the library init/fini functions and the DES tables from the export list. diff --git a/src/lib/crypto/crypto_libinit.c b/src/lib/crypto/crypto_libinit.c index a799b1ec3..91bf8ac22 100644 --- a/src/lib/crypto/crypto_libinit.c +++ b/src/lib/crypto/crypto_libinit.c @@ -1,11 +1,11 @@ #include -#include "crypto_libinit.h" -/* get prng_cleanup decl */ #include "k5-int.h" -static int initialized = 0; +MAKE_INIT_FUNCTION(cryptoint_initialize_library); +MAKE_FINI_FUNCTION(cryptoint_cleanup_library); -extern void prng_cleanup (void); +extern int krb5int_prng_init(void); +extern void krb5int_prng_cleanup (void); /* * Initialize the crypto library. @@ -13,12 +13,12 @@ extern void prng_cleanup (void); int cryptoint_initialize_library (void) { - - if (!initialized) { - initialized = 1; - } - - return 0; + return krb5int_prng_init(); +} + +int krb5int_crypto_init(void) +{ + return CALL_INIT_FUNCTION(cryptoint_initialize_library); } /* @@ -27,9 +27,7 @@ int cryptoint_initialize_library (void) void cryptoint_cleanup_library (void) { - assert (initialized); - - krb5int_prng_cleanup (); - - initialized = 0; + if (!INITIALIZER_RAN(cryptoint_initialize_library)) + return; + krb5int_prng_cleanup (); } diff --git a/src/lib/crypto/crypto_libinit.h b/src/lib/crypto/crypto_libinit.h deleted file mode 100644 index 44c7e16b0..000000000 --- a/src/lib/crypto/crypto_libinit.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef K5CRYPTO_LIBINIT_H -#define K5CRYPTO_LIBINIT_H - -int cryptoint_initialize_library (void); -void cryptoint_cleanup_library (void); - -#endif /* K5CRYPTO_LIBINIT_H */ diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c index eebaca2b9..dd1c4c852 100644 --- a/src/lib/crypto/prng.c +++ b/src/lib/crypto/prng.c @@ -26,10 +26,13 @@ #include "k5-int.h" #include "enc_provider.h" #include +#include "k5-thread.h" #include "yarrow.h" static Yarrow_CTX y_ctx; -static int inited=0; +static k5_once_t init_once = K5_ONCE_INIT; +static int inited, init_error; +static k5_mutex_t yarrow_lock = K5_MUTEX_PARTIAL_INITIALIZER; /* Helper function to estimate entropy based on sample length * and where it comes from. @@ -54,56 +57,85 @@ entropy_estimate (unsigned int randsource, size_t length) return (0); } -krb5_error_code KRB5_CALLCONV -krb5_c_random_add_entropy (krb5_context context, unsigned int randsource, - const krb5_data *data) +int krb5int_prng_init(void) { - int yerr; + return k5_mutex_finish_init(&yarrow_lock); +} - if (inited == 0) { +static void do_yarrow_init(void) +{ unsigned i; + int yerr; + yerr = krb5int_yarrow_init (&y_ctx, NULL); - if ((yerr != YARROW_OK) && (yerr != YARROW_NOT_SEEDED)) - return (KRB5_CRYPTO_INTERNAL); - + if ((yerr != YARROW_OK) && (yerr != YARROW_NOT_SEEDED)) { + init_error = yerr; + return; + } for (i=0; i < KRB5_C_RANDSOURCE_MAX; i++ ) { - unsigned source_id; - if (krb5int_yarrow_new_source (&y_ctx, &source_id) != YARROW_OK ) - return KRB5_CRYPTO_INTERNAL; - assert (source_id == i); + unsigned source_id; + if (krb5int_yarrow_new_source (&y_ctx, &source_id) != YARROW_OK ) { + init_error = 17; + return; + } + assert (source_id == i); } inited=1; - - } + init_error = 0; +} + +krb5_error_code KRB5_CALLCONV +krb5_c_random_add_entropy (krb5_context context, unsigned int randsource, + const krb5_data *data) +{ + int yerr; + + /* Make sure the mutex got initialized. */ + yerr = krb5int_crypto_init(); + if (yerr) + return yerr; + /* Run the Yarrow init code, if not done already. */ + yerr = k5_once(&init_once, do_yarrow_init); + if (yerr) + return yerr; + /* Return an error if the Yarrow initialization failed. */ + if (init_error) + return KRB5_CRYPTO_INTERNAL; + /* Now, finally, feed in the data. */ + yerr = k5_mutex_lock(&yarrow_lock); + if (yerr) + return yerr; yerr = krb5int_yarrow_input (&y_ctx, randsource, data->data, data->length, entropy_estimate (randsource, data->length)); + k5_mutex_unlock(&yarrow_lock); if (yerr != YARROW_OK) return (KRB5_CRYPTO_INTERNAL); return (0); } krb5_error_code KRB5_CALLCONV -krb5_c_random_seed -(krb5_context context, krb5_data *data) +krb5_c_random_seed (krb5_context context, krb5_data *data) { - return (krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_OLDAPI, data)); + return krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_OLDAPI, data); } - - krb5_error_code KRB5_CALLCONV krb5_c_random_make_octets(krb5_context context, krb5_data *data) { int yerr; assert (inited); + yerr = k5_mutex_lock(&yarrow_lock); + if (yerr) + return yerr; yerr = krb5int_yarrow_output (&y_ctx, data->data, data->length); if (yerr == YARROW_NOT_SEEDED) { yerr = krb5int_yarrow_reseed (&y_ctx, YARROW_SLOW_POOL); if (yerr == YARROW_OK) yerr = krb5int_yarrow_output (&y_ctx, data->data, data->length); } + k5_mutex_unlock(&yarrow_lock); if ( yerr != YARROW_OK) return (KRB5_CRYPTO_INTERNAL); return(0); @@ -111,8 +143,9 @@ krb5_c_random_make_octets(krb5_context context, krb5_data *data) void krb5int_prng_cleanup (void) { - if (inited) krb5int_yarrow_final (&y_ctx); - inited = 0; + if (inited) + krb5int_yarrow_final (&y_ctx); + inited = 0; } -- 2.26.2