Some missed files needed for rev #24420
authorZhanna Tsitkov <tsitkova@mit.edu>
Tue, 5 Oct 2010 03:29:35 +0000 (03:29 +0000)
committerZhanna Tsitkov <tsitkova@mit.edu>
Tue, 5 Oct 2010 03:29:35 +0000 (03:29 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24421 dc483132-0cff-0310-8789-dd5450dbe970

20 files changed:
src/lib/crypto/krb/prng/Makefile.in [new file with mode: 0644]
src/lib/crypto/krb/prng/deps [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/Makefile.in [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/deps [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/entropy.c [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/fortuna.h [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/prng_fortuna.c [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/t_fortuna.c [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.c [new file with mode: 0644]
src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.expected [new file with mode: 0644]
src/lib/crypto/krb/prng/nss/Makefile.in [new file with mode: 0644]
src/lib/crypto/krb/prng/nss/deps [new file with mode: 0644]
src/lib/crypto/krb/prng/nss/prng_nss.c [new file with mode: 0644]
src/lib/crypto/krb/prng/nss/prng_nss.h [new file with mode: 0644]
src/lib/crypto/krb/prng/prng.h [new file with mode: 0644]
src/lib/crypto/krb/prng/yarrow/prng_yarrow.c [new file with mode: 0644]
src/lib/crypto/nss/sha2/Makefile.in [new file with mode: 0644]
src/lib/crypto/nss/sha2/deps [new file with mode: 0644]
src/lib/crypto/nss/sha2/sha2.c [new file with mode: 0644]
src/lib/crypto/nss/sha2/sha2.h [new file with mode: 0644]

diff --git a/src/lib/crypto/krb/prng/Makefile.in b/src/lib/crypto/krb/prng/Makefile.in
new file mode 100644 (file)
index 0000000..76a9388
--- /dev/null
@@ -0,0 +1,41 @@
+mydir=lib/crypto/krb/prng
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+SUBDIRS= @PRNG_ALG@
+LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/../../@CRYPTO_IMPL@/enc_provider \
+               -I$(srcdir)/../../@CRYPTO_IMPL@/hash_provider                           \
+               -I$(srcdir)/@PRNG_ALG@                  \
+               -I$(srcdir)/../../@CRYPTO_IMPL@/                \
+               -I$(srcdir)/../../@CRYPTO_IMPL@/aes     \
+               -I$(srcdir)/../../@CRYPTO_IMPL@/sha1 -I$(srcdir)/../../@CRYPTO_IMPL@/sha2
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+DEFS=
+
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+STLIBOBJS=\
+       prng.o
+
+OBJS=\
+       $(OUTPRE)prng.$(OBJEXT)
+
+SRCS=\
+       $(srcdir)/prng.c
+
+STOBJLISTS= OBJS.ST  @PRNG_ALG@/OBJS.ST 
+
+SUBDIROBJLISTS=  @PRNG_ALG@/OBJS.ST 
+
+
+all-unix:: all-libobjs
+includes:: depend
+
+depend:: $(SRCS)
+
+clean-unix:: clean-libobjs
+
+@lib_frag@
+@libobj_frag@
+
diff --git a/src/lib/crypto/krb/prng/deps b/src/lib/crypto/krb/prng/deps
new file mode 100644 (file)
index 0000000..bde1cdd
--- /dev/null
@@ -0,0 +1,16 @@
+# 
+# Generated makefile dependencies follow.
+#
+prng.so prng.po $(OUTPRE)prng.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../builtin/enc_provider/enc_provider.h \
+  $(srcdir)/../../builtin/sha1/shs.h $(srcdir)/../../builtin/yhash.h \
+  $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  prng.c
diff --git a/src/lib/crypto/krb/prng/fortuna/Makefile.in b/src/lib/crypto/krb/prng/fortuna/Makefile.in
new file mode 100644 (file)
index 0000000..df960c2
--- /dev/null
@@ -0,0 +1,53 @@
+mydir=lib/crypto/krb/prng/fortuna
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../.. \
+               -I$(srcdir)/../../../@CRYPTO_IMPL@              \
+               -I$(srcdir)/../../../@CRYPTO_IMPL@/sha2         \
+               -I$(srcdir)/../../../@CRYPTO_IMPL@/aes  \
+               -I$(srcdir)/../../../@CRYPTO_IMPL@/enc_provider
+DEFS=
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+STLIBOBJS= \
+       prng_fortuna.o entropy.o
+OBJS= \
+       $(OUTPRE)prng_fortuna.$(OBJEXT) \
+       $(OUTPRE)entropy.$(OBJEXT)
+
+SRCS=\
+       $(srcdir)/entropy.c \
+       $(srcdir)/prng_fortuna.c 
+
+all-unix:: all-libobjs
+
+includes:: depend
+
+depend:: $(SRCS)
+
+t_fortuna: t_fortuna.$(OBJEXT) $(SUPPORT_DEPLIB)
+       $(CC_LINK) -o t_fortuna t_fortuna.$(OBJEXT) -lcom_err $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
+
+t_fortuna_make_oct: t_fortuna_make_oct.$(OBJEXT) $(SUPPORT_DEPLIB)
+       $(CC_LINK) -o t_fortuna_make_oct t_fortuna_make_oct.$(OBJEXT) -lcom_err $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
+
+check-unix:: t_fortuna t_fortuna_make_oct
+# ifdef TEST_FORTUNA
+ifeq ("@PRNG_FORTUNA_TEST@","yes")
+       $(RUN_SETUP) $(VALGRIND) ./t_fortuna_make_oct > t_fortuna_make_oct.result && \
+       diff t_fortuna_make_oct.result t_fortuna_make_oct.expected
+else
+       $(RUN_SETUP) $(VALGRIND) ./t_fortuna
+       $(RUN_SETUP) $(VALGRIND) ./t_fortuna_make_oct > t_fortuna_make_oct.result
+endif
+
+clean::
+       $(RM) t_fortuna$(EXEEXT) t_fortuna.$(OBJEXT)  t_fortuna_make_oct.result  t_fortuna_make_oct$(EXEEXT)  t_fortuna_make_oct.$(OBJEXT)
+
+
+clean-unix:: clean-libobjs
+
+@lib_frag@
+@libobj_frag@
+
diff --git a/src/lib/crypto/krb/prng/fortuna/deps b/src/lib/crypto/krb/prng/fortuna/deps
new file mode 100644 (file)
index 0000000..1d420c5
--- /dev/null
@@ -0,0 +1,45 @@
+# 
+# Generated makefile dependencies follow.
+#
+prng_fortuna.so prng_fortuna.po $(OUTPRE)prng_fortuna.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../../builtin/aes/aes.h \
+  $(srcdir)/../prng.h \
+  $(srcdir)/../../../builtin/sha2/sha2.h \
+  $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  prng_fortuna.c fortuna.h 
+entropy.so entropy.po $(OUTPRE)entropy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS)        \
+  $(top_srcdir)/include/k5-buf.h \
+  $(srcdir)/../prng.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  entropy.c
+t_fortuna.so t_fortuna.po $(OUTPRE)t_fortuna.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../../builtin/aes/aes.h \
+  $(srcdir)/../prng.h \
+  $(srcdir)/../../../builtin/sha2/sha2.h \
+  $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  t_fortuna.c fortuna.h 
+
diff --git a/src/lib/crypto/krb/prng/fortuna/entropy.c b/src/lib/crypto/krb/prng/fortuna/entropy.c
new file mode 100644 (file)
index 0000000..0f9344e
--- /dev/null
@@ -0,0 +1,84 @@
+/* various methods to collect entropy */
+#include "prng.h"
+
+#include "fortuna.h"
+#include "k5-int.h"
+
+#ifndef min
+#define min(a, b)       ((a) < (b) ? (a) : (b))
+#endif
+
+krb5_error_code
+k5_entropy_from_device(krb5_context context, const char *device, unsigned char* buf, int buflen)
+{
+    struct stat sb;
+    int fd;
+    unsigned char *bp;
+    size_t left;
+    fd = open(device, O_RDONLY);
+    if (fd == -1)
+        return 0;
+    set_cloexec_fd(fd);
+    if (fstat(fd, &sb) == -1 || S_ISREG(sb.st_mode)) {
+        close(fd);
+        return 0;
+    }
+
+    for (bp = buf, left = sizeof(buf); left > 0;) {
+        ssize_t count;
+        count = read(fd, bp, (unsigned) left);
+        if (count <= 0) {
+            close(fd);
+            return 0;
+        }
+        left -= count;
+        bp += count;
+    }
+    close(fd);
+    return 0;
+}
+
+krb5_error_code
+k5_entropy_dev_random(krb5_context context, unsigned char* buf, int buflen)
+{
+    memset(buf, 0, buflen);
+    return k5_entropy_from_device(context,"/dev/random", buf, buflen);
+}
+
+krb5_error_code
+k5_entropy_dev_urandom(krb5_context context, unsigned char* buf, int buflen)
+{
+    memset(buf, 0, buflen);
+    return k5_entropy_from_device(context,"/dev/urandom", buf, buflen);
+}
+
+krb5_error_code
+k5_entropy_pid(krb5_context context, unsigned char* buf, int buflen)
+{
+    pid_t pid = getpid(); 
+    int pidlen = min(buflen,(int)sizeof(&pid));
+    memset(buf, 0, buflen);
+    memcpy(buf, &pid, pidlen);
+    return 0;
+}
+
+krb5_error_code
+k5_entropy_uid(krb5_context context, unsigned char* buf, int buflen)
+{
+    pid_t uid = getuid(); 
+    int uidlen=min(buflen,(int)sizeof(&uid));
+    memset(buf, 0, buflen);
+    memcpy(buf, &uid, uidlen);
+    return 0;
+}
+
+#ifdef TEST_FORTUNA
+int
+test_entr(krb5_context context, unsigned char* buf, int buflen)
+{
+    char buf1[26] = "Seed To Test Fortuna PRNG";
+    memset(buf, 0, buflen);
+    memcpy(buf, buf1, min(buflen, 26));
+    return 0;
+}
+#endif
diff --git a/src/lib/crypto/krb/prng/fortuna/fortuna.h b/src/lib/crypto/krb/prng/fortuna/fortuna.h
new file mode 100644 (file)
index 0000000..34fde09
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prng/fortuna.h
+ *
+ * Copyright 2010 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef FORTUNA_H
+#define FORTUNA_H
+
+#include "k5-int.h"
+#include "prng.h"
+#ifndef OPENSSL
+#include "aes.h"
+#endif
+#include "enc_provider.h"
+#include "sha2.h"
+#include "enc_provider.h"
+
+extern const struct krb5_prng_provider krb5int_prng_fortuna;
+
+/* various entropy collect functions */
+krb5_error_code
+k5_entropy_from_device(krb5_context context, const char *device, unsigned char* buf, int buflen);
+krb5_error_code
+k5_entropy_dev_random(krb5_context context, unsigned char* buf, int buflen);
+krb5_error_code
+k5_entropy_dev_urandom(krb5_context context, unsigned char* buf, int buflen);
+krb5_error_code
+k5_entropy_pid(krb5_context context, unsigned char* buf, int buflen);
+krb5_error_code
+k5_entropy_uid(krb5_context context, unsigned char* buf, int buflen);
+
+#ifdef TEST_FORTUNA
+int test_entr(krb5_context context, unsigned char* buf, int buflen);
+#endif
+
+#define FORTUNA_OK                1  /* All is well */
+#define FORTUNA_FAIL              0  /* generic failure */
+#define FORTUNA_LOCKING          -12
+
+#endif
diff --git a/src/lib/crypto/krb/prng/fortuna/prng_fortuna.c b/src/lib/crypto/krb/prng/fortuna/prng_fortuna.c
new file mode 100644 (file)
index 0000000..07a52a9
--- /dev/null
@@ -0,0 +1,614 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* prng_fortuna.c */
+/*
+ * fortuna.c
+ *             Fortuna-like PRNG.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.     IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.8 2006/10/04 00:29:46 momjian Exp $
+ */
+/*
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ *  or implied warranty.
+ */
+
+#include "fortuna.h"
+#include "k5-int.h"
+
+
+#include "k5-thread.h"
+k5_mutex_t fortuna_lock = K5_MUTEX_PARTIAL_INITIALIZER;
+
+/*
+ * Why Fortuna-like: There does not seem to be any definitive reference
+ * on Fortuna in the net.  Instead this implementation is based on
+ * following references:
+ *
+ * http://en.wikipedia.org/wiki/Fortuna_(PRNG)
+ *      - Wikipedia article
+ * http://jlcooke.ca/random/
+ *      - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
+ */
+
+/*
+ * There is some confusion about whether and how to carry forward
+ * the state of the pools.     Seems like original Fortuna does not
+ * do it, resetting hash after each request.  I guess expecting
+ * feeding to happen more often that requesting.   This is absolutely
+ * unsuitable for pgcrypto, as nothing asynchronous happens here.
+ *
+ * J.L. Cooke fixed this by feeding previous hash to new re-initialized
+ * hash context.
+ *
+ * Fortuna predecessor Yarrow requires ability to query intermediate
+ * 'final result' from hash, without affecting it.
+ *
+ * This implementation uses the Yarrow method - asking intermediate
+ * results, but continuing with old state.
+ */
+
+/*
+ * Algorithm parameters
+ */
+
+#define NUM_POOLS      32
+
+/* in microseconds */
+#define RESEED_INTERVAL 100000 /* 0.1 sec */
+
+/* for one big request, reseed after this many bytes */
+#define RESEED_BYTES   (1024*1024)
+
+/*
+ * Skip reseed if pool 0 has less than this many
+ * bytes added since last reseed.
+ */
+#define POOL0_FILL             (256/8)
+
+/* Entropy gathering */
+int (*entropy_collector[])(krb5_context context, unsigned char buf[], int buflen) =
+{
+#ifndef TEST_FORTUNA
+ /*   k5_entropy_dev_random, */
+    k5_entropy_dev_urandom,
+    k5_entropy_pid,
+    k5_entropy_uid
+#else
+    test_entr
+#endif
+};
+
+/*
+ * Algorithm constants
+ */
+
+#define AES_BLOCK_SIZE 16
+#define AES_MAXNR 14
+
+#define AES_ENCRYPT 1
+#define AES_DECRYPT 0
+
+/* Both cipher key size and hash result size */
+#define BLOCK                  32
+
+/* cipher block size */
+#define CIPH_BLOCK             16
+
+/* for internal wrappers */
+
+#define MD_CTX                 SHA256_CTX
+#define CIPH_CTX               aes_ctx
+
+/* Genarator - block cipher in CTR mode */
+struct fortuna_state
+{
+    unsigned char      counter[CIPH_BLOCK];
+    unsigned char      result[CIPH_BLOCK];
+    unsigned char      key[BLOCK];
+    MD_CTX             pool[NUM_POOLS];
+    CIPH_CTX           ciph;
+    unsigned           reseed_count;
+    struct timeval     last_reseed_time;
+    unsigned           pool0_bytes;
+    unsigned           rnd_pos;
+    int                        tricks_done;
+    pid_t              pid;
+};
+typedef struct fortuna_state FState;
+
+
+/*
+ * Use our own wrappers here.
+ * - Need to get intermediate result from digest, without affecting it.
+ * - Need re-set key on a cipher context.
+ * - Algorithms are guaranteed to exist.
+ * - No memory allocations.
+ */
+
+static void
+ciph_init(CIPH_CTX * ctx /*out*/, const unsigned char *key, int klen)
+{
+    krb5int_aes_enc_key(key, klen, ctx);
+}
+
+static void
+ciph_encrypt(CIPH_CTX *ctx, const unsigned char *in, unsigned char *out)
+{
+    aes_enc_blk(in, out, ctx);
+}
+
+static void
+md_init(MD_CTX * ctx)
+{
+    sha2Init(ctx);
+}
+
+static void
+md_update(MD_CTX * ctx, const unsigned char *data, int len)
+{
+    sha2Update(ctx, data, len);
+}
+
+static void
+md_result(MD_CTX * ctx, unsigned char *dst)
+{
+    MD_CTX     tmp_ctx;
+
+    memcpy(&tmp_ctx, ctx, sizeof(*ctx));
+    sha2Final(dst, &tmp_ctx);
+    memset(&tmp_ctx, 0, sizeof(tmp_ctx));
+}
+
+/*
+ * initialize state
+ */
+static  krb5_error_code
+init_state(FState * st)
+{
+    int        i;
+    krb5_error_code ret = 0;
+
+    ret = k5_mutex_finish_init(&fortuna_lock);
+    if (ret)
+        return ret;
+
+    memset(st, 0, sizeof(*st));
+    for (i = 0; i < NUM_POOLS; i++)
+       md_init(&st->pool[i]);
+    st->pid = getpid();
+
+    return 0;
+}
+
+/*
+ * Endianess does not matter.
+ * It just needs to change without repeating.
+ */
+static void
+inc_counter(FState * st)
+{
+    uint32_t   *val = (uint32_t *) st->counter;
+
+    if (++val[0])
+       return;
+    if (++val[1])
+       return;
+    if (++val[2])
+       return;
+    ++val[3];
+}
+
+/*
+ * This is called 'cipher in counter mode'.
+ */
+static void
+encrypt_counter(FState * st, unsigned char *dst)
+{
+    ciph_encrypt(&st->ciph, st->counter, dst);
+    inc_counter(st);
+}
+
+
+/*
+ * The time between reseed must be at least RESEED_INTERVAL microseconds.
+ */
+static int
+enough_time_passed(FState * st)
+{
+    int    ok = FORTUNA_FAIL;
+    struct timeval tv;
+    struct timeval *last = &st->last_reseed_time;
+
+    gettimeofday(&tv, NULL);
+
+    /* check how much time has passed */
+    if (tv.tv_sec > last->tv_sec + 1)
+       ok = FORTUNA_OK;
+    else if (tv.tv_sec == last->tv_sec + 1) {
+       if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+           ok = FORTUNA_OK;
+    } else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+       ok = FORTUNA_OK;
+
+    /* reseed will happen, update last_reseed_time */
+    if (ok)
+       memcpy(last, &tv, sizeof(tv));
+
+    memset(&tv, 0, sizeof(tv));
+
+    return ok;
+}
+
+/*
+ * generate new key from all the pools
+ */
+static void
+reseed(FState * st)
+{
+    unsigned   k;
+    unsigned   n;
+    MD_CTX             key_md;
+    unsigned char      buf[BLOCK];
+
+    /* set pool as empty */
+    st->pool0_bytes = 0;
+
+    /*
+     * Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
+     */
+    n = ++st->reseed_count;
+
+    /*
+     * The goal: use k-th pool only 1/(2^k) of the time.
+     */
+    md_init(&key_md);
+    for (k = 0; k < NUM_POOLS; k++) {
+       md_result(&st->pool[k], buf);
+       md_update(&key_md, buf, BLOCK);
+
+       if (n & 1 || !n)
+           break;
+       n >>= 1;
+    }
+    /* add old key into mix too */
+    md_update(&key_md, st->key, BLOCK);
+
+#ifndef TEST_FORTUNA
+    /* add pid to make output diverse after fork() */
+    md_update(&key_md, (const unsigned char *)&st->pid, sizeof(st->pid));
+#endif
+
+    /* now we have new key */
+    md_result(&key_md, st->key);
+    /* use new key */
+    ciph_init(&st->ciph, st->key, BLOCK);
+
+    memset(&key_md, 0, sizeof(key_md));
+    memset(buf, 0, BLOCK);
+}
+
+/*
+ * Pick a random pool. This uses key bytes as random source.
+ */
+static unsigned
+get_rand_pool(FState * st)
+{
+    unsigned   rnd;
+
+    /*
+     * This slightly prefers lower pools - thats OK.
+     */
+    rnd = st->key[st->rnd_pos] % NUM_POOLS;
+
+    st->rnd_pos++;
+    if (st->rnd_pos >= BLOCK)
+       st->rnd_pos = 0;
+
+    return rnd;
+}
+
+/*
+ * update pools
+ */
+static void
+add_entropy(FState * st, const unsigned char data[], unsigned len)
+{
+    unsigned           pos;
+    unsigned char      hash[BLOCK];
+    MD_CTX             md;
+
+    /* hash given data */
+    md_init(&md);
+    md_update(&md, data, len);
+    md_result(&md, hash);
+
+    /*
+     * Make sure the pool 0 is initialized, then update randomly.
+     */
+    if (st->reseed_count == 0)
+       pos = 0;
+    else
+       pos = get_rand_pool(st);
+    md_update(&st->pool[pos], hash, BLOCK);
+
+    if (pos == 0)
+       st->pool0_bytes += len;
+
+    memset(hash, 0, BLOCK);
+    memset(&md, 0, sizeof(md));
+}
+
+/*
+ * Just take 2 next blocks as new key
+ */
+static void
+rekey(FState * st)
+{
+    encrypt_counter(st, st->key);
+    encrypt_counter(st, st->key + CIPH_BLOCK);
+    ciph_init(&st->ciph, st->key, BLOCK);
+}
+
+/*
+ * Hide public constants. (counter, pools > 0)
+ *
+ * This can also be viewed as spreading the startup
+ * entropy over all of the components.
+ */
+static void
+startup_tricks(FState * st)
+{
+    int                        i;
+    unsigned char      buf[BLOCK];
+
+    /* Use next block as counter. */
+    encrypt_counter(st, st->counter);
+
+    /* Now shuffle pools, excluding #0 */
+    for (i = 1; i < NUM_POOLS; i++) {
+       encrypt_counter(st, buf);
+       encrypt_counter(st, buf + CIPH_BLOCK);
+       md_update(&st->pool[i], buf, BLOCK);
+    }
+    memset(buf, 0, BLOCK);
+
+    /* Hide the key. */
+    rekey(st);
+
+    /* This can be done only once. */
+    st->tricks_done = 1;
+}
+
+static void
+extract_data(FState * st, unsigned count, unsigned char *dst)
+{
+    unsigned   n;
+    unsigned   block_nr = 0;
+    pid_t      pid = getpid();
+
+    /* Should we reseed? */
+    if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0)
+       if (enough_time_passed(st))
+           reseed(st);
+
+    /* Do some randomization on first call */
+    if (!st->tricks_done)
+       startup_tricks(st);
+
+    /* If we forked, force a reseed again */
+    if (pid != st->pid) {
+       st->pid = pid;
+       reseed(st);
+    }
+    while (count > 0) {
+       /* produce bytes */
+       encrypt_counter(st, st->result);
+
+       /* copy result */
+       if (count > CIPH_BLOCK)
+           n = CIPH_BLOCK;
+       else
+           n = count;
+       memcpy(dst, st->result, n);
+       dst += n;
+       count -= n;
+
+       /* must not give out too many bytes with one key */
+       block_nr++;
+       if (block_nr > (RESEED_BYTES / CIPH_BLOCK)) {
+           rekey(st);
+           block_nr = 0;
+       }
+    }
+    /* Set new key for next request. */
+    rekey(st);
+}
+
+/*
+ * public interface
+ */
+
+static FState  main_state;
+static int     init_done;
+static int     have_entropy;
+static int      resend_bytes;
+
+#define FORTUNA_RESEED_BYTE    10000
+
+/*
+ * Try our best to do an inital seed
+ */
+#define INIT_BYTES     128
+
+static int
+fortuna_reseed(void)
+{
+    int entropy_p = 0;
+    krb5_context ctx;
+    unsigned char buf[ENTROPY_BUFSIZE];
+    int num = sizeof(entropy_collector)/sizeof(entropy_collector[0]);
+
+    if (!init_done)
+       abort();
+    
+    while(num > 0){
+        entropy_collector[num-1](ctx, buf, ENTROPY_BUFSIZE);
+        add_entropy(&main_state, buf, sizeof(buf));
+        num--;
+    }
+    memset (buf,0,ENTROPY_BUFSIZE);
+    entropy_p = 1; 
+
+    return entropy_p;
+}
+
+static int
+fortuna_init(void)
+{
+    krb5_error_code ret = 0;
+
+    if (!init_done) {
+        ret = init_state(&main_state);
+        if (ret == 0)
+            init_done = 1;
+    }
+    if (!have_entropy)
+       have_entropy = fortuna_reseed();
+    return (init_done && have_entropy);
+}
+
+static  krb5_error_code
+fortuna_seed(const unsigned char *indata, int size)
+{
+    krb5_error_code ret = 0;
+
+    fortuna_init();
+
+    ret = k5_mutex_lock(&fortuna_lock);
+    if (ret)
+        return FORTUNA_LOCKING;
+
+    add_entropy(&main_state, indata, size);
+    if (size >= INIT_BYTES)
+       have_entropy = 1;
+
+    k5_mutex_unlock(&fortuna_lock);
+
+    return FORTUNA_OK;
+}
+
+static int
+fortuna_bytes(unsigned char *outdata, int size)
+{
+    krb5_error_code ret = 0;
+
+    if (!fortuna_init()){
+       return FORTUNA_FAIL;
+    }
+
+    ret = k5_mutex_lock(&fortuna_lock);
+    if (ret)
+        return FORTUNA_LOCKING;
+
+    resend_bytes += size;
+    if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) {
+       resend_bytes = 0;
+       fortuna_reseed();
+    }
+    extract_data(&main_state, size, outdata);
+
+    k5_mutex_unlock(&fortuna_lock);
+
+    return FORTUNA_OK;
+}
+
+static void
+fortuna_cleanup(void)
+{
+    krb5_error_code ret = 0;
+
+    ret = k5_mutex_lock(&fortuna_lock);
+
+    init_done = 0;
+    have_entropy = 0;
+    memset(&main_state, 0, sizeof(main_state));
+
+    if (!ret)
+        k5_mutex_unlock(&fortuna_lock);
+
+    k5_mutex_destroy(&fortuna_lock);
+
+}
+
+static krb5_error_code
+fortuna_add_entropy(krb5_context context, unsigned int randsource,
+                          const krb5_data *indata)
+{
+    krb5_error_code ret = 0;
+    ret = fortuna_seed((const unsigned char *)indata->data, indata->length);
+    if (ret != FORTUNA_OK)
+        return KRB5_CRYPTO_INTERNAL;
+    return 0;
+}
+
+static krb5_error_code
+fortuna_make_octets(krb5_context context, krb5_data *outdata)
+{
+    krb5_error_code ret = 0;
+    ret = fortuna_bytes((unsigned char *)outdata->data, outdata->length);
+    if (ret != FORTUNA_OK)
+        return KRB5_CRYPTO_INTERNAL;
+    return 0;
+}
+
+const struct krb5_prng_provider krb5int_prng_fortuna = {
+    "fortuna",
+    fortuna_make_octets,
+    fortuna_add_entropy,
+    fortuna_init,
+    fortuna_cleanup
+};
+
diff --git a/src/lib/crypto/krb/prng/fortuna/t_fortuna.c b/src/lib/crypto/krb/prng/fortuna/t_fortuna.c
new file mode 100644 (file)
index 0000000..3365f66
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "prng.h"
+#include "fortuna.h"
+#include <k5-int.h>
+
+
+#define LEN_TEST_BUF 1024 * 1024
+static int len = LEN_TEST_BUF;
+
+int
+main(int argc, char **argv)
+{
+    char buffer[LEN_TEST_BUF];
+    krb5_data data = {0, LEN_TEST_BUF, (char*)buffer};
+    int bit, i;
+    double res;
+    int bits[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+    if (len < 100000) 
+        return 0;
+
+    for (i = 0; i < LEN_TEST_BUF; i++)
+         buffer[i] = 0;
+
+    /* head vs tail */
+    krb5_c_random_make_octets(NULL, &data);
+    for (i = 0; i < len; i++) {
+        unsigned char c = ((unsigned char *)buffer)[i];
+        for (bit = 0; bit < 8 && c; bit++) {
+            if (c & 1)
+                bits[bit]++;
+            c = c >> 1;
+        }
+    }
+    
+    for (bit = 0; bit < 8; bit++) {
+
+        res = ((double)abs(len - bits[bit] * 2)) / (double)len;
+        if (res > 0.005){
+            printf("head %d vs tail %d > 0.5%%%% %lf == %d vs %d\n",
+                 bit, bit, res, len, bits[bit]);
+            return 1;
+        }
+
+        printf("head vs tails bit %d is %lf\n", bit, res);
+    }
+
+    return 0;
+}
diff --git a/src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.c b/src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.c
new file mode 100644 (file)
index 0000000..42a5be2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "prng.h"
+#include "fortuna.h"
+#include <k5-int.h>
+
+#define LEN_TEST_BUF 1024
+static int len = LEN_TEST_BUF;
+
+static void hex_print( FILE* f, const char* var, void* data, size_t size );
+
+int
+main(int argc, char **argv)
+{
+    char buffer[LEN_TEST_BUF];
+    krb5_data data = {0, LEN_TEST_BUF, (char*)buffer};
+    int i;
+
+    for (i = 0; i < LEN_TEST_BUF; i++)
+         buffer[i] = 0;
+
+    krb5_c_random_make_octets(NULL, &data);
+
+    hex_print( stdout, "random1", data.data, data.length );
+
+    /* To target FORTUNA_RESEED_BYTE */
+    i = 0;
+    while (i++ < 11){
+        krb5_c_random_make_octets(NULL, &data);
+    }
+
+    hex_print( stdout, "random2", data.data, data.length );
+
+    return 0;
+}
+static void
+hex_print( FILE* f, const char* var, void* data, size_t size )
+{
+    const char* conv = "0123456789abcdef";
+    size_t i;
+    char* p = (char*) data;
+    char c, d;
+
+    fprintf( f, var );
+    fprintf( f, " = " );
+    for ( i = 0; i < size; i++ )
+    {
+        c = conv[ (p[ i ] >> 4) & 0xf ];
+        d = conv[ p[ i ] & 0xf ];
+        fprintf( f, "%c%c", c, d );
+    }
+    fprintf( f, "\n" );
+}
+
diff --git a/src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.expected b/src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.expected
new file mode 100644 (file)
index 0000000..89789a6
--- /dev/null
@@ -0,0 +1,2 @@
+random1 = c27d031fce09ad26525e107021c1038062c9e05672065bce1139a9ae583d9cd70319e9a68d1f4da2cf24099af05ab1a910c781035864ab7e45337199cfa7ece05111d3604215feac555e847148dcf47fa8361746ce162201edbb83f4f753ad9933f9c618f86e15ff28eecdddbcaacd2ff212c236141b2edc5e5b91f2a95f89af5070eed9652f2857963801cff9f21d6a08f8c1480270009ebde555a00dcc60b0688cba89950aeeac8a0806922ea1baae494e1bc1be7920fa6c9b980a80f374a5ea53f3e10ffeef047bea388949fc0b66252d25c8775dd01a03a27528a4c801993129e581e3c4d77ecca9efaf27047d7eec025f6f0601d469a93f5be5cbac10b773a392a3d0a167ec76637014974fe6808e88b9b8fbd51dfbad7192d1edad971b11404f96849cc88dab07b21ff14d5d528d60c3bb7ad4b1ddc3e6b082df9d89b020d276db81676ffcf6521b2bab33c404b27f15f5547ee4a37654680fb331afb256a6cd83146a5baf70a6a5a455c7ead49493f7aa85d4afde951f33f44a99c49ea1e3f568b70735c46dce20460150d2c96aa0849cd5b7062253fdb11ba4a7e046fe24ccd3c87bbebe3351c10a8b6fb4b1e2dd46803782982970cf9805fa2a8540d9f910ea4e360a342a320cce34101472fdc258ba339038e464da6bc20b79df5fc6ae27762a7315d3b342d99eca5d23c5ce2f1ba800bdb68882a6b520e31037e8c1e1ea3444334ed6ec3913994344b714009b9cc816d57d5a74e1cbfe3f038f0def48f43ef81983a872068f60e808ed75997d23e4896faba5542738bd403b3d5fc33f64d606d376e936f89a60cf0ad417ba0f9cd4bb70287437e9f7d63572432d859473dadd9b8c51a8813e3e734968288afdb22a5779c1f6ccc681cf2332f634096f4d40088bdee97270a7d7c04d7b367001b7c154da3f69734fd91590710e54af97f4e03b80c800ccef3282b519aaa4a76f9cb06d6746211be6ca8ac910b3b0bb799ae185dbc92c8ac2d91f0c6e5bc7095e41ebd2b3217648ba62616a3820f282154ab2787f26c47c47bb099810b65e862ed44b9d47ac87d693d2f87295834274310f337b15a4d7b33d91ffefa7b3dfec270327db4b46a5e0e1cdc072e5d0a2e8392a2bede194ee715070785f1d1cb6a5bcd2f13b4aa644541b9e6336bbb87d88bead71858dfc4c211589865faf08c8cc9ba47728dc8d2ebc3fb6d9c434b8ad7f99fbc14124fb5ffaa24fb0c7650bb19e5e17379fb58579d3b41a007e3783f68cf523a9b1fbbbab2e40c9aa8049f4e2a609c4adc528b904792121e139bbf340980adc38ac32f9538790cad55351b46faae28a0c8d5a995d55e254694102901556c9ce648da6803c6480d5ad0e567ace44d88f5d45cc02e55f81b011d2c2188cd6e89aa6a7cffed6a14a8dbb592e4f386b5a7204d6a0d56cb0844c8df76f7697
+random2 = 9d87e8e1b4b74803357d0cc36ca668584c2bba571cb38f66fba3a2d03f897fcf392fd2f88184d330ca03e85b7c4531269849864ee6bc61d81501b7a5796377a73aa6c594b9b37f0e7c130acfac926a329d742ca0bf9edbc39d5bb64dffbbd81467be1fab250eaedbeff79bb2a697584a0b14626833d06f92dbdddd6bc12d6caba725d1eae4a899b4fd75b9bbd9ed05cca9f96c7cc41ae236f3c904f0d9ee4c83111e8dc2bf520a30bcfb2afb8943f61cfd4ef9364dab069276b282f831e1abad31048926ca3cccaa7406998620c941b1ded73d623c0659462e13bf68c0ceafbd5a23afb402b2477297e431182d964cd57cc494b26886af5037964467df5b2f0f981a5aaac9a1718b5b00c174adb0d4de383eb46ffb0ecffc4a432822b9af3d21e7b5b10b7e221978ffb47d058f33456518bc647f78d5e3f5e2850957a12f83b9a0c5a8736b509336eced539c9c0faeb37285f90bb12e3499ef9aaae8c5de67ac2e5b374dffe4e1c5c3f14c4cd8905c7a7db03ac69dbdcf627c2bd4f98dda671dd0da9b70495e476fdba17894665ee2c3f8bb9e5d015b0ee727ddf85115d5833fd13633afd2dd4d5bfa751c9a4b7e937c77939cb72f057714ad94a112d28b578ce265306b415339280748fd20977967f5b04ff92d93e994fe3fd4b887bb8fb7c8cd16af9877532e49df4ee3b7132fed5920d5fc5aeda6784f4371af614d1502f036c1519c53bec2a79303050562b1b929cf705254607486c550fbb40fb7445262929bb4ef8ed658c9e4a825ca0d3e796e5e681a5ce19c2c8880a44c78f205add4c8092a790f7a8d2fbae663d32ac0640317a9735e43369ed680247789330a372910a7ce356f8eafd8776972315bb83794589f22f21770cb1b7c17f25861da3fd142398a85ba357865da0684e916eade4d078deb78ccd5442c27d4e4973eb582d2d55fd5877c64f234a61dcc11a828afa5a52ddea02ad8001c09a60fc7a14bd7118486722db6bf3a54dded4691a7937c3cb546395fc99e49954216f203aaee05985a25ea284022c72dd0a156f030c6a2604b9332ab5324c35f77674836321bcd263f8c2176558d83e23cc00d0fa4d438e9536ab7e574067baeeaeda20b2af5f8ee0821e5ff7949a50c286da61b19d8c32cca7ce1459989731cedd2852a297a6b65637413747b47286a62cf4eabfb5308acbf2d593769f0e8d148945556f1fcfdc7cadd8a6e0c0e174ddb301610d201c7b78b079c2270ac5737fe4771d9bab5257dcf5cca173af2f374c6f68e4658189f1aff3bb81c99e56dc69d14249b07d36c2f73adcb5fa1b71b629a0957b571bf6af13c12983056b6263c9c484b0778c3c1eb1261399644e942eb54479461af9397d7413822a4f267304b1dafc32744ef543a3f3442e05d70c727ac1afb846454aa50d2d979349c508f46981c297672ee78a1
diff --git a/src/lib/crypto/krb/prng/nss/Makefile.in b/src/lib/crypto/krb/prng/nss/Makefile.in
new file mode 100644 (file)
index 0000000..3f537e5
--- /dev/null
@@ -0,0 +1,31 @@
+mydir=lib/crypto/krb/prng/nss
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../.. \
+               -I$(srcdir)/../../../@CRYPTO_IMPL@
+DEFS=
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+STLIBOBJS=  prng_nss.o
+OBJS= \
+       $(OUTPRE)prng_nss.$(OBJEXT)
+
+SRCS=\
+       $(srcdir)/prng_nss.c 
+
+all-unix:: all-libobjs
+
+includes:: depend
+
+depend:: $(SRCS)
+
+clean::
+       $(RM) t_nss$(EXEEXT) t_nss.$(OBJEXT)  t_nss_make_oct.result  t_nss_make_oct$(EXEEXT)  t_nss_make_oct.$(OBJEXT)
+
+
+clean-unix:: clean-libobjs
+
+@lib_frag@
+@libobj_frag@
+
diff --git a/src/lib/crypto/krb/prng/nss/deps b/src/lib/crypto/krb/prng/nss/deps
new file mode 100644 (file)
index 0000000..b75e678
--- /dev/null
@@ -0,0 +1,17 @@
+# 
+# Generated makefile dependencies follow.
+#
+prng_nss.so prng_nss.po $(OUTPRE)prng_nss.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../../builtin/aes/aes.h \
+  $(srcdir)/../prng.h \
+  $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  prng_nss.c prng_nss.h 
+
diff --git a/src/lib/crypto/krb/prng/nss/prng_nss.c b/src/lib/crypto/krb/prng/nss/prng_nss.c
new file mode 100644 (file)
index 0000000..c42e63a
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * prng_nss.c
+ *
+ * Copyright (C) 2008, 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "prng.h"
+#include <assert.h>
+#include "k5-thread.h"
+
+#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.
+ */
+
+#include "../nss/nss_gen.h"
+#include <pk11pub.h>
+
+static int
+nss_init(void)
+{
+    return 0;
+}
+
+static krb5_error_code
+nss_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;
+}
+
+static krb5_error_code
+nss_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;
+}
+
+static void
+nss_cleanup (void)
+{
+}
+
+const struct krb5_prng_provider krb5int_prng_nss = {
+    "nss",
+    nss_make_octets,
+    nss_add_entropy,
+    nss_init,
+    nss_cleanup
+};
+#endif
diff --git a/src/lib/crypto/krb/prng/nss/prng_nss.h b/src/lib/crypto/krb/prng/nss/prng_nss.h
new file mode 100644 (file)
index 0000000..5bfed3e
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prng/fortuna.h
+ *
+ * Copyright 2010 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef FORTUNA_H
+#define FORTUNA_H
+
+#include "k5-int.h"
+#include "prng.h"
+
+extern const struct krb5_prng_provider krb5int_prng_nss;
+
+#endif
diff --git a/src/lib/crypto/krb/prng/prng.h b/src/lib/crypto/krb/prng/prng.h
new file mode 100644 (file)
index 0000000..f4a0e6f
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prng/prng.h
+ *
+ * Copyright 2010 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+
+#ifndef PRNG_H
+#define PRNG_H
+
+#include "k5-int.h"
+
+#if defined(FORTUNA)
+#define ENTROPY_BUFSIZE 32  /* SHA256 digest length */
+#elif defined(CRYPTO_IMPL_NSS)
+/*
+ * NSS gathers its own OS entropy, so it doesn't really matter how much we read
+ * in krb5_c_random_os_entropy.  Use the same value as Yarrow (without using a
+ * Yarrow constant), so that we don't read too much from /dev/random.
+ */
+#define ENTROPY_BUFSIZE 20
+#else
+#define ENTROPY_BUFSIZE YARROW_SLOW_THRESH/8  /* SHA1 digest length*/
+#endif
+
+/* prng.h */
+struct krb5_prng_provider {
+    char prng_name[8];
+    krb5_error_code (*make_octets)(krb5_context, krb5_data *);
+    krb5_error_code (*add_entropy)(krb5_context, unsigned int randsource, const krb5_data*);
+    int (*init)(void);
+    void (*cleanup)(void);
+};
+
+#endif
diff --git a/src/lib/crypto/krb/prng/yarrow/prng_yarrow.c b/src/lib/crypto/krb/prng/yarrow/prng_yarrow.c
new file mode 100644 (file)
index 0000000..d1f0e7f
--- /dev/null
@@ -0,0 +1,138 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * prng_yarrow.c
+ *
+ * Copyright (C) 2001, 2002, 2004, 2007, 2008, 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "prng.h"
+#include "enc_provider.h"
+#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;
+
+/* Helper function to estimate entropy based on sample length
+ * and where it comes from.
+ */
+
+static size_t
+entropy_estimate(unsigned int randsource, size_t length)
+{
+    switch (randsource) {
+    case KRB5_C_RANDSOURCE_OLDAPI:
+        return 4 * length;
+    case KRB5_C_RANDSOURCE_OSRAND:
+        return 8 * length;
+    case KRB5_C_RANDSOURCE_TRUSTEDPARTY:
+        return 4 * length;
+    case KRB5_C_RANDSOURCE_TIMING:
+        return 2;
+    case KRB5_C_RANDSOURCE_EXTERNAL_PROTOCOL:
+        return 0;
+    default:
+        abort();
+    }
+    return 0;
+}
+
+static int
+yarrow_init(void)
+{
+    unsigned i, source_id;
+    int yerr;
+
+    yerr = k5_mutex_finish_init(&yarrow_lock);
+    if (yerr)
+        return yerr;
+
+    yerr = krb5int_yarrow_init (&y_ctx, NULL);
+    if (yerr != YARROW_OK && yerr != YARROW_NOT_SEEDED)
+        return KRB5_CRYPTO_INTERNAL;
+
+    for (i=0; i < KRB5_C_RANDSOURCE_MAX; i++ ) {
+        if (krb5int_yarrow_new_source(&y_ctx, &source_id) != YARROW_OK)
+            return KRB5_CRYPTO_INTERNAL;
+        assert (source_id == i);
+    }
+
+    return 0;
+}
+
+static krb5_error_code
+yarrow_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;
+    /* Now, finally, feed in the data.  */
+    yerr = krb5int_yarrow_input(&y_ctx, randsource,
+                                data->data, data->length,
+                                entropy_estimate(randsource, data->length));
+    if (yerr != YARROW_OK)
+        return KRB5_CRYPTO_INTERNAL;
+    return 0;
+}
+/*
+static krb5_error_code
+yarrow_seed(krb5_context context, krb5_data *data)
+{
+    return yarrow_add_entropy(context, KRB5_C_RANDSOURCE_OLDAPI, data);
+}
+*/
+static krb5_error_code
+yarrow_make_octets(krb5_context context, krb5_data *data)
+{
+    int 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);
+    }
+    if (yerr != YARROW_OK)
+        return KRB5_CRYPTO_INTERNAL;
+    return 0;
+}
+
+static void
+yarrow_cleanup (void)
+{
+    krb5int_yarrow_final (&y_ctx);
+    k5_mutex_destroy(&yarrow_lock);
+}
+
+const struct krb5_prng_provider krb5int_prng_yarrow = {
+    "yarrow",
+    yarrow_make_octets,
+    yarrow_add_entropy,
+    yarrow_init,
+    yarrow_cleanup
+};
diff --git a/src/lib/crypto/nss/sha2/Makefile.in b/src/lib/crypto/nss/sha2/Makefile.in
new file mode 100644 (file)
index 0000000..b42462e
--- /dev/null
@@ -0,0 +1,32 @@
+mydir=lib/crypto/nss/sha2
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+DEFS=
+LOCALINCLUDES = -I$(srcdir)/.. @CRYPTO_IMPL_CFLAGS@
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR=sha1
+##DOS##OBJFILE=..\$(OUTPRE)sha2.lst
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+STLIBOBJS= sha2.o
+
+OBJS= $(OUTPRE)sha2.$(OBJEXT) 
+
+SRCS= $(srcdir)/sha2.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix:: all-libobjs
+
+includes:: depend
+
+depend:: $(SRCS)
+
+clean::
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/nss/sha2/deps b/src/lib/crypto/nss/sha2/deps
new file mode 100644 (file)
index 0000000..e75ca6b
--- /dev/null
@@ -0,0 +1,14 @@
+# 
+# Generated makefile dependencies follow.
+#
+shs.so shs.po $(OUTPRE)shs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
+  $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h $(srcdir)/shs.c \
+  $(srcdir)/shs.h
diff --git a/src/lib/crypto/nss/sha2/sha2.c b/src/lib/crypto/nss/sha2/sha2.c
new file mode 100644 (file)
index 0000000..71f27b4
--- /dev/null
@@ -0,0 +1,19 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+#include "k5-int.h"
+#include "sha2.h"
+
+void sha2Init(SHA2_INFO *shsInfo)
+{
+    return;
+}
+
+void sha2Update(SHA2_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count)
+{
+    return;
+}
+
+void sha2Final(SHA2_INFO *shsInfo)
+{
+    return;
+}
diff --git a/src/lib/crypto/nss/sha2/sha2.h b/src/lib/crypto/nss/sha2/sha2.h
new file mode 100644 (file)
index 0000000..ade8b61
--- /dev/null
@@ -0,0 +1,23 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#ifndef _SHA2_DEFINED
+
+#include "k5-int.h"
+
+#define _SHA2_DEFINED
+
+typedef krb5_octet      SHS_BYTE;
+#define SHA2_DIGESTSIZE  32
+
+/* The structure for storing SHA2 info */
+
+typedef struct {
+    void *nss_ctxt;
+    unsigned char   digestBuf[SHA2_DIGESTSIZE]; /* output */
+    unsigned int    digestLen; /* output */
+} SHA2_INFO;
+
+void sha2Init(SHA2_INFO *shsInfo);
+void sha2Update(SHA2_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count);
+void sha2Final(SHA2_INFO *shsInfo);
+
+#endif /* _SHA2_DEFINED */