From cf38783a30f793857f179cca9186996f3bad2b71 Mon Sep 17 00:00:00 2001 From: Zhanna Tsitkov Date: Tue, 5 Oct 2010 03:29:35 +0000 Subject: [PATCH] Some missed files needed for rev #24420 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24421 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/crypto/krb/prng/Makefile.in | 41 ++ src/lib/crypto/krb/prng/deps | 16 + src/lib/crypto/krb/prng/fortuna/Makefile.in | 53 ++ src/lib/crypto/krb/prng/fortuna/deps | 45 ++ src/lib/crypto/krb/prng/fortuna/entropy.c | 84 +++ src/lib/crypto/krb/prng/fortuna/fortuna.h | 62 ++ .../crypto/krb/prng/fortuna/prng_fortuna.c | 614 ++++++++++++++++++ src/lib/crypto/krb/prng/fortuna/t_fortuna.c | 81 +++ .../krb/prng/fortuna/t_fortuna_make_oct.c | 85 +++ .../prng/fortuna/t_fortuna_make_oct.expected | 2 + src/lib/crypto/krb/prng/nss/Makefile.in | 31 + src/lib/crypto/krb/prng/nss/deps | 17 + src/lib/crypto/krb/prng/nss/prng_nss.c | 92 +++ src/lib/crypto/krb/prng/nss/prng_nss.h | 36 + src/lib/crypto/krb/prng/prng.h | 56 ++ src/lib/crypto/krb/prng/yarrow/prng_yarrow.c | 138 ++++ src/lib/crypto/nss/sha2/Makefile.in | 32 + src/lib/crypto/nss/sha2/deps | 14 + src/lib/crypto/nss/sha2/sha2.c | 19 + src/lib/crypto/nss/sha2/sha2.h | 23 + 20 files changed, 1541 insertions(+) create mode 100644 src/lib/crypto/krb/prng/Makefile.in create mode 100644 src/lib/crypto/krb/prng/deps create mode 100644 src/lib/crypto/krb/prng/fortuna/Makefile.in create mode 100644 src/lib/crypto/krb/prng/fortuna/deps create mode 100644 src/lib/crypto/krb/prng/fortuna/entropy.c create mode 100644 src/lib/crypto/krb/prng/fortuna/fortuna.h create mode 100644 src/lib/crypto/krb/prng/fortuna/prng_fortuna.c create mode 100644 src/lib/crypto/krb/prng/fortuna/t_fortuna.c create mode 100644 src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.c create mode 100644 src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.expected create mode 100644 src/lib/crypto/krb/prng/nss/Makefile.in create mode 100644 src/lib/crypto/krb/prng/nss/deps create mode 100644 src/lib/crypto/krb/prng/nss/prng_nss.c create mode 100644 src/lib/crypto/krb/prng/nss/prng_nss.h create mode 100644 src/lib/crypto/krb/prng/prng.h create mode 100644 src/lib/crypto/krb/prng/yarrow/prng_yarrow.c create mode 100644 src/lib/crypto/nss/sha2/Makefile.in create mode 100644 src/lib/crypto/nss/sha2/deps create mode 100644 src/lib/crypto/nss/sha2/sha2.c create mode 100644 src/lib/crypto/nss/sha2/sha2.h diff --git a/src/lib/crypto/krb/prng/Makefile.in b/src/lib/crypto/krb/prng/Makefile.in new file mode 100644 index 000000000..76a9388b8 --- /dev/null +++ b/src/lib/crypto/krb/prng/Makefile.in @@ -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 index 000000000..bde1cdd49 --- /dev/null +++ b/src/lib/crypto/krb/prng/deps @@ -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 index 000000000..df960c23e --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/Makefile.in @@ -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 index 000000000..1d420c571 --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/deps @@ -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 index 000000000..0f9344e5b --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/entropy.c @@ -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 index 000000000..34fde09e1 --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/fortuna.h @@ -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 index 000000000..07a52a928 --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/prng_fortuna.c @@ -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 index 000000000..3365f6693 --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/t_fortuna.c @@ -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 + + +#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 index 000000000..42a5be209 --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.c @@ -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 + +#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 index 000000000..89789a67b --- /dev/null +++ b/src/lib/crypto/krb/prng/fortuna/t_fortuna_make_oct.expected @@ -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 index 000000000..3f537e57e --- /dev/null +++ b/src/lib/crypto/krb/prng/nss/Makefile.in @@ -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 index 000000000..b75e678ab --- /dev/null +++ b/src/lib/crypto/krb/prng/nss/deps @@ -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 index 000000000..c42e63ac3 --- /dev/null +++ b/src/lib/crypto/krb/prng/nss/prng_nss.c @@ -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 +#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 + +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 index 000000000..5bfed3ef2 --- /dev/null +++ b/src/lib/crypto/krb/prng/nss/prng_nss.h @@ -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 index 000000000..f4a0e6fa8 --- /dev/null +++ b/src/lib/crypto/krb/prng/prng.h @@ -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 index 000000000..d1f0e7f8a --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/prng_yarrow.c @@ -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 +#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 index 000000000..b42462eb2 --- /dev/null +++ b/src/lib/crypto/nss/sha2/Makefile.in @@ -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 index 000000000..e75ca6bcf --- /dev/null +++ b/src/lib/crypto/nss/sha2/deps @@ -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 index 000000000..71f27b4e7 --- /dev/null +++ b/src/lib/crypto/nss/sha2/sha2.c @@ -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 index 000000000..ade8b615a --- /dev/null +++ b/src/lib/crypto/nss/sha2/sha2.h @@ -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 */ -- 2.26.2