diff options
-rw-r--r-- | src/configure.in | 1 | ||||
-rw-r--r-- | src/lib/crypto/crypto_tests/Makefile.in | 8 | ||||
-rw-r--r-- | src/lib/crypto/krb/Makefile.in | 3 | ||||
-rw-r--r-- | src/lib/crypto/krb/prng.c | 82 |
4 files changed, 82 insertions, 12 deletions
diff --git a/src/configure.in b/src/configure.in index bd60b8e..c5bf4c4 100644 --- a/src/configure.in +++ b/src/configure.in @@ -134,6 +134,7 @@ openssl) nss) CRYPTO_IMPL_CFLAGS=`pkg-config --cflags nss` CRYPTO_IMPL_LIBS="-lnss3 $(pkg-config --libs nss-util)" + AC_DEFINE(CRYPTO_IMPL_NSS,1,[Define if crypto implementation is NSS]) ;; *) AC_MSG_ERROR([Unknown crypto implementation $withval]) diff --git a/src/lib/crypto/crypto_tests/Makefile.in b/src/lib/crypto/crypto_tests/Makefile.in index c92cc7e..cfab1b6 100644 --- a/src/lib/crypto/crypto_tests/Makefile.in +++ b/src/lib/crypto/crypto_tests/Makefile.in @@ -41,6 +41,9 @@ EXTRADEPSRCS=\ # NOTE: The t_cksum known checksum values are primarily for regression # testing. They are not derived a priori, but are known to produce # checksums that interoperate. +# +# We use the NSS PRNG when NSS is the crypto back end, so don't test +# against the expected output for Yarrow. check-unix:: t_nfold t_encrypt t_prf t_prng t_hmac \ t_cksum4 t_cksum5 \ aes-test \ @@ -48,8 +51,9 @@ check-unix:: t_nfold t_encrypt t_prf t_prng t_hmac \ t_crc t_cts t_short $(RUN_SETUP) $(VALGRIND) ./t_nfold $(RUN_SETUP) $(VALGRIND) ./t_encrypt - $(RUN_SETUP) $(VALGRIND) ./t_prng <$(srcdir)/t_prng.seed >t_prng.output && \ - diff t_prng.output $(srcdir)/t_prng.expected + if [ @CRYPTO_IMPL@ != nss ]; then \ + $(RUN_SETUP) $(VALGRIND) ./t_prng <$(srcdir)/t_prng.seed >t_prng.output && \ + diff t_prng.output $(srcdir)/t_prng.expected; fi $(RUN_SETUP) $(VALGRIND) ./t_hmac $(RUN_SETUP) $(VALGRIND) ./t_prf <$(srcdir)/t_prf.in >t_prf.output diff t_prf.output $(srcdir)/t_prf.expected diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in index 9e01911..194b69c 100644 --- a/src/lib/crypto/krb/Makefile.in +++ b/src/lib/crypto/krb/Makefile.in @@ -8,7 +8,8 @@ LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/../@CRYPTO_IMPL@/enc_provider -I$(srcdir -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/yarrow \ -I$(srcdir)/../@CRYPTO_IMPL@/ -I$(srcdir)/../@CRYPTO_IMPL@/des \ -I$(srcdir)/../@CRYPTO_IMPL@/aes -I$(srcdir)/arcfour \ - -I$(srcdir)/../@CRYPTO_IMPL@/sha1 -I$(srcdir)/../@CRYPTO_IMPL@ + -I$(srcdir)/../@CRYPTO_IMPL@/sha1 -I$(srcdir)/../@CRYPTO_IMPL@ \ + @CRYPTO_IMPL_CFLAGS@ PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) DEFS= diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c index ef32699..b9da3d5 100644 --- a/src/lib/crypto/krb/prng.c +++ b/src/lib/crypto/krb/prng.c @@ -29,11 +29,74 @@ #include <assert.h> #include "k5-thread.h" -#include "yarrow.h" -static Yarrow_CTX y_ctx; #define yarrow_lock krb5int_yarrow_lock k5_mutex_t yarrow_lock = K5_MUTEX_PARTIAL_INITIALIZER; +#ifdef CRYPTO_IMPL_NSS + +/* + * Using Yarrow with NSS is a bit problematic because the MD5 contexts it holds + * open for the entropy pools would be invalidated by a fork(), causing us to + * lose the entropy contained therein. + * + * Therefore, use the NSS PRNG if NSS is the crypto implementation. Doing this + * via ifdefs here is temporary until we come up with better build logic for + * it. + */ + +#include "../nss/nss_gen.h" +#include <pk11pub.h> + +/* Gather 8K of OS entropy per call, enough to fill the additional data buffer + * for the built-in PRNG and trigger a reseed. */ +#define OS_ENTROPY_LEN 8192 + +int krb5int_prng_init(void) +{ + return 0; +} + +krb5_error_code KRB5_CALLCONV +krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, + const krb5_data *data) +{ + krb5_error_code ret; + + ret = k5_nss_init(); + if (ret) + return ret; + if (PK11_RandomUpdate(data->data, data->length) != SECSuccess) + return k5_nss_map_last_error(); + return 0; +} + +krb5_error_code KRB5_CALLCONV +krb5_c_random_make_octets(krb5_context context, krb5_data *data) +{ + krb5_error_code ret; + + ret = k5_nss_init(); + if (ret) + return ret; + if (PK11_GenerateRandom((unsigned char *)data->data, + data->length) != SECSuccess) + return k5_nss_map_last_error(); + return 0; +} + +void +krb5int_prng_cleanup (void) +{ +} + +#else /* CRYPTO_IMPL_NSS */ + +#include "yarrow.h" +static Yarrow_CTX y_ctx; + +/* Gather enough OS entropy per call to trigger a Yarrow reseed. */ +#define OS_ENTROPY_LEN (YARROW_SLOW_THRESH/8) + /* Helper function to estimate entropy based on sample length * and where it comes from. */ @@ -100,12 +163,6 @@ krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, } krb5_error_code KRB5_CALLCONV -krb5_c_random_seed(krb5_context context, krb5_data *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; @@ -127,6 +184,13 @@ krb5int_prng_cleanup (void) k5_mutex_destroy(&yarrow_lock); } +#endif /* not CRYPTO_IMPL_NSS */ + +krb5_error_code KRB5_CALLCONV +krb5_c_random_seed(krb5_context context, krb5_data *data) +{ + return krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OLDAPI, data); +} /* * Routines to get entropy from the OS. For UNIX we try /dev/urandom @@ -163,7 +227,7 @@ read_entropy_from_device(krb5_context context, const char *device) krb5_data data; struct stat sb; int fd; - unsigned char buf[YARROW_SLOW_THRESH/8], *bp; + unsigned char buf[OS_ENTROPY_LEN], *bp; int left; fd = open (device, O_RDONLY); |