aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto/yarrow/yarrow.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypto/yarrow/yarrow.c')
-rw-r--r--src/lib/crypto/yarrow/yarrow.c94
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;