aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-09-25 20:21:57 +0000
committerGreg Hudson <ghudson@mit.edu>2010-09-25 20:21:57 +0000
commit4006c3d647a0a0f1eccb5baeb530c96bfbbbf7a5 (patch)
tree047c8626c229d99b35bae5b0e1fbde6317706be9
parentdefb200396bd449b0e12a163e5407a124ebe6018 (diff)
downloadkrb5-4006c3d647a0a0f1eccb5baeb530c96bfbbbf7a5.zip
krb5-4006c3d647a0a0f1eccb5baeb530c96bfbbbf7a5.tar.gz
krb5-4006c3d647a0a0f1eccb5baeb530c96bfbbbf7a5.tar.bz2
When NSS is the crypto implementation, use the NSS PRNG. Avoids the
issue that Yarrow's entropy pools would be invalidated by a fork. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/nss@24349 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/configure.in1
-rw-r--r--src/lib/crypto/crypto_tests/Makefile.in8
-rw-r--r--src/lib/crypto/krb/Makefile.in3
-rw-r--r--src/lib/crypto/krb/prng.c82
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);