diff options
Diffstat (limited to 'src/lib/crypto/yarrow/yarrow.c')
-rw-r--r-- | src/lib/crypto/yarrow/yarrow.c | 94 |
1 files changed, 75 insertions, 19 deletions
diff --git a/src/lib/crypto/yarrow/yarrow.c b/src/lib/crypto/yarrow/yarrow.c index c9f4188..a619c5b 100644 --- a/src/lib/crypto/yarrow/yarrow.c +++ b/src/lib/crypto/yarrow/yarrow.c @@ -121,6 +121,11 @@ static void krb5int_yarrow_init_Limits(Yarrow_CTX* y) PRNG state */ #ifdef YARROW_DETECT_FORK +static int +yarrow_input_locked( Yarrow_CTX* y, unsigned source_id, + const void *sample, + size_t size, size_t entropy_bits ); + static int Yarrow_detect_fork(Yarrow_CTX *y) { pid_t newpid; @@ -135,12 +140,12 @@ static int Yarrow_detect_fork(Yarrow_CTX *y) * Then we reseed. This doesn't really increase entropy, but does make the * streams distinct assuming we already have good entropy*/ y->pid = newpid; - TRY (krb5int_yarrow_input (y, 0, &newpid, - sizeof (newpid), 0)); - TRY (krb5int_yarrow_input (y, 0, &newpid, - sizeof (newpid), 0)); - TRY (krb5int_yarrow_reseed (y, YARROW_FAST_POOL)); - } + TRY (yarrow_input_locked (y, 0, &newpid, + sizeof (newpid), 0)); + TRY (yarrow_input_locked (y, 0, &newpid, + sizeof (newpid), 0)); + TRY (krb5int_yarrow_reseed (y, YARROW_FAST_POOL)); + } CATCH: EXCEP_RET; @@ -241,10 +246,11 @@ int krb5int_yarrow_init(Yarrow_CTX* y, const char *filename) EXCEP_RET; } -YARROW_DLL -int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, - const void* sample, - size_t size, size_t entropy_bits ) +static +int yarrow_input_maybe_locking( Yarrow_CTX* y, unsigned source_id, + const void* sample, + size_t size, size_t entropy_bits, + int do_lock ) { EXCEP_DECL; int ret; @@ -254,7 +260,6 @@ int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, size_t estimate; if (!y) { THROW( YARROW_BAD_ARG ); } - TRY( Yarrow_detect_fork( y ) ); if (source_id >= y->num_sources) { THROW( YARROW_BAD_SOURCE ); } @@ -265,8 +270,10 @@ int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, THROW( YARROW_BAD_SOURCE ); } - TRY( LOCK() ); - locked = 1; + if (do_lock) { + TRY( LOCK() ); + locked = 1; + } /* hash in the sample */ @@ -332,6 +339,24 @@ int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, } YARROW_DLL +int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, + const void* sample, + size_t size, size_t entropy_bits ) +{ + return yarrow_input_maybe_locking(y, source_id, sample, size, + entropy_bits, 1); +} + +static int +yarrow_input_locked( Yarrow_CTX* y, unsigned source_id, + const void *sample, + size_t size, size_t entropy_bits ) +{ + return yarrow_input_maybe_locking(y, source_id, sample, size, + entropy_bits, 0); +} + +YARROW_DLL int krb5int_yarrow_new_source(Yarrow_CTX* y, unsigned* source_id) { EXCEP_DECL; @@ -395,7 +420,7 @@ static int krb5int_yarrow_output_Block( Yarrow_CTX* y, void* out ) if (y->out_count >= y->Pg) { y->out_count = 0; - TRY( krb5int_yarrow_gate( y ) ); + TRY( yarrow_gate_locked( y ) ); /* require new seed after reaching gates_limit */ @@ -478,11 +503,23 @@ int krb5int_yarrow_status( Yarrow_CTX* y, int *num_sources, unsigned *source_id, EXCEP_RET; } +static int yarrow_output_locked(Yarrow_CTX*, void*, size_t); + YARROW_DLL int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ) { EXCEP_DECL; - int locked = 0; + TRY( LOCK() ); + TRY( yarrow_output_locked(y, out, size)); +CATCH: + UNLOCK(); + EXCEP_RET; +} + +static +int yarrow_output_locked( Yarrow_CTX* y, void* out, size_t size ) +{ + EXCEP_DECL; size_t left; char* outp; size_t use; @@ -495,8 +532,6 @@ int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ) left = size; outp = out; - TRY( LOCK() ); - if (y->out_left > 0) { use = min(left, y->out_left); @@ -521,8 +556,30 @@ int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ) } CATCH: - if ( locked ) { TRY( UNLOCK() ); } + EXCEP_RET; +} + +static int yarrow_gate_locked(Yarrow_CTX* y) +{ + EXCEP_DECL; + byte new_K[CIPHER_KEY_SIZE]; + + if (!y) { THROW( YARROW_BAD_ARG ); } + TRACE( printf( "GATE[" ); ); + + /* K <- Next k bits of PRNG output */ + + TRY( yarrow_output_locked(y, new_K, CIPHER_KEY_SIZE) ); + mem_copy(y->K, new_K, CIPHER_KEY_SIZE); + + /* need to resetup the key schedule as the key has changed */ + + TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); + + CATCH: + TRACE( printf( "]," ); ); + mem_zero(new_K, sizeof(new_K)); EXCEP_RET; } @@ -837,7 +894,6 @@ int krb5int_yarrow_final(Yarrow_CTX* y) int locked = 0; if (!y) { THROW( YARROW_BAD_ARG ); } - TRY( Yarrow_detect_fork(y) ); TRY( LOCK() ); locked = 1; |