From 4bff2d892d71f928916326e472a1d4460b083bca Mon Sep 17 00:00:00 2001 From: Zhanna Tsitkov Date: Tue, 5 Oct 2010 03:18:22 +0000 Subject: Improves prng code modularity. Introduces fortuna-like prng that can be used in lieu of yarrow. Yarrow stays the default prng while fortuna may be engaged during configuration by using "--with-prng-alg=fortuna" flag. Also, nss crypto backend continues to use its own prng. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24420 dc483132-0cff-0310-8789-dd5450dbe970 --- src/Makefile.in | 5 +- src/configure.in | 33 +- src/lib/crypto/Makefile.in | 8 +- src/lib/crypto/builtin/Makefile.in | 13 +- src/lib/crypto/builtin/sha2/Makefile.in | 44 ++ src/lib/crypto/builtin/sha2/deps | 14 + src/lib/crypto/builtin/sha2/sha2.h | 91 +++ src/lib/crypto/builtin/sha2/sha256.c | 232 +++++++ src/lib/crypto/builtin/sha2/t_sha256.c | 126 ++++ src/lib/crypto/crypto_tests/Makefile.in | 11 +- src/lib/crypto/krb/Makefile.in | 25 +- src/lib/crypto/krb/prng.c | 282 --------- src/lib/crypto/krb/prng/prng.c | 180 ++++++ src/lib/crypto/krb/prng/yarrow/ASSUMPTIONS | 101 +++ src/lib/crypto/krb/prng/yarrow/LICENSE | 21 + src/lib/crypto/krb/prng/yarrow/Makefile.in | 42 ++ src/lib/crypto/krb/prng/yarrow/README | 94 +++ src/lib/crypto/krb/prng/yarrow/TODO | 9 + src/lib/crypto/krb/prng/yarrow/deps | 41 ++ src/lib/crypto/krb/prng/yarrow/yarrow.c | 959 +++++++++++++++++++++++++++++ src/lib/crypto/krb/prng/yarrow/yarrow.h | 188 ++++++ src/lib/crypto/krb/prng/yarrow/yarrow.man | 315 ++++++++++ src/lib/crypto/krb/prng/yarrow/yarrow.pod | 112 ++++ src/lib/crypto/krb/prng/yarrow/ycipher.c | 89 +++ src/lib/crypto/krb/prng/yarrow/ycipher.h | 43 ++ src/lib/crypto/krb/prng/yarrow/yexcep.h | 107 ++++ src/lib/crypto/krb/prng/yarrow/ylock.h | 24 + src/lib/crypto/krb/prng/yarrow/ystate.h | 28 + src/lib/crypto/krb/prng/yarrow/ytypes.h | 27 + src/lib/crypto/krb/yarrow/ASSUMPTIONS | 101 --- src/lib/crypto/krb/yarrow/LICENSE | 21 - src/lib/crypto/krb/yarrow/Makefile.in | 38 -- src/lib/crypto/krb/yarrow/README | 94 --- src/lib/crypto/krb/yarrow/TODO | 9 - src/lib/crypto/krb/yarrow/deps | 29 - src/lib/crypto/krb/yarrow/yarrow.c | 959 ----------------------------- src/lib/crypto/krb/yarrow/yarrow.h | 186 ------ src/lib/crypto/krb/yarrow/yarrow.man | 315 ---------- src/lib/crypto/krb/yarrow/yarrow.pod | 112 ---- src/lib/crypto/krb/yarrow/ycipher.c | 95 --- src/lib/crypto/krb/yarrow/ycipher.h | 43 -- src/lib/crypto/krb/yarrow/yexcep.h | 107 ---- src/lib/crypto/krb/yarrow/ylock.h | 24 - src/lib/crypto/krb/yarrow/ystate.h | 28 - src/lib/crypto/krb/yarrow/ytypes.h | 27 - src/lib/crypto/nss/Makefile.in | 16 +- src/lib/crypto/openssl/Makefile.in | 13 +- src/lib/crypto/openssl/sha2/Makefile.in | 31 + src/lib/crypto/openssl/sha2/deps | 13 + src/lib/crypto/openssl/sha2/sha2.h | 42 ++ src/lib/crypto/openssl/sha2/sha256.c | 28 + src/util/collected-client-lib/Makefile.in | 3 +- 52 files changed, 3096 insertions(+), 2502 deletions(-) create mode 100644 src/lib/crypto/builtin/sha2/Makefile.in create mode 100644 src/lib/crypto/builtin/sha2/deps create mode 100644 src/lib/crypto/builtin/sha2/sha2.h create mode 100644 src/lib/crypto/builtin/sha2/sha256.c create mode 100644 src/lib/crypto/builtin/sha2/t_sha256.c delete mode 100644 src/lib/crypto/krb/prng.c create mode 100644 src/lib/crypto/krb/prng/prng.c create mode 100644 src/lib/crypto/krb/prng/yarrow/ASSUMPTIONS create mode 100644 src/lib/crypto/krb/prng/yarrow/LICENSE create mode 100644 src/lib/crypto/krb/prng/yarrow/Makefile.in create mode 100644 src/lib/crypto/krb/prng/yarrow/README create mode 100644 src/lib/crypto/krb/prng/yarrow/TODO create mode 100644 src/lib/crypto/krb/prng/yarrow/deps create mode 100644 src/lib/crypto/krb/prng/yarrow/yarrow.c create mode 100644 src/lib/crypto/krb/prng/yarrow/yarrow.h create mode 100644 src/lib/crypto/krb/prng/yarrow/yarrow.man create mode 100644 src/lib/crypto/krb/prng/yarrow/yarrow.pod create mode 100644 src/lib/crypto/krb/prng/yarrow/ycipher.c create mode 100644 src/lib/crypto/krb/prng/yarrow/ycipher.h create mode 100644 src/lib/crypto/krb/prng/yarrow/yexcep.h create mode 100644 src/lib/crypto/krb/prng/yarrow/ylock.h create mode 100644 src/lib/crypto/krb/prng/yarrow/ystate.h create mode 100644 src/lib/crypto/krb/prng/yarrow/ytypes.h delete mode 100644 src/lib/crypto/krb/yarrow/ASSUMPTIONS delete mode 100644 src/lib/crypto/krb/yarrow/LICENSE delete mode 100644 src/lib/crypto/krb/yarrow/Makefile.in delete mode 100644 src/lib/crypto/krb/yarrow/README delete mode 100644 src/lib/crypto/krb/yarrow/TODO delete mode 100644 src/lib/crypto/krb/yarrow/deps delete mode 100644 src/lib/crypto/krb/yarrow/yarrow.c delete mode 100644 src/lib/crypto/krb/yarrow/yarrow.h delete mode 100644 src/lib/crypto/krb/yarrow/yarrow.man delete mode 100644 src/lib/crypto/krb/yarrow/yarrow.pod delete mode 100644 src/lib/crypto/krb/yarrow/ycipher.c delete mode 100644 src/lib/crypto/krb/yarrow/ycipher.h delete mode 100644 src/lib/crypto/krb/yarrow/yexcep.h delete mode 100644 src/lib/crypto/krb/yarrow/ylock.h delete mode 100644 src/lib/crypto/krb/yarrow/ystate.h delete mode 100644 src/lib/crypto/krb/yarrow/ytypes.h create mode 100644 src/lib/crypto/openssl/sha2/Makefile.in create mode 100644 src/lib/crypto/openssl/sha2/deps create mode 100644 src/lib/crypto/openssl/sha2/sha2.h create mode 100644 src/lib/crypto/openssl/sha2/sha256.c diff --git a/src/Makefile.in b/src/Makefile.in index 72b7d355a..64a5aad10 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -204,7 +204,7 @@ WINMAKEFILES=Makefile \ lib\crypto\krb\raw\Makefile lib\crypto\krb\old\Makefile \ lib\crypto\@CRYPTO_IMPL@\sha1\Makefile lib\crypto\@CRYPTO_IMPL@\arcfour\Makefile \ lib\crypto\@CRYPTO_IMPL@\md4\Makefile lib\crypto\@CRYPTO_IMPL@\md5\Makefile \ - lib\crypto\krb\yarrow\Makefile lib\crypto\@CRYPTO_IMPL@\aes\Makefile \ + lib\crypto\krb\prng\Makefile lib\crypto\@CRYPTO_IMPL@\aes\Makefile \ lib\crypto\crypto_tests \ lib\gssapi\Makefile lib\gssapi\generic\Makefile \ lib\gssapi\krb5\Makefile lib\gssapi\mechglue\Makefile \ @@ -404,7 +404,8 @@ FILES= ./* \ lib/crypto/krb/old/* lib/crypto/krb/raw/* \ lib/crypto/@CRYPTO_IMPL@/sha1/* lib/crypto/@CRYPTO_IMPL@/arcfour/* \ lib/crypto/@CRYPTO_IMPL@/md4/* \ - lib/crypto/@CRYPTO_IMPL@/md5/* lib/crypto/krb/yarrow/* \ + lib/crypto/@CRYPTO_IMPL@/md5/* lib/crypto/krb/prng/* \ + lib/crypto/krb/prng/@PRNG_ALG@/* \ lib/crypto/@CRYPTO_IMPL@/* lib/crypto/krb/* lib/crypto/crypto_tests \ lib/gssapi/* lib/gssapi/generic/* lib/gssapi/krb5/* \ lib/gssapi/mechglue/* lib/gssapi/spnego/* \ diff --git a/src/configure.in b/src/configure.in index 70e9817c3..20e014e90 100644 --- a/src/configure.in +++ b/src/configure.in @@ -145,6 +145,31 @@ AC_SUBST(CRYPTO_IMPL) AC_SUBST(CRYPTO_IMPL_CFLAGS) AC_SUBST(CRYPTO_IMPL_LIBS) +if test "$CRYPTO_IMPL" = nss; then + PRNG_ALG="nss" +else +PRNG_ALG="yarrow" +AC_ARG_WITH([prng-alg], +AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. Ignored for nss. @<:@yarrow@:>@]), +[PRNG_ALG=$withval +AC_MSG_RESULT("k5crypto will use \'$withval\'") +], withval=yarrow) +fi +AC_CONFIG_COMMANDS(PRNG_ALG, , PRNG_ALG=$PRNG_ALG) +AC_SUBST(PRNG_ALG) +if test "$withval" = fortuna; then + AC_DEFINE(FORTUNA,1,[Define if Fortuna PRNG is selected]) +fi + +AC_ARG_ENABLE([fortuna-test], + [ --enable-fortuna-test build to test Fortuna PRNG],,enableval=no) +if test "$enableval" = yes ; then + PRNG_FORTUNA_TEST="yes" + AC_DEFINE(TEST_FORTUNA,1,[Create a special build to test Fortuna PRNG]) + AC_CONFIG_COMMANDS(PRNG_FORTUNA_TEST, , PRNG_FORTUNA_TEST=$PRNG_FORTUNA_TEST) + AC_SUBST(PRNG_FORTUNA_TEST) +fi + # --with-kdc-kdb-update makes the KDC update the database with last request # information and failure information. @@ -1101,8 +1126,12 @@ V5_AC_OUTPUT_MAKEFILE(. lib/crypto/$CRYPTO_IMPL/hash_provider lib/crypto/krb/checksum lib/crypto/krb/prf lib/crypto/krb/rand2key lib/crypto/$CRYPTO_IMPL lib/crypto/$CRYPTO_IMPL/md4 lib/crypto/$CRYPTO_IMPL/md5 - lib/crypto/krb/old lib/crypto/krb/raw lib/crypto/$CRYPTO_IMPL/sha1 - lib/crypto/krb/arcfour lib/crypto/krb/yarrow lib/crypto/$CRYPTO_IMPL/aes + lib/crypto/krb/old lib/crypto/krb/raw + lib/crypto/$CRYPTO_IMPL/sha1 + lib/crypto/$CRYPTO_IMPL/sha2 + lib/crypto/krb/arcfour lib/crypto/krb/prng + lib/crypto/krb/prng/$PRNG_ALG + lib/crypto/$CRYPTO_IMPL/aes lib/crypto/$CRYPTO_IMPL/camellia lib/crypto/crypto_tests lib/krb5 lib/krb5/error_tables lib/krb5/asn.1 lib/krb5/ccache diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index 579d0829c..3749a15a6 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -22,9 +22,11 @@ STOBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST \ @CRYPTO_IMPL@/enc_provider/OBJS.ST \ @CRYPTO_IMPL@/hash_provider/OBJS.ST \ krb/checksum/OBJS.ST krb/prf/OBJS.ST krb/rand2key/OBJS.ST \ - krb/old/OBJS.ST krb/raw/OBJS.ST krb/yarrow/OBJS.ST \ + krb/old/OBJS.ST krb/raw/OBJS.ST krb/prng/OBJS.ST \ + krb/prng/@PRNG_ALG@/OBJS.ST \ @CRYPTO_IMPL@/md4/OBJS.ST @CRYPTO_IMPL@/md5/OBJS.ST \ @CRYPTO_IMPL@/sha1/OBJS.ST \ + @CRYPTO_IMPL@/sha2/OBJS.ST \ krb/arcfour/OBJS.ST \ @CRYPTO_IMPL@/aes/OBJS.ST @CRYPTO_IMPL@/des/OBJS.ST \ @CRYPTO_IMPL@/camellia/OBJS.ST krb/OBJS.ST \ @@ -34,9 +36,11 @@ SUBDIROBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST \ @CRYPTO_IMPL@/enc_provider/OBJS.ST \ @CRYPTO_IMPL@/hash_provider/OBJS.ST \ krb/checksum/OBJS.ST krb/prf/OBJS.ST krb/rand2key/OBJS.ST \ - krb/old/OBJS.ST krb/raw/OBJS.ST krb/yarrow/OBJS.ST \ + krb/old/OBJS.ST krb/raw/OBJS.ST krb/prng/OBJS.ST \ + krb/prng/@PRNG_ALG@/OBJS.ST \ @CRYPTO_IMPL@/md4/OBJS.ST @CRYPTO_IMPL@/md5/OBJS.ST \ @CRYPTO_IMPL@/sha1/OBJS.ST \ + @CRYPTO_IMPL@/sha2/OBJS.ST \ krb/arcfour/OBJS.ST \ @CRYPTO_IMPL@/aes/OBJS.ST @CRYPTO_IMPL@/des/OBJS.ST \ @CRYPTO_IMPL@/camellia/OBJS.ST krb/OBJS.ST \ diff --git a/src/lib/crypto/builtin/Makefile.in b/src/lib/crypto/builtin/Makefile.in index 5dd7fafdd..240d2895b 100644 --- a/src/lib/crypto/builtin/Makefile.in +++ b/src/lib/crypto/builtin/Makefile.in @@ -1,12 +1,13 @@ mydir=lib/crypto/builtin BUILDTOP=$(REL)..$(S)..$(S).. -SUBDIRS=camellia des aes md4 md5 sha1 enc_provider hash_provider +SUBDIRS=camellia des aes md4 md5 sha1 sha2 enc_provider hash_provider LOCALINCLUDES = -I$(srcdir)/../krb \ -I$(srcdir)/../krb/hash_provider \ -I$(srcdir)/des \ -I$(srcdir)/aes \ -I$(srcdir)/camellia \ -I$(srcdir)/sha1 \ + -I$(srcdir)/sha2 \ -I$(srcdir)/md4 \ -I$(srcdir)/md5 \ -I$(srcdir)/enc_provider \ @@ -41,7 +42,7 @@ SRCS=\ $(srcdir)/pbkdf2.c STOBJLISTS= des/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST sha1/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST \ @@ -49,7 +50,7 @@ STOBJLISTS= des/OBJS.ST md4/OBJS.ST \ OBJS.ST SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST sha1/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST \ @@ -89,6 +90,9 @@ all-windows:: cd ..\sha1 @echo Making in crypto\sha1 $(MAKE) -$(MFLAGS) + cd ..\sh2a + @echo Making in crypto\sha2 + $(MAKE) -$(MFLAGS) cd ..\hash_provider @echo Making in crypto\hash_provider $(MAKE) -$(MFLAGS) @@ -116,6 +120,9 @@ clean-windows:: cd ..\sha1 @echo Making clean in crypto\sha1 $(MAKE) -$(MFLAGS) clean + cd ..\sha2 + @echo Making clean in crypto\sha2 + $(MAKE) -$(MFLAGS) clean cd ..\hash_provider @echo Making clean in crypto\hash_provider $(MAKE) -$(MFLAGS) clean diff --git a/src/lib/crypto/builtin/sha2/Makefile.in b/src/lib/crypto/builtin/sha2/Makefile.in new file mode 100644 index 000000000..535d7eeb8 --- /dev/null +++ b/src/lib/crypto/builtin/sha2/Makefile.in @@ -0,0 +1,44 @@ +mydir=lib/crypto/builtin/sha2 +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=sha2 +##DOS##OBJFILE=..\$(OUTPRE)sha2.lst + +RUN_SETUP = @KRB5_RUN_ENV@ +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= sha256.o + +OBJS= $(OUTPRE)sha256.$(OBJEXT) + +SRCS= $(srcdir)/sha256.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +t_sha256: t_sha256.o sha256.o $(SUPPORT_DEPLIB) + $(CC_LINK) -o t_sha256 t_sha256.o sha256.o $(SUPPORT_LIB) + + +$(OUTPRE)t_sha256.exe: $(OUTPRE)t_sha256.obj $(OUTPRE)sha256.obj + link -out:$@ $** + + +check-unix:: t_sha256 + $(RUN_SETUP) $(VALGRIND) $(C)t_sha256 + +clean:: + $(RM) t_sha256$(EXEEXT) t_sha256$(OBJEXT) + +clean-unix:: clean-libobjs + +@libobj_frag@ + diff --git a/src/lib/crypto/builtin/sha2/deps b/src/lib/crypto/builtin/sha2/deps new file mode 100644 index 000000000..85b60989a --- /dev/null +++ b/src/lib/crypto/builtin/sha2/deps @@ -0,0 +1,14 @@ +# +# Generated makefile dependencies follow. +# +sha256.so sha256.po $(OUTPRE)sha256.$(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/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 \ + sha256.c sha2.h diff --git a/src/lib/crypto/builtin/sha2/sha2.h b/src/lib/crypto/builtin/sha2/sha2.h new file mode 100644 index 000000000..0cff88f4a --- /dev/null +++ b/src/lib/crypto/builtin/sha2/sha2.h @@ -0,0 +1,91 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * Copyright (c) 1995 - 2001 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. + */ + +/* $Id$ */ + +#ifndef HEIM_SHA_H +#define HEIM_SHA_H 1 + +#include +/* +#include +#include +#include +#ifdef KRB5 +#include +#endif +*/ +#ifndef min +#define min(a,b) (((a)>(b))?(b):(a)) +#endif + +/* Vector Crays doesn't have a good 32-bit type, or more precisely, + * int32_t as defined by isn't 32 bits, and we don't + * want to depend in being able to redefine this type. To cope with + * this we have to clamp the result in some places to [0,2^32); no + * need to do this on other machines. Did I say this was a mess? + */ + +#ifdef _CRAY +#define CRAYFIX(X) ((X) & 0xffffffff) +#else +#define CRAYFIX(X) (X) +#endif + +static inline uint32_t +cshift (uint32_t x, unsigned int n) +{ + x = CRAYFIX(x); + return CRAYFIX((x << n) | (x >> (32 - n))); +} + +/* + * SHA-2 256 + */ + +#define SHA256_DIGEST_LENGTH 32 + +struct sha256state { + unsigned int sz[2]; + uint32_t counter[8]; + unsigned char save[64]; +}; + +typedef struct sha256state SHA256_CTX; + +void sha2Init (SHA256_CTX *); +void sha2Update (SHA256_CTX *, const void *, size_t); +void sha2Final (void *, SHA256_CTX *); + +#endif /* HEIM_SHA_H */ diff --git a/src/lib/crypto/builtin/sha2/sha256.c b/src/lib/crypto/builtin/sha2/sha256.c new file mode 100644 index 000000000..fb66bff70 --- /dev/null +++ b/src/lib/crypto/builtin/sha2/sha256.c @@ -0,0 +1,232 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/builtin/sha256.c */ +/* + * Copyright (c) 2006 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 +#include "sha2.h" + +#ifdef FORTUNA + +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define ROTR(x,n) (((x)>>(n)) | ((x) << (32 - (n)))) + +#define Sigma0(x) (ROTR(x,2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define Sigma1(x) (ROTR(x,6) ^ ROTR(x,11) ^ ROTR(x,25)) +#define sigma0(x) (ROTR(x,7) ^ ROTR(x,18) ^ ((x)>>3)) +#define sigma1(x) (ROTR(x,17) ^ ROTR(x,19) ^ ((x)>>10)) + +#define A m->counter[0] +#define B m->counter[1] +#define C m->counter[2] +#define D m->counter[3] +#define E m->counter[4] +#define F m->counter[5] +#define G m->counter[6] +#define H m->counter[7] + +static const uint32_t constant_256[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +void +sha2Init (SHA256_CTX *m) +{ + m->sz[0] = 0; + m->sz[1] = 0; + A = 0x6a09e667; + B = 0xbb67ae85; + C = 0x3c6ef372; + D = 0xa54ff53a; + E = 0x510e527f; + F = 0x9b05688c; + G = 0x1f83d9ab; + H = 0x5be0cd19; +} + +static void +calc (SHA256_CTX *m, uint32_t *in) +{ + uint32_t AA, BB, CC, DD, EE, FF, GG, HH; + uint32_t data[64]; + int i; + + AA = A; + BB = B; + CC = C; + DD = D; + EE = E; + FF = F; + GG = G; + HH = H; + + for (i = 0; i < 16; ++i) + data[i] = in[i]; + for (i = 16; i < 64; ++i) + data[i] = sigma1(data[i-2]) + data[i-7] + + sigma0(data[i-15]) + data[i - 16]; + + for (i = 0; i < 64; i++) { + uint32_t T1, T2; + + T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_256[i] + data[i]; + T2 = Sigma0(AA) + Maj(AA,BB,CC); + + HH = GG; + GG = FF; + FF = EE; + EE = DD + T1; + DD = CC; + CC = BB; + BB = AA; + AA = T1 + T2; + } + + A += AA; + B += BB; + C += CC; + D += DD; + E += EE; + F += FF; + G += GG; + H += HH; +} + +/* + * From `Performance analysis of MD5' by Joseph D. Touch + */ + +#if !defined(WORDS_BIGENDIAN) || defined(_CRAY) +static inline uint32_t +swap_uint32_t (uint32_t t) +{ +#define ROL(x,n) ((x)<<(n))|((x)>>(32-(n))) + uint32_t temp1, temp2; + + temp1 = cshift(t, 16); + temp2 = temp1 >> 8; + temp1 &= 0x00ff00ff; + temp2 &= 0x00ff00ff; + temp1 <<= 8; + return temp1 | temp2; +} +#endif + +struct x32{ + unsigned int a:32; + unsigned int b:32; +}; + +void +sha2Update (SHA256_CTX *m, const void *v, size_t len) +{ + const unsigned char *p = v; + size_t old_sz = m->sz[0]; + size_t offset; + + m->sz[0] += len * 8; + if (m->sz[0] < old_sz) + ++m->sz[1]; + offset = (old_sz / 8) % 64; + while(len > 0){ + size_t l = min(len, 64 - offset); + memcpy(m->save + offset, p, l); + offset += l; + p += l; + len -= l; + if(offset == 64){ +#if !defined(WORDS_BIGENDIAN) || defined(_CRAY) + int i; + uint32_t current[16]; + struct x32 *u = (struct x32*)m->save; + for(i = 0; i < 8; i++){ + current[2*i+0] = swap_uint32_t(u[i].a); + current[2*i+1] = swap_uint32_t(u[i].b); + } + calc(m, current); +#else + calc(m, (uint32_t*)m->save); +#endif + offset = 0; + } + } +} + +void +sha2Final (void *res, SHA256_CTX *m) +{ + unsigned char zeros[72]; + unsigned offset = (m->sz[0] / 8) % 64; + unsigned int dstart = (120 - offset - 1) % 64 + 1; + + *zeros = 0x80; + memset (zeros + 1, 0, sizeof(zeros) - 1); + zeros[dstart+7] = (m->sz[0] >> 0) & 0xff; + zeros[dstart+6] = (m->sz[0] >> 8) & 0xff; + zeros[dstart+5] = (m->sz[0] >> 16) & 0xff; + zeros[dstart+4] = (m->sz[0] >> 24) & 0xff; + zeros[dstart+3] = (m->sz[1] >> 0) & 0xff; + zeros[dstart+2] = (m->sz[1] >> 8) & 0xff; + zeros[dstart+1] = (m->sz[1] >> 16) & 0xff; + zeros[dstart+0] = (m->sz[1] >> 24) & 0xff; + sha2Update (m, zeros, dstart + 8); + { + int i; + unsigned char *r = (unsigned char*)res; + + for (i = 0; i < 8; ++i) { + r[4*i+3] = m->counter[i] & 0xFF; + r[4*i+2] = (m->counter[i] >> 8) & 0xFF; + r[4*i+1] = (m->counter[i] >> 16) & 0xFF; + r[4*i] = (m->counter[i] >> 24) & 0xFF; + } + } +} +#endif /* FORTUNA */ diff --git a/src/lib/crypto/builtin/sha2/t_sha256.c b/src/lib/crypto/builtin/sha2/t_sha256.c new file mode 100644 index 000000000..bcad91093 --- /dev/null +++ b/src/lib/crypto/builtin/sha2/t_sha256.c @@ -0,0 +1,126 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/builtin/t_sha256.c */ +/* + * Copyright (c) 1995 - 2002 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 +#include "sha2.h" + +#ifndef FORTUNA +int +main (void) +{ + return 0; +} + +#else + +#define ONE_MILLION_A "one million a's" + +struct test { + char *str; + unsigned char hash[64]; +}; + +struct test tests[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }}, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }}, + { ONE_MILLION_A, + {0xcd,0xc7,0x6e,0x5c, 0x99,0x14,0xfb,0x92, + 0x81,0xa1,0xc7,0xe2, 0x84,0xd7,0x3e,0x67, + 0xf1,0x80,0x9a,0x48, 0xa4,0x97,0x20,0x0e, + 0x04,0x6d,0x39,0xcc, 0xc7,0x11,0x2c,0xd0 }}, + { NULL } +}; + +int +main (void) +{ + struct test *t; + void *ctx = malloc(sizeof(SHA256_CTX)); + unsigned char *res = malloc(SHA256_DIGEST_LENGTH); + char buf[1000]; + + for (t = tests; t->str; ++t) { + + sha2Init(ctx); + if(strcmp(t->str, ONE_MILLION_A) == 0) { + int i; + memset(buf, 'a', sizeof(buf)); + for(i = 0; i < 1000; i++) { + sha2Update(ctx, buf, sizeof(buf)); + } + } else { + sha2Update(ctx, (unsigned char *)t->str, strlen(t->str)); + } + + sha2Final(res, ctx); + if (memcmp (res, t->hash, SHA256_DIGEST_LENGTH) != 0) { + int i; + + printf ("%s(\"%s\") failed\n", "SHA- 256", t->str); + printf("should be: "); + for(i = 0; i < SHA256_DIGEST_LENGTH; ++i) { + if(i > 0 && (i % 16) == 0) + printf("\n "); + printf("%02x ", t->hash[i]); + } + printf("\nresult was: "); + for(i = 0; i < SHA256_DIGEST_LENGTH; ++i) { + if(i > 0 && (i % 16) == 0) + printf("\n "); + printf("%02x ", res[i]); + } + printf("\n"); + return 1; + } + + if (memcmp (res, t->hash, SHA256_DIGEST_LENGTH) != 0) { + printf("EVP %s failed here old function where successful!\n", "SHA-256"); + return 1; + } + } + free(ctx); + free(res); + printf ("success\n"); + return 0; +} +#endif /* FORTUNA */ diff --git a/src/lib/crypto/crypto_tests/Makefile.in b/src/lib/crypto/crypto_tests/Makefile.in index 784d30701..62a80b2a2 100644 --- a/src/lib/crypto/crypto_tests/Makefile.in +++ b/src/lib/crypto/crypto_tests/Makefile.in @@ -3,7 +3,8 @@ BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../krb -I$(srcdir)/../@CRYPTO_IMPL@/enc_provider \ -I$(srcdir)/../@CRYPTO_IMPL@/hash_provider -I$(srcdir)/../krb/keyhash_provider \ -I$(srcdir)/../krb/dk -I$(srcdir)/../@CRYPTO_IMPL@/ \ - -I$(srcdir)/../krb/yarrow \ + -I$(srcdir)/../krb/prng \ + -I$(srcdir)/../krb/prng/@PRNG_ALG@ \ -I$(srcdir)/../krb/crc32 -I$(srcdir)/../krb/old -I$(srcdir)/../krb/raw \ -I$(srcdir)/../@CRYPTO_IMPL@/aes -I$(srcdir)/../@CRYPTO_IMPL@/des \ -I$(srcdir)/../@CRYPTO_IMPL@/arcfour -I$(srcdir)/../@CRYPTO_IMPL@/sha1 \ @@ -56,9 +57,13 @@ check-unix:: t_nfold t_encrypt t_prf t_prng t_cmac t_hmac \ t_crc t_cts t_short t_str2key t_camellia_ccm $(RUN_SETUP) $(VALGRIND) ./t_nfold $(RUN_SETUP) $(VALGRIND) ./t_encrypt +ifeq ("@PRNG_ALG@","fortuna") + $(RUN_SETUP) $(VALGRIND) ./t_prng <$(srcdir)/t_prng.seed >t_prng.output +else if [ @CRYPTO_IMPL@ != nss ]; then \ - $(RUN_SETUP) $(VALGRIND) ./t_prng <$(srcdir)/t_prng.seed >t_prng.output && \ - diff t_prng.output $(srcdir)/t_prng.expected; fi + $(RUN_SETUP) $(VALGRIND) ./t_prng <$(srcdir)/t_prng.seed >t_prng.output && diff t_prng.output $(srcdir)/t_prng.expected; \ + fi +endif $(RUN_SETUP) $(VALGRIND) ./t_cmac $(RUN_SETUP) $(VALGRIND) ./t_hmac $(RUN_SETUP) $(VALGRIND) ./t_prf <$(srcdir)/t_prf.in >t_prf.output diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in index 35dbc877f..c4bdd70d9 100644 --- a/src/lib/crypto/krb/Makefile.in +++ b/src/lib/crypto/krb/Makefile.in @@ -1,11 +1,13 @@ mydir=lib/crypto/krb BUILDTOP=$(REL)..$(S)..$(S).. SUBDIRS= arcfour checksum crc32 dk \ - prf rand2key old raw yarrow + prf rand2key old raw prng LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/../@CRYPTO_IMPL@/enc_provider -I$(srcdir)/dk \ -I$(srcdir)/../@CRYPTO_IMPL@/hash_provider \ -I$(srcdir)/prf -I$(srcdir)/rand2key \ - -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/yarrow \ + -I$(srcdir)/old -I$(srcdir)/raw \ + -I$(srcdir)/prng \ + -I$(srcdir)/prng/@PRNG_ALG@ \ -I$(srcdir)/../@CRYPTO_IMPL@/ -I$(srcdir)/../@CRYPTO_IMPL@/des \ -I$(srcdir)/../@CRYPTO_IMPL@/aes -I$(srcdir)/arcfour \ -I$(srcdir)/../@CRYPTO_IMPL@/camellia \ @@ -55,7 +57,6 @@ STLIBOBJS=\ nfold.o \ old_api_glue.o \ prf.o \ - prng.o \ random_to_key.o \ state.o \ string_to_cksumtype.o \ @@ -95,7 +96,6 @@ OBJS=\ $(OUTPRE)nfold.$(OBJEXT) \ $(OUTPRE)old_api_glue.$(OBJEXT) \ $(OUTPRE)prf.$(OBJEXT) \ - $(OUTPRE)prng.$(OBJEXT) \ $(OUTPRE)random_to_key.$(OBJEXT) \ $(OUTPRE)state.$(OBJEXT) \ $(OUTPRE)string_to_cksumtype.$(OBJEXT) \ @@ -134,7 +134,6 @@ SRCS=\ $(srcdir)/old_api_glue.c \ $(srcdir)/prf.c \ $(srcdir)/cf2.c \ - $(srcdir)/prng.c \ $(srcdir)/random_to_key.c \ $(srcdir)/state.c \ $(srcdir)/string_to_cksumtype.c \ @@ -145,11 +144,11 @@ SRCS=\ STOBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST \ dk/OBJS.ST prf/OBJS.ST rand2key/OBJS.ST \ - old/OBJS.ST raw/OBJS.ST yarrow/OBJS.ST OBJS.ST + old/OBJS.ST raw/OBJS.ST prng/@PRNG_ALG@/OBJS.ST prng/OBJS.ST OBJS.ST SUBDIROBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST \ dk/OBJS.ST prf/OBJS.ST rand2key/OBJS.ST \ - old/OBJS.ST raw/OBJS.ST yarrow/OBJS.ST + old/OBJS.ST raw/OBJS.ST prng/@PRNG_ALG@/OBJS.ST prng/OBJS.ST ##DOS##LIBOBJS = $(OBJS) @@ -185,8 +184,8 @@ all-windows:: cd ..\raw @echo Making in crypto\raw $(MAKE) -$(MFLAGS) - cd ..\yarrow - @echo Making in crypto\yarrow + cd ..\prng + @echo Making in crypto\prng $(MAKE) -$(MFLAGS) cd .. @@ -215,8 +214,8 @@ clean-windows:: cd ..\raw @echo Making clean in crypto\raw $(MAKE) -$(MFLAGS) clean - cd ..\yarrow - @echo Making clean in crypto\yarrow + cd ..\prng + @echo Making clean in crypto\prng $(MAKE) -$(MFLAGS) clean cd .. @@ -245,8 +244,8 @@ check-windows:: cd ..\raw @echo Making check in crypto\raw $(MAKE) -$(MFLAGS) check - cd ..\yarrow - @echo Making check in crypto\yarrow + cd ..\prng + @echo Making check in crypto\prng $(MAKE) -$(MFLAGS) check cd .. diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c deleted file mode 100644 index a25cfcfcb..000000000 --- a/src/lib/crypto/krb/prng.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * Copyright (C) 2001, 2002, 2004, 2007, 2008 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 "k5-int.h" -#include "enc_provider.h" -#include -#include "k5-thread.h" - -#define yarrow_lock krb5int_yarrow_lock -k5_mutex_t yarrow_lock = K5_MUTEX_PARTIAL_INITIALIZER; - -#ifdef CRYPTO_IMPL_NSS - -/* - * Using Yarrow with NSS is a bit problematic because the MD5 contexts it holds - * open for the entropy pools would be invalidated by a fork(), causing us to - * lose the entropy contained therein. - * - * Therefore, use the NSS PRNG if NSS is the crypto implementation. Doing this - * via ifdefs here is temporary until we come up with better build logic for - * it. - */ - -#include "../nss/nss_gen.h" -#include - -/* - * 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 OS_ENTROPY_LEN 20 - -int krb5int_prng_init(void) -{ - return 0; -} - -krb5_error_code KRB5_CALLCONV -krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, - const krb5_data *data) -{ - krb5_error_code ret; - - ret = k5_nss_init(); - if (ret) - return ret; - if (PK11_RandomUpdate(data->data, data->length) != SECSuccess) - return k5_nss_map_last_error(); - return 0; -} - -krb5_error_code KRB5_CALLCONV -krb5_c_random_make_octets(krb5_context context, krb5_data *data) -{ - krb5_error_code ret; - - ret = k5_nss_init(); - if (ret) - return ret; - if (PK11_GenerateRandom((unsigned char *)data->data, - data->length) != SECSuccess) - return k5_nss_map_last_error(); - return 0; -} - -void -krb5int_prng_cleanup (void) -{ -} - -#else /* CRYPTO_IMPL_NSS */ - -#include "yarrow.h" -static Yarrow_CTX y_ctx; - -/* Gather enough OS entropy per call to trigger a Yarrow reseed. */ -#define OS_ENTROPY_LEN (YARROW_SLOW_THRESH/8) - -/* Helper function to estimate entropy based on sample length - * and where it comes from. - */ - -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; -} - -int krb5int_prng_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; -} - -krb5_error_code KRB5_CALLCONV -krb5_c_random_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; -} - -krb5_error_code KRB5_CALLCONV -krb5_c_random_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; -} - -void -krb5int_prng_cleanup (void) -{ - krb5int_yarrow_final (&y_ctx); - k5_mutex_destroy(&yarrow_lock); -} - -#endif /* not CRYPTO_IMPL_NSS */ - -krb5_error_code KRB5_CALLCONV -krb5_c_random_seed(krb5_context context, krb5_data *data) -{ - return krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OLDAPI, data); -} - -/* - * Routines to get entropy from the OS. For UNIX we try /dev/urandom - * and /dev/random. Currently we don't do anything for Windows. - */ -#if defined(_WIN32) - -krb5_error_code KRB5_CALLCONV -krb5_c_random_os_entropy(krb5_context context, int strong, int *success) -{ - if (success) - *success = 0; - return 0; -} - -#else /*Windows*/ -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif - -/* - * Helper function to read entropy from a random device. Takes the - * name of a device, opens it, makes sure it is a device and if so, - * reads entropy. Returns a boolean indicating whether entropy was - * read. - */ - -static int -read_entropy_from_device(krb5_context context, const char *device) -{ - krb5_data data; - struct stat sb; - int fd; - unsigned char buf[OS_ENTROPY_LEN], *bp; - int 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); - data.length = sizeof (buf); - data.data = (char *) buf; - return (krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND, - &data) == 0); -} - -krb5_error_code KRB5_CALLCONV -krb5_c_random_os_entropy(krb5_context context, int strong, int *success) -{ - int unused; - int *oursuccess = success ? success : &unused; - - *oursuccess = 0; - /* If we are getting strong data then try that first. We are - guaranteed to cause a reseed of some kind if strong is true and - we have both /dev/random and /dev/urandom. We want the strong - data included in the reseed so we get it first.*/ - if (strong) { - if (read_entropy_from_device(context, "/dev/random")) - *oursuccess = 1; - } - if (read_entropy_from_device(context, "/dev/urandom")) - *oursuccess = 1; - return 0; -} - -#endif /*Windows or pre-OSX Mac*/ diff --git a/src/lib/crypto/krb/prng/prng.c b/src/lib/crypto/krb/prng/prng.c new file mode 100644 index 000000000..e064599bc --- /dev/null +++ b/src/lib/crypto/krb/prng/prng.c @@ -0,0 +1,180 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * 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" + +#ifdef FORTUNA +#include "fortuna.h" +const struct krb5_prng_provider *prng = &krb5int_prng_fortuna; +#elif defined(CRYPTO_IMPL_NSS) +#include "prng_nss.h" +const struct krb5_prng_provider *prng = &krb5int_prng_nss; +#else +#include "yarrow.h" +const struct krb5_prng_provider *prng = &krb5int_prng_yarrow; +#endif + +/* + * krb5int_prng_init - Returns 0 on success + */ +int krb5int_prng_init(void) +{ + int err = 0; + err = prng->init(); + return err; +} + +/* + * krb5_c_random_add_entropy - Returns 0 on success + */ +krb5_error_code KRB5_CALLCONV +krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, + const krb5_data *data) +{ + krb5_error_code err = 0; + err = prng->add_entropy(context, randsource, data); + return err; +} + +/* + * krb5_c_random_seed - Returns 0 on success + */ +krb5_error_code KRB5_CALLCONV +krb5_c_random_seed(krb5_context context, krb5_data *data) +{ + return krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OLDAPI, data); +} + +/* + * krb5_c_random_make_octets - Returns 0 on success + */ +krb5_error_code KRB5_CALLCONV +krb5_c_random_make_octets(krb5_context context, krb5_data *data) +{ + krb5_error_code err = 0; + err = prng->make_octets(context, data); + return err; +} + +void +krb5int_prng_cleanup (void) +{ + prng->cleanup(); + return; +} + + +/* + * Routines to get entropy from the OS. For UNIX we try /dev/urandom + * and /dev/random. Currently we don't do anything for Windows. + */ +#if defined(_WIN32) + +krb5_error_code KRB5_CALLCONV +krb5_c_random_os_entropy(krb5_context context, int strong, int *success) +{ + if (success) + *success = 0; + return 0; +} + +#else /*Windows*/ +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif + +/* + * Helper function to read entropy from a random device. Takes the + * name of a device, opens it, makes sure it is a device and if so, + * reads entropy. Returns a boolean indicating whether entropy was + * read. + */ + +/* + * read_entropy_from_device - Returns 0 on success + */ +static int +read_entropy_from_device(krb5_context context, const char *device) +{ + krb5_data data; + struct stat sb; + int fd; + unsigned char buf[ENTROPY_BUFSIZE], *bp; + int 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); + data.length = sizeof (buf); + data.data = (char *) buf; + return (krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND, + &data) == 0); +} + +/* + * krb5_c_random_os_entropy - Returns 0 on success + */ +krb5_error_code KRB5_CALLCONV +krb5_c_random_os_entropy(krb5_context context, int strong, int *success) +{ + int unused; + int *oursuccess = success ? success : &unused; + + *oursuccess = 0; + /* If we are getting strong data then try that first. We are + guaranteed to cause a reseed of some kind if strong is true and + we have both /dev/random and /dev/urandom. We want the strong + data included in the reseed so we get it first.*/ + if (strong) { + if (read_entropy_from_device(context, "/dev/random")) + *oursuccess = 1; + } + if (read_entropy_from_device(context, "/dev/urandom")) + *oursuccess = 1; + return 0; +} + +#endif /*Windows or pre-OSX Mac*/ + diff --git a/src/lib/crypto/krb/prng/yarrow/ASSUMPTIONS b/src/lib/crypto/krb/prng/yarrow/ASSUMPTIONS new file mode 100644 index 000000000..3e3c99c49 --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/ASSUMPTIONS @@ -0,0 +1,101 @@ +Assumptions +=========== + +The Yarrow design, described in "Yarrow-160: Notes on the Design and +Analysis of the Yarrow Cryptographic Pseudonumber Generator" by John +Kelsey, Bruce Schneier and Niels Ferguson of Counterpane Systems +(available from http://www.counterpane.com/yarrow.html), left out some +implementation details and has some ambiguities in the protocol. ZKS +has to made some assumptions and taken some decisions in its +implementation of Yarrow. In the text, `we' represents ZKS. + +Here is the list of those assumptions: + +1) To simplify the code and speed up running time, we limit the number +of different sources to 20. This should be enough for most +applications. This can be changed by redefining YARROW_MAX_SOURCE in +yarrow.h. + +2) The Yarrow paper (in section 5.3) state that Pt is either +implementation dependent or dynamically adjusted. We chose to fix the +slow pool's Pt to 100 and the fast pool's Pt to 10. This can be +changed by redefining YARROW_FAST_PT and YARROW_SLOW_PT in yarrow.c. + +3) Initialization when there is no saved state is not discussed in the +Yarrow paper. We have defined that CPRNG is becomes seeded after a +slow reseed. During initialization, a slow reseed is triggered by +YARROW_K_OF_N_INIT_THRESH sources reaching the slow threshold +YARROW_SLOW_INIT_THRESH. During initialization, fast reseeds are +triggered when a source reaches the fast threshold +YARROW_FAST_INIT_THRESH. After reseed the behavior of the pools is +controlled by YARROW_K_OF_N_THRESH, YARROW_SLOW_THRESH and +YARROW_FAST_THRESH. + +Our default values for YARROW_K_OF_N_INIT_THRESH, +YARROW_SLOW_INIT_THRESH and YARROW_FAST_INIT_THRESH are the same as +YARROW_K_OF_N_THRESH, YARROW_SLOW_THRESH and YARROW_FAST_THRESH +respectively. Note this means that a Yarrow_Poll call by itself can +never put us in an initialized state, as it only works on one pool, +and the default YARROW_K_OF_N_INIT_THRESH value is 2. + +4) We define a function Yarrow_Poll which can gather entropy. The +user must allocate a source_id, and call Yarrow_Poll manually. +Yarrow_Poll just adds samples from the machines state to the source +given as an argument. + +5) Prior to initialization, Yarrow_Output will fail. + +6) The actions to take on state load are not described in the yarrow +paper, all it says is that 2k bytes should be written (and by +implication read back in somehow). We read in the 2k bytes, hash +them into the fast pool, and then do a forced fast reseed, and an +immediate state save. + +7) In step 2 of the reseed process, we must hash the value i. The +representation of this integer will affect the hash value. In our +code, i is a 64-bit unsigned value. We update the hash context using +the 64 bit big endian representation of i. + +8) Yarrow outputs random bits in blocks. If the calling function +requests less bits than available, then the unused bits are kept +in memory until the next call. In case of a reseed, we chose to +discard those leftover bits. + +9) The samples from one source must alternate between the two pools. +As a default, we initialize the first pool to send the sample too to +be the fast pool. This initialization is done only when a source is +added, not when we reseed from one. + +10) The Yarrow paper states that the maximum number of outputs between +reseeding is limited to min(2^n,2^(k/3)*Pg), but does not explain +what is to happen when this limit is reached. It could be the case +that we reach the limit but there is not enough entropy in the pools +to reseed. In our code, the Yarrow_Output_Block will do a forced +fast reseed. + +11) In the Yarrow paper, the limit on the number of outputs between +reseeding is expressed in number of outputs: + +#oututs <= min(2^n, 2^(k/3).Pg) + +but we redefine it in terms of gates by dividing the numbers by Pg, +the number of outputs per gate, and counting the number of gates +instead. This makes an overflow a little less likely. + +We don't use a bignum library, so in event of overflow, the limit in +number of gates before reseed (y->gates_limit) is reduced down to +2^64-1 (or 2^32-1 if 64 bit ints aren't available on the platform). + +12) The Yarrow paper describes that the cipher block C should be +incremented as part of the output function. We treat the bytes +of C as a big endian number to do the increment. + +13) Triple-DES key size. The yarrow paper uses the letter k to +represent the keysize in bits. Due to the parity bits, the size of k +is 192 bits. However the effective key size is actually 168 bits, as +the value of k is used in security limits, k must be 168 bits. The +paper uses k (eg set K to the next k output bits), so we have to do +the parity padding function, to copy bits 0-6 to 0-7, 7-13 to 8-15 +etc. The macro DES_Init performs the function of doing a DES key +schedule from a packed key (no parity bits), internally doing the +parity padding. Other ciphers are simpler as there is no parity. diff --git a/src/lib/crypto/krb/prng/yarrow/LICENSE b/src/lib/crypto/krb/prng/yarrow/LICENSE new file mode 100644 index 000000000..c85475d7e --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/LICENSE @@ -0,0 +1,21 @@ +Copyright 2000 by Zero-Knowledge Systems, Inc. + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +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 Zero-Knowledge Systems, +Inc. not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. Zero-Knowledge Systems, Inc. makes no representations +about the suitability of this software for any purpose. It is +provided "as is" without express or implied warranty. + +ZERO-KNOWLEDGE SYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL ZERO-KNOWLEDGE SYSTEMS, INC. BE LIABLE FOR +ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/src/lib/crypto/krb/prng/yarrow/Makefile.in b/src/lib/crypto/krb/prng/yarrow/Makefile.in new file mode 100644 index 000000000..40dd85aa0 --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/Makefile.in @@ -0,0 +1,42 @@ +mydir=lib/crypto/krb/prng/yarrow +BUILDTOP=$(REL)..$(S)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../.. \ + -I$(srcdir)/../../../@CRYPTO_IMPL@ \ + -I$(srcdir)/../../../@CRYPTO_IMPL@/sha1 \ + -I$(srcdir)/../../../@CRYPTO_IMPL@/enc_provider +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=yarrow +##DOS##OBJFILE=..\$(OUTPRE)yarrow.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= \ + prng_yarrow.o \ + yarrow.o \ + ycipher.o +OBJS= \ + $(OUTPRE)prng_yarrow.$(OBJEXT) \ + $(OUTPRE)yarrow.$(OBJEXT) \ + $(OUTPRE)ycipher.$(OBJEXT) + +SRCS=\ + $(srcdir)/prng_yarrow.c \ + $(srcdir)/yarrow.c \ + $(srcdir)/ycipher.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs + +@lib_frag@ +@libobj_frag@ + diff --git a/src/lib/crypto/krb/prng/yarrow/README b/src/lib/crypto/krb/prng/yarrow/README new file mode 100644 index 000000000..3dd4b801a --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/README @@ -0,0 +1,94 @@ +Yarrow - Secure Pseudo-Random Number Generator +============================================== + +This is an implementation of the cryptographic pseudo-random number +generator Yarrow. You are encouraged to use, modify, and incorporate +this code. Please see the accompanying LICENSE file for more details. + + +Yarrow can be used with OpenSSL 0.9.5a (http://www.openssl.org) and +other cryptographic libraries. + +The Yarrow design is described in "Yarrow-160: Notes on the Design and +Analysis of the Yarrow Cryptographic Pseudorandom Number Generator" by +John Kelsey, Bruce Schneier and Niels Ferguson of Counterpane Systems, +available from http://www.counterpane.com/yarrow.html + +The Yarrow function calls are described in the yarrow(3) manpage. + +Installation +============ + +By default, Yarrow is built with OpenSSL. If the OpenSSL headers are +not installed in the standard directory /usr/local/ssl/include, +set the path in the Makefile. + +If it is possible that an application using Yarrow will fork(), Yarrow +must be compiled with -DYARROW_DETECT_FORK (then the child process +will have to seed Yarrow again), or the Yarrow_CTX must be allocated +in shared memory. + +If compiled with -DYARROW_SAVE_STATE, Yarrow will use a seed file +specified in the Yarrow_Init call. + +When the settings in the Makefile are correct, run "make". + + +Yarrow with OpenSSL: +------------------- + +The macros YARROW_CIPHER_3DES (default), YARROW_CIPHER_BLOWFISH and +YARROW_CIPHER_IDEA for ciphers and YARROW_HASH_SHA1 (default) and +YARROW_HASH_MD5 for hash functions are available to select algorithms +from OpenSSL. + +CRYPTO_set_locking_callback() is required in multithreaded applications. + + +Yarrow with other cryptographic libraries: +----------------------------------------- + +The Yarrow implementation uses a symmetric cipher, a cryptographic +hash function and a mutex. By default, Yarrow calls OpenSSL. For use +with other cryptographic libraries, the following types and macros +should be defined: + +Symmetric cipher - ycipher.h: + + typedef struct { ... } CIPHER_CTX; + + #define CIPHER_BLOCK_SIZE ... + #define CIPHER_KEY_SIZE ... + + void CIPHER_Init(CIPHER_CTX *ctx, void *key); + void CIPHER_Encrypt_Block(CIPHER_CTX *ctx, void *in, void *out); + +Hash function - yhash.h: + + typedef struct { ... } HASH_CTX; + + #define HASH_DIGEST_SIZE ... + #define HASH_STATE_SIZE ... + + void HASH_Init(HASH_CTX *ctx); + void HASH_Update(HASH_CTX *ctx, const void *data, unsigned long size); + void HASH_Final(HASH_CTX *ctx, unsigned char *md); + +Mutex - ylock.h: + + int LOCK(void); + int UNLOCK(void); + +Learn More: +---------- + +It is Zero-Knowledge's hope that third party developers of yarrow will +collaborate to derive test vectors for yarrow. In an effort to further +this discussion, we have created a mailing list for developers and +interested parties. To subscribe, send an email to +"yarrow-request@zeroknowledge.com" with "subscribe" in the body of the +message. + +For more information, or if you have questions or comments regarding open +source at Zero-Knowledge Systems, please visit +http://opensource.zeroknowledge.com diff --git a/src/lib/crypto/krb/prng/yarrow/TODO b/src/lib/crypto/krb/prng/yarrow/TODO new file mode 100644 index 000000000..bd133ecfd --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/TODO @@ -0,0 +1,9 @@ +open issues: + +* when should the initial seed be considered complete? +* poll system ressources for randomness on startup? +* how frequently should the PRNG state be saved? +* how to react to fork()? +* what should the seed file contain, how should it be processed? +* test fork() hack +* test openSSL locks in multi-threaded environment diff --git a/src/lib/crypto/krb/prng/yarrow/deps b/src/lib/crypto/krb/prng/yarrow/deps new file mode 100644 index 000000000..1a8caea42 --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/deps @@ -0,0 +1,41 @@ +# +# Generated makefile dependencies follow. +# +yarrow.so yarrow.po $(OUTPRE)yarrow.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(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 \ + yarrow.c yarrow.h ycipher.h yexcep.h ylock.h ystate.h \ + ytypes.h +ycipher.so ycipher.po $(OUTPRE)ycipher.$(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 yarrow.h ycipher.c \ + ycipher.h ytypes.h +prng_yarrow.so prng_yarrow.po $(OUTPRE)prng_yarrow.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(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_yarrow.c yarrow.h ycipher.h yexcep.h ylock.h ystate.h diff --git a/src/lib/crypto/krb/prng/yarrow/yarrow.c b/src/lib/crypto/krb/prng/yarrow/yarrow.c new file mode 100644 index 000000000..2eacd936b --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/yarrow.c @@ -0,0 +1,959 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +/* + * Yarrow - Cryptographic Pseudo-Random Number Generator + * Copyright (c) 2000 Zero-Knowledge Systems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * 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 Zero-Knowledge Systems, + * Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Zero-Knowledge Systems, Inc. makes no representations + * about the suitability of this software for any purpose. It is + * provided "as is" without express or implied warranty. + * + * See the accompanying LICENSE file for more information. + */ + +#include "k5-int.h" + +#include +#include +#ifdef _WIN32 +#include "port-sockets.h" +#else +# include +# include +#endif +#if !defined(YARROW_NO_MATHLIB) +#include +#endif + +#define YARROW_IMPL +#include "yarrow.h" +#include "ycipher.h" +#include "ylock.h" +#include "ystate.h" +#include "yexcep.h" + +#if defined( YARROW_DEBUG ) || defined( YARROW_TRACE ) +# include +#endif + +#undef TRACE +#if defined( YARROW_TRACE ) +extern int yarrow_verbose; +#define TRACE( x ) do { if (yarrow_verbose) { x } } while (0) +#else +#define TRACE( x ) +#endif + +#if defined(macintosh) +# define make_big_endian32(x) (x) +#else +# define make_big_endian32(x) htonl(x) +#endif + +#if defined( YARROW_DEBUG ) +static void hex_print(FILE* f, const char* var, void* data, size_t size); +#endif + +static void block_increment( void* block, const int sz ); +#if defined( YARROW_SAVE_STATE ) +static int Yarrow_Load_State( Yarrow_CTX *y ); +static int Yarrow_Save_State( Yarrow_CTX *y ); +#endif + +static int yarrow_gate_locked(Yarrow_CTX* y); + +static const byte zero_block[CIPHER_BLOCK_SIZE] = { 0, }; + +static const char* const yarrow_str_error[] = { + "ok", + "failed", + "failed: uninitialized", + "failed: already initialized", + "failed: no driver", + "failed: can't open driver", + "failed: invalid source id", + "failed: no more source ids available", + "failed: invalid argument", + "failed: insufficient privileges", + "failed: out of memory", + "failed: resource exhausted", + "failed: not enough entropy to generate output", + "failed: locking error", + "failed: no state to load", + "failed: state load or save failed", + "failed: not implemented" +}; + +/* calculate limits after initialization */ + +static void krb5int_yarrow_init_Limits(Yarrow_CTX* y) +{ + double tmp1, tmp2, limit; + /* max number of gates between reseeds -> exceed this, do forced reseed */ + + /* #oututs <= min(2^n, 2^(k/3).Pg) */ + + /* => #gates <= min(2^n/Pg, 2^(k/3)) */ + + tmp1 = POW_CIPHER_BLOCK_SIZE / y->Pg; + tmp2 = POW_CIPHER_KEY_SIZE; + limit = min(tmp1, tmp2); + if (limit < COUNTER_MAX) + { + y->gates_limit = limit; + } + else + { + y->gates_limit = COUNTER_MAX; + } +} + +static int yarrow_reseed_locked( Yarrow_CTX* y, int pool ); + +/* if the program was forked, the child must not operate on the same + PRNG state */ +#ifdef YARROW_DETECT_FORK + +static int +yarrow_input_locked( Yarrow_CTX* y, unsigned source_id, + const void *sample, + size_t size, size_t entropy_bits ); + +static int Yarrow_detect_fork(Yarrow_CTX *y) +{ + pid_t newpid; + EXCEP_DECL; + + /* this does not work for multi-threaded apps if threads have different + * pids */ + newpid = getpid(); + if ( y->pid != newpid ) + { + /* we input the pid twice, so it will get into the fast pool at least once + * Then we reseed. This doesn't really increase entropy, but does make the + * streams distinct assuming we already have good entropy*/ + y->pid = newpid; + TRY (yarrow_input_locked (y, 0, &newpid, + sizeof (newpid), 0)); + TRY (yarrow_input_locked (y, 0, &newpid, + sizeof (newpid), 0)); + TRY (yarrow_reseed_locked (y, YARROW_FAST_POOL)); + } + +CATCH: + EXCEP_RET; +} + +#else + +#define Yarrow_detect_fork(x) (YARROW_OK) + +#endif + +static void Yarrow_Make_Seeded( Yarrow_CTX* y ) +{ + TRACE( printf( "SEEDED," ); ); + y->seeded = 1; + + /* now we are seeded switch to _THRESH values */ + + y->slow_thresh = YARROW_SLOW_THRESH; + y->fast_thresh = YARROW_FAST_THRESH; + y->slow_k_of_n_thresh = YARROW_K_OF_N_THRESH; +} + +YARROW_DLL +int krb5int_yarrow_init(Yarrow_CTX* y, const char *filename) +{ + EXCEP_DECL; + int locked = 0; + + if (!y) { THROW( YARROW_BAD_ARG ); } + TRY( LOCK() ); + locked = 1; + + y->seeded = 0; + y->saved = 0; + +#if defined( YARROW_DETECT_FORK ) + y->pid = getpid(); +#endif + + y->entropyfile = filename; + y->num_sources = 0; + mem_zero(y->C, sizeof(y->C)); + HASH_Init(&y->pool[YARROW_FAST_POOL]); + HASH_Init(&y->pool[YARROW_SLOW_POOL]); + + mem_zero(y->K, sizeof(y->K)); + + mem_zero(&y->cipher, sizeof(y->cipher)); + + TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); + y->out_left = 0; + y->out_count = 0; + y->gate_count = 0; + y->Pg = YARROW_OUTPUTS_PER_GATE; + y->Pt[YARROW_FAST_POOL] = YARROW_FAST_PT; + y->Pt[YARROW_SLOW_POOL] = YARROW_SLOW_PT; + y->slow_k_of_n = 0; + + /* start with INIT_THRESH values, after seeded, switch to THRESH values */ + + y->slow_thresh = YARROW_SLOW_INIT_THRESH; + y->fast_thresh = YARROW_FAST_INIT_THRESH; + y->slow_k_of_n_thresh = YARROW_K_OF_N_INIT_THRESH; + + krb5int_yarrow_init_Limits(y); + +#if defined( YARROW_SAVE_STATE ) + if ( y->entropyfile != NULL ) + { + int ret = Yarrow_Load_State( y ); + if ( ret != YARROW_OK && ret != YARROW_NO_STATE ) + { + THROW( ret ); + } + + /* if load suceeded then write new state back immediately + */ + + /* Also check that it's not already saved, because the reseed in + * Yarrow_Load_State may trigger a save + */ + + if ( ret == YARROW_OK && !y->saved ) + { + TRY( Yarrow_Save_State( y ) ); + } + } +#endif + + if ( !y->seeded ) + { + THROW( YARROW_NOT_SEEDED ); + } + +CATCH: + if ( locked ) { TRY( UNLOCK() ); } + EXCEP_RET; +} + +static +int yarrow_input_maybe_locking( Yarrow_CTX* y, unsigned source_id, + const void* sample, + size_t size, size_t entropy_bits, + int do_lock ) +{ + EXCEP_DECL; + int ret; + int locked = 0; + Source* source; + size_t new_entropy; + size_t estimate; + + if (do_lock) { + TRY( LOCK() ); + locked = 1; + } + k5_assert_locked(&krb5int_yarrow_lock); + + if (!y) { THROW( YARROW_BAD_ARG ); } + + if (source_id >= y->num_sources) { THROW( YARROW_BAD_SOURCE ); } + + source = &y->source[source_id]; + + if(source->pool != YARROW_FAST_POOL && source->pool != YARROW_SLOW_POOL) + { + THROW( YARROW_BAD_SOURCE ); + } + + /* hash in the sample */ + + HASH_Update(&y->pool[source->pool], (const void*)sample, size); + + /* only update entropy estimate if pool is not full */ + + if ( (source->pool == YARROW_FAST_POOL && + source->entropy[source->pool] < y->fast_thresh) || + (source->pool == YARROW_SLOW_POOL && + source->entropy[source->pool] < y->slow_thresh) ) + { + new_entropy = min(entropy_bits, size * 8 * YARROW_ENTROPY_MULTIPLIER); + if (source->estimator) + { + estimate = source->estimator(sample, size); + new_entropy = min(new_entropy, estimate); + } + source->entropy[source->pool] += new_entropy; + if ( source->entropy[source->pool] > YARROW_POOL_SIZE ) + { + source->entropy[source->pool] = YARROW_POOL_SIZE; + } + + if (source->pool == YARROW_FAST_POOL) + { + if (source->entropy[YARROW_FAST_POOL] >= y->fast_thresh) + { + ret = yarrow_reseed_locked(y, YARROW_FAST_POOL); + if ( ret != YARROW_OK && ret != YARROW_NOT_SEEDED ) + { + THROW( ret ); + } + } + } + else + { + if (!source->reached_slow_thresh && + source->entropy[YARROW_SLOW_POOL] >= y->slow_thresh) + { + source->reached_slow_thresh = 1; + y->slow_k_of_n++; + if (y->slow_k_of_n >= y->slow_k_of_n_thresh) + { + y->slow_k_of_n = 0; + ret = yarrow_reseed_locked(y, YARROW_SLOW_POOL); + if ( ret != YARROW_OK && ret != YARROW_NOT_SEEDED ) + { + THROW( ret ); + } + } + } + } + } + + /* put samples in alternate pools */ + + source->pool = (source->pool + 1) % 2; + +CATCH: + if ( locked ) { TRY( UNLOCK() ); } + EXCEP_RET; +} + +YARROW_DLL +int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, + const void* sample, + size_t size, size_t entropy_bits ) +{ + return yarrow_input_maybe_locking(y, source_id, sample, size, + entropy_bits, 1); +} + +static int +yarrow_input_locked( Yarrow_CTX* y, unsigned source_id, + const void *sample, + size_t size, size_t entropy_bits ) +{ + return yarrow_input_maybe_locking(y, source_id, sample, size, + entropy_bits, 0); +} + +YARROW_DLL +int krb5int_yarrow_new_source(Yarrow_CTX* y, unsigned* source_id) +{ + EXCEP_DECL; + int locked = 0; + Source* source; + + if (!y) { THROW( YARROW_BAD_ARG ); } + + TRY( LOCK() ); + locked = 1; + + if (y->num_sources + 1 > YARROW_MAX_SOURCES) + { + THROW( YARROW_TOO_MANY_SOURCES ); + } + + *source_id = y->num_sources; + + source = &y->source[*source_id]; + + source->pool = YARROW_FAST_POOL; + source->entropy[YARROW_FAST_POOL] = 0; + source->entropy[YARROW_SLOW_POOL] = 0; + source->reached_slow_thresh = 0; + source->estimator = 0; + + y->num_sources++; +CATCH: + if ( locked ) { TRY( UNLOCK() ); } + EXCEP_RET; +} + +int krb5int_yarrow_register_source_estimator(Yarrow_CTX* y, unsigned source_id, + estimator_fn* fptr) +{ + EXCEP_DECL; + Source* source; + + if (!y) { THROW( YARROW_BAD_ARG ); } + if (source_id >= y->num_sources) { THROW( YARROW_BAD_SOURCE ); } + + source = &y->source[source_id]; + + source->estimator = fptr; + +CATCH: + EXCEP_RET; +} + +static int krb5int_yarrow_output_Block( Yarrow_CTX* y, void* out ) +{ + EXCEP_DECL; + + if (!y || !out) { THROW( YARROW_BAD_ARG ); } + + TRACE( printf( "OUT," ); ); + + /* perform a gate function after Pg outputs */ + + y->out_count++; + if (y->out_count >= y->Pg) + { + y->out_count = 0; + TRY( yarrow_gate_locked( y ) ); + + /* require new seed after reaching gates_limit */ + + y->gate_count++; + if ( y->gate_count >= y->gates_limit ) + { + y->gate_count = 0; + + /* not defined whether to do slow or fast reseed */ + + TRACE( printf( "OUTPUT LIMIT REACHED," ); ); + + TRY( yarrow_reseed_locked( y, YARROW_SLOW_POOL ) ); + } + } + + /* C <- (C + 1) mod 2^n */ + + block_increment( y->C, CIPHER_BLOCK_SIZE ); + + /* R <- E_k(C) */ + + TRY ( krb5int_yarrow_cipher_encrypt_block ( &y->cipher, y->C, out )); + +#if defined(YARROW_DEBUG) + printf("===\n"); + hex_print( stdout, "output: C", y->C, CIPHER_BLOCK_SIZE ); + hex_print( stdout, "output: K", y->K, CIPHER_KEY_SIZE ); + hex_print( stdout, "output: O", out, CIPHER_BLOCK_SIZE ); +#endif +CATCH: + EXCEP_RET; +} + +YARROW_DLL +int krb5int_yarrow_status( Yarrow_CTX* y, int *num_sources, unsigned *source_id, + size_t *entropy_bits, size_t *entropy_max ) +{ + EXCEP_DECL; + int num = y->slow_k_of_n_thresh; + int source = -1; + size_t emax = y->slow_thresh; + size_t entropy = 0; + unsigned i; + + if (!y) { THROW( YARROW_BAD_ARG ); } + TRY( Yarrow_detect_fork( y ) ); + + if (num_sources) { *num_sources = num; } + if (source_id) { *source_id = -1; } + if (entropy_bits) { *entropy_bits = 0; } + if (entropy_max) { *entropy_max = emax; } + + if (y->seeded) + { + if (num_sources) { *num_sources = 0; } + if (entropy_bits) { *entropy_bits = emax; } + THROW( YARROW_OK ); + } + + for (i = 0; i < y->num_sources; i++) + { + if (y->source[i].entropy[YARROW_SLOW_POOL] >= y->slow_thresh) + { + num--; + } + else if (y->source[i].entropy[YARROW_SLOW_POOL] > entropy) + { + source = i; + entropy = y->source[i].entropy[YARROW_SLOW_POOL]; + } + } + + if (num_sources) { *num_sources = num; } + if (source_id) { *source_id = source; } + if (entropy_bits) { *entropy_bits = entropy; } + THROW( YARROW_NOT_SEEDED ); + +CATCH: + EXCEP_RET; +} + +static int yarrow_output_locked(Yarrow_CTX*, void*, size_t); + +YARROW_DLL +int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ) +{ + EXCEP_DECL; + TRY( LOCK() ); + TRY( yarrow_output_locked(y, out, size)); +CATCH: + UNLOCK(); + EXCEP_RET; +} + +static +int yarrow_output_locked( Yarrow_CTX* y, void* out, size_t size ) +{ + EXCEP_DECL; + size_t left; + char* outp; + size_t use; + + if (!y || !out) { THROW( YARROW_BAD_ARG ); } + TRY( Yarrow_detect_fork( y ) ); + + if (!y->seeded) { THROW( YARROW_NOT_SEEDED ); } + + left = size; + outp = out; + + if (y->out_left > 0) + { + use = min(left, y->out_left); + mem_copy(outp, y->out + CIPHER_BLOCK_SIZE - y->out_left, use); + left -= use; + y->out_left -= use; + outp += use; + } + + for ( ; + left >= CIPHER_BLOCK_SIZE; + left -= CIPHER_BLOCK_SIZE, outp += CIPHER_BLOCK_SIZE) + { + TRY( krb5int_yarrow_output_Block(y, outp) ); + } + + if (left > 0) + { + TRY( krb5int_yarrow_output_Block(y, y->out) ); + mem_copy(outp, y->out, left); + y->out_left = CIPHER_BLOCK_SIZE - left; + } + +CATCH: + EXCEP_RET; +} + +static int yarrow_gate_locked(Yarrow_CTX* y) +{ + EXCEP_DECL; + byte new_K[CIPHER_KEY_SIZE]; + + if (!y) { THROW( YARROW_BAD_ARG ); } + + TRACE( printf( "GATE[" ); ); + + /* K <- Next k bits of PRNG output */ + + TRY( yarrow_output_locked(y, new_K, CIPHER_KEY_SIZE) ); + mem_copy(y->K, new_K, CIPHER_KEY_SIZE); + + /* need to resetup the key schedule as the key has changed */ + + TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); + +CATCH: + TRACE( printf( "]," ); ); + mem_zero(new_K, sizeof(new_K)); + EXCEP_RET; +} + +int krb5int_yarrow_gate(Yarrow_CTX* y) +{ + EXCEP_DECL; + byte new_K[CIPHER_KEY_SIZE]; + + if (!y) { THROW( YARROW_BAD_ARG ); } + + TRACE( printf( "GATE[" ); ); + + /* K <- Next k bits of PRNG output */ + + TRY( krb5int_yarrow_output(y, new_K, CIPHER_KEY_SIZE) ); + mem_copy(y->K, new_K, CIPHER_KEY_SIZE); + + /* need to resetup the key schedule as the key has changed */ + + TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); + +CATCH: + TRACE( printf( "]," ); ); + mem_zero(new_K, sizeof(new_K)); + EXCEP_RET; +} + +#if defined( YARROW_SAVE_STATE ) +static int Yarrow_Load_State( Yarrow_CTX *y ) +{ + EXCEP_DECL; + Yarrow_STATE state; + + if ( !y ) { THROW( YARROW_BAD_ARG ); } + + if ( y->entropyfile ) + { + TRY( STATE_Load(y->entropyfile, &state) ); + TRACE( printf( "LOAD STATE," ); ); + +#if defined( YARROW_DEBUG ) + hex_print( stderr, "state.load", state.seed, sizeof(state.seed)); +#endif + + /* what to do here is not defined by the Yarrow paper */ + /* this is a place holder until we get some clarification */ + + HASH_Update( &y->pool[YARROW_FAST_POOL], + state.seed, sizeof(state.seed) ); + + Yarrow_Make_Seeded( y ); + + TRY( krb5int_yarrow_reseed(y, YARROW_FAST_POOL) ); + } +CATCH: + mem_zero(state.seed, sizeof(state.seed)); + EXCEP_RET; +} + +static int Yarrow_Save_State( Yarrow_CTX *y ) +{ + EXCEP_DECL; + Yarrow_STATE state; + + if ( !y ) { THROW( YARROW_BAD_ARG ); } + + if ( y->entropyfile && y->seeded ) + { + TRACE( printf( "SAVE STATE[" ); ); + TRY( krb5int_yarrow_output( y, state.seed, sizeof(state.seed) ) ); + TRY( STATE_Save(y->entropyfile, &state) ); + } + y->saved = 1; +# if defined(YARROW_DEBUG) + hex_print(stdout, "state.save", state.seed, sizeof(state.seed)); +# endif + +CATCH: + TRACE( printf( "]," ); ); + mem_zero(state.seed, sizeof(state.seed)); + EXCEP_RET; +} + +#endif + +static int yarrow_reseed_locked(Yarrow_CTX* y, int pool) +{ + EXCEP_DECL; + HASH_CTX* fast_pool; + HASH_CTX* slow_pool; + byte digest[HASH_DIGEST_SIZE]; + HASH_CTX hash; + byte v_0[HASH_DIGEST_SIZE]; + byte v_i[HASH_DIGEST_SIZE]; + krb5_ui_4 big_endian_int32; + COUNTER i; + + k5_assert_locked(&krb5int_yarrow_lock); + if (!y) { THROW( YARROW_BAD_ARG ); } + fast_pool = &y->pool[YARROW_FAST_POOL]; + slow_pool = &y->pool[YARROW_SLOW_POOL]; + if( pool != YARROW_FAST_POOL && pool != YARROW_SLOW_POOL ) + { + THROW( YARROW_BAD_ARG ); + } + + TRACE( printf( "%s RESEED,", + pool == YARROW_SLOW_POOL ? "SLOW" : "FAST" ); ); + + if (pool == YARROW_SLOW_POOL) + { + /* SLOW RESEED */ + + /* feed hash of slow pool into the fast pool */ + + + HASH_Final(slow_pool, digest); + + /* Each pool contains the running hash of all inputs fed into it + * since it was last used to carry out a reseed -- this implies + * that the pool must be reinitialized after a reseed + */ + + HASH_Init(slow_pool); /* reinitialize slow pool */ + HASH_Update(fast_pool, digest, sizeof(digest)); + + if (y->seeded == 0) + { + Yarrow_Make_Seeded( y ); + } + } + + /* step 1. v_0 <- hash of all inputs into fast pool */ + + HASH_Final(fast_pool, &v_0); + HASH_Init(fast_pool); /* reinitialize fast pool */ + + /* v_i <- v_0 */ + + mem_copy( v_i, v_0, sizeof(v_0) ); + + /* step 2. v_i = h(v_{i-1}|v_0|i) for i = 1,..,Pt */ + + /* note: this code has to work for Pt = 0 also */ + + for ( i = 0; i < y->Pt[pool]; i++ ) + { + HASH_Init(&hash); + HASH_Update(&hash, v_i, sizeof(v_i)); + HASH_Update(&hash, v_0, sizeof(v_0)); + big_endian_int32 = make_big_endian32(0); /* MS word */ + HASH_Update(&hash, &big_endian_int32, sizeof(krb5_ui_4)); + big_endian_int32 = make_big_endian32(i & 0xFFFFFFFF); /* LS word */ + HASH_Update(&hash, &big_endian_int32, sizeof(krb5_ui_4)); + HASH_Final(&hash, &v_i); + } + + /* step3. K = h'(h(v_Pt|K)) */ + + /* t = h(v_Pt|K) */ + + HASH_Init(&hash); + HASH_Update(&hash, v_i, sizeof(v_i)); + HASH_Update(&hash, y->K, sizeof(y->K)); + HASH_Final(&hash, v_i); + +#if defined(YARROW_DEBUG) + hex_print(stdout, "old K", y->K, sizeof(y->K)); +#endif + /* K <- h'(t) */ + + TRY( krb5int_yarrow_stretch(v_i, HASH_DIGEST_SIZE, y->K, CIPHER_KEY_SIZE) ); + + /* need to resetup the key schedule as the key has changed */ + + TRY(krb5int_yarrow_cipher_init(&y->cipher, y->K)); + +#if defined(YARROW_DEBUG) + hex_print(stdout, "new K", y->K, sizeof(y->K)); +#endif + + /* step 4. C <- E_k(0) */ + +#if defined(YARROW_DEBUG) + hex_print(stdout, "old C", y->C, sizeof(y->C)); +#endif + TRY (krb5int_yarrow_cipher_encrypt_block (&y->cipher, zero_block, y->C)); +#if defined(YARROW_DEBUG) + hex_print(stdout, "new C", y->C, sizeof(y->C)); +#endif + + /* discard part output from previous key */ + + y->out_left = 0; + + /* step 5. Reset all entropy estimate accumulators of the entropy + * accumulator to zero + */ + + for (i = 0; i < y->num_sources; i++) + { + y->source[i].entropy[pool] = 0; + if (pool == YARROW_SLOW_POOL) + { + /* if this is a slow reseed, reset the fast pool entropy + * accumulator also + */ + y->source[i].entropy[YARROW_FAST_POOL] = 0; + y->source[i].reached_slow_thresh = 0; + } + } + + /* step 7. If a seed file is in use, the next 2k bits of output + * are written to the seed file + */ + +#if defined( YARROW_SAVE_STATE ) + if ( y->seeded && y->entropyfile ) + { + TRY( Yarrow_Save_State( y ) ); + } +#endif + +CATCH: + /* step 6. Wipe the memory of all intermediate values + * + */ + + mem_zero( digest, sizeof(digest) ); + mem_zero( &hash, sizeof(hash) ); + mem_zero( v_0, sizeof(v_0) ); + mem_zero( v_i, sizeof(v_i) ); + + EXCEP_RET; +} +int krb5int_yarrow_reseed(Yarrow_CTX* y, int pool) +{ + int r; + LOCK(); + r = yarrow_reseed_locked(y, pool); + UNLOCK(); + return r; +} + +int krb5int_yarrow_stretch(const byte* m, size_t size, byte* out, size_t out_size) +{ + EXCEP_DECL; + const byte* s_i; + byte* outp; + int left; + unsigned int use; + HASH_CTX hash, save; + byte digest[HASH_DIGEST_SIZE]; + + if (m == NULL || size == 0 || out == NULL || out_size == 0) + { + THROW( YARROW_BAD_ARG ); + } + + /* + * s_0 = m + * s_1 = h(s_0 | ... | s_{i-1}) + * + * h'(m, k) = first k bits of (s_0 | s_1 | ...) + * + */ + + outp = out; + left = out_size; + + use = min(out_size, size); + mem_copy(outp, m, use); /* get k bits or as many as available */ + + s_i = (const byte*)m; /* pointer to s0 = m */ + outp += use; + left -= use; + + HASH_Init(&hash); + for ( ; + left > 0; + left -= HASH_DIGEST_SIZE) + { + HASH_Update(&hash, s_i, use); + + /* have to save hash state to one side as HASH_final changes state */ + + mem_copy(&save, &hash, sizeof(hash)); + HASH_Final(&hash, digest); + + use = min(HASH_DIGEST_SIZE, left); + mem_copy(outp, digest, use); + + /* put state back for next time */ + + mem_copy(&hash, &save, sizeof(hash)); + + s_i = outp; /* retain pointer to s_i */ + outp += use; + } + +CATCH: + mem_zero(&hash, sizeof(hash)); + mem_zero(digest, sizeof(digest)); + + EXCEP_RET; +} + +static void block_increment(void* block, const int sz) +{ + byte* b = block; + int i; + + for (i = sz-1; (++b[i]) == 0 && i > 0; i--) + { + ; /* nothing */ + } +} + +YARROW_DLL +int krb5int_yarrow_final(Yarrow_CTX* y) +{ + EXCEP_DECL; + int locked = 0; + + if (!y) { THROW( YARROW_BAD_ARG ); } + TRY( LOCK() ); + locked = 1; + +#if defined( YARROW_SAVE_STATE ) + if ( y->seeded && y->entropyfile ) + { + TRY( Yarrow_Save_State( y ) ); + } +#endif + +CATCH: + if ( y ) + { + krb5int_yarrow_cipher_final(&y->cipher); + mem_zero( y, sizeof(Yarrow_CTX) ); + } + if ( locked ) { TRY( UNLOCK() ); } + EXCEP_RET; +} + +YARROW_DLL +const char* krb5int_yarrow_str_error( int err ) +{ + err = 1-err; + if ( err < 0 || + (unsigned int) err >= sizeof( yarrow_str_error ) / sizeof( char* ) ) + { + err = 1-YARROW_FAIL; + } + return yarrow_str_error[ err ]; +} + +#if defined(YARROW_DEBUG) +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"); +} +#endif diff --git a/src/lib/crypto/krb/prng/yarrow/yarrow.h b/src/lib/crypto/krb/prng/yarrow/yarrow.h new file mode 100644 index 000000000..02abfaf8d --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/yarrow.h @@ -0,0 +1,188 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef YARROW_H +#define YARROW_H + +#ifdef HAVE_UNISTD_H +#define YARROW_DETECT_FORK +#include +#endif +#define YARROW_NO_MATHLIB + +#include "ytypes.h" +#include +#include "ycipher.h" + +extern const struct krb5_prng_provider krb5int_prng_yarrow; + +/* These error codes are returned by the functions below. */ + +#define YARROW_OK 1 /* All is well */ +#define YARROW_FAIL 0 /* generic failure */ +#define YARROW_NOT_INIT -1 /* YarrowInit hasn't been called */ +#define YARROW_ALREADY_INIT -2 /* YarrowInit has already been called */ +#define YARROW_NO_DRIVER -3 /* driver doesn't exist */ +#define YARROW_CANT_OPEN -4 /* can't open driver */ +#define YARROW_BAD_SOURCE -5 /* invalid source id */ +#define YARROW_TOO_MANY_SOURCES -6 /* can't create any more source ids */ +#define YARROW_BAD_ARG -7 /* invalid argument */ +#define YARROW_ACCESS -8 /* insufficient privileges */ +#define YARROW_NOMEM -9 /* out of memory */ +#define YARROW_NORSRC -10 /* a resource is exhausted */ +#define YARROW_NOT_SEEDED -11 /* not enough entropy to generate output */ +#define YARROW_LOCKING -12 /* locking error */ +#define YARROW_NO_STATE -13 /* there is no state to load */ +#define YARROW_STATE_ERROR -14 /* error with state load or save */ +#define YARROW_NOT_IMPL -15 /* not implemented */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Yarrow implementation and configuration parameters */ + +/* pool identification */ +#define YARROW_FAST_POOL 0 +#define YARROW_SLOW_POOL 1 + +#define YARROW_MAX_SOURCES 20 +#define YARROW_ENTROPY_MULTIPLIER 0.5 + +#define YARROW_POOL_SIZE (HASH_DIGEST_SIZE*8) + +#define YARROW_OUTPUTS_PER_GATE 10 /* Pg */ +#define YARROW_FAST_PT 10 +#define YARROW_SLOW_PT 100 + +/* thresholds to use once seeded */ + +#define YARROW_FAST_THRESH 100 +#define YARROW_SLOW_THRESH 160 +#define YARROW_K_OF_N_THRESH 2 + +/* The Yarrow paper does not specify when the initial seed should be + considered complete. Use the same conditions as a slow reseed */ + +#define YARROW_FAST_INIT_THRESH YARROW_FAST_THRESH +#define YARROW_SLOW_INIT_THRESH YARROW_SLOW_THRESH +#define YARROW_K_OF_N_INIT_THRESH YARROW_K_OF_N_THRESH + +/* sanity checks */ + +#if YARROW_FAST_THRESH > YARROW_POOL_SIZE +error "can't have higher YARROW_FAST_THRESH than pool size" +#endif + +#if YARROW_SLOW_THRESH > YARROW_POOL_SIZE +error "can't have higher YARROW_SLOW_THRESH than pool size" +#endif + +#if YARROW_FAST_INIT_THRESH > YARROW_POOL_SIZE +error "can't have higher YARROW_FAST_INIT_THRESH than pool size" +#endif + +#if YARROW_SLOW_INIT_THRESH > YARROW_POOL_SIZE +error "can't have higher YARROW_SLOW_INIT_THRESH than pool size" +#endif + +typedef size_t estimator_fn(const void* sample, size_t size); + +typedef struct +{ + int pool; + size_t entropy[2]; + int reached_slow_thresh; + estimator_fn* estimator; +} Source; + +typedef struct +{ + /* state */ + int seeded; + int saved; +#if defined( YARROW_DETECT_FORK ) + int pid; +#endif + Source source[YARROW_MAX_SOURCES]; + unsigned num_sources; + HASH_CTX pool[2]; + byte out[CIPHER_BLOCK_SIZE]; + unsigned out_left; + COUNTER out_count; + COUNTER gate_count; + COUNTER gates_limit; + byte C[CIPHER_BLOCK_SIZE]; + CIPHER_CTX cipher; + byte K[CIPHER_KEY_SIZE]; + + const char *entropyfile; + + /* parameters */ + COUNTER Pt[2]; + COUNTER Pg; + int slow_k_of_n; + + /* current thresholds */ + size_t slow_thresh; + size_t fast_thresh; + int slow_k_of_n_thresh; +} Yarrow_CTX; + +# define YARROW_DLL + + +YARROW_DLL +int krb5int_yarrow_init( Yarrow_CTX* y, const char *filename ); + + +YARROW_DLL +int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, + const void* sample, + size_t size, size_t entropy_bits ); + +YARROW_DLL +int krb5int_yarrow_status( Yarrow_CTX* y, int *num_sources, unsigned *source_id, + size_t *entropy_bits, size_t *entropy_max ); + +YARROW_DLL +int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ); + +YARROW_DLL +int krb5int_yarrow_new_source( Yarrow_CTX* y, unsigned* source_id ); + +YARROW_DLL +int krb5int_yarrow_register_source_estimator( Yarrow_CTX* y, unsigned source_id, + estimator_fn* fptr ); + +YARROW_DLL +int krb5int_yarrow_stretch( const byte* m, size_t size, byte* out, size_t out_size ); + +YARROW_DLL +int krb5int_yarrow_reseed( Yarrow_CTX* y, int pool ); + +YARROW_DLL +int krb5int_yarrow_gate( Yarrow_CTX* y ); + +YARROW_DLL +int krb5int_yarrow_final( Yarrow_CTX* y ); + +YARROW_DLL +const char* krb5int_yarrow_str_error( int ); + + +# define mem_zero(p, n) memset((p), 0, (n)) +# define mem_copy(d, s, n) memcpy((d), (s), (n)) + + +#if !defined(WIN32) +# define min(x, y) ((x) < (y) ? (x) : (y)) +# define max(x, y) ((x) > (y) ? (x) : (y)) +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* YARROW_H */ diff --git a/src/lib/crypto/krb/prng/yarrow/yarrow.man b/src/lib/crypto/krb/prng/yarrow/yarrow.man new file mode 100644 index 000000000..a65b4e05c --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/yarrow.man @@ -0,0 +1,315 @@ +.rn '' }` +''' $RCSfile$$Revision$$Date$ +''' +''' $Log$ +''' Revision 1.1 2001/11/08 21:51:57 hartmans +''' Add Yarrow from http://www.zeroknowledge.com/. +''' +''' This is version 0.1 of their Yarrow implementation. I have flattened the distribution, +''' copying files in the src directory directly into this directory. +''' +''' Revision 1.1.2.1 2000/08/13 21:11:24 adamb +''' added some more assumptions +''' included yarrow.man derived from yarrow.pod with pod2man +''' +''' +.de Sh +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb +.ft CW +.nf +.ne \\$1 +.. +.de Ve +.ft R + +.fi +.. +''' +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(*W-|\(bv\*(Tr +.ie n \{\ +.ds -- \(*W- +.ds PI pi +.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of +''' \*(L" and \*(R", except that they are used on ".xx" lines, +''' such as .IP and .SH, which do another additional levels of +''' double-quote interpretation +.ds M" """ +.ds S" """ +.ds N" """"" +.ds T" """"" +.ds L' ' +.ds R' ' +.ds M' ' +.ds S' ' +.ds N' ' +.ds T' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds M" `` +.ds S" '' +.ds N" `` +.ds T" '' +.ds L' ` +.ds R' ' +.ds M' ` +.ds S' ' +.ds N' ` +.ds T' ' +.ds PI \(*p +'br\} +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +.TH YARROW 1 "perl 5.005, patch 03" "13/Aug/2000" "User Contributed Perl Documentation" +.UC +.if n .hy 0 +.if n .na +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.de CQ \" put $1 in typewriter font +.ft CW +'if n "\c +'if t \\&\\$1\c +'if n \\&\\$1\c +'if n \&" +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +'.ft R +.. +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 +. \" AM - accent mark definitions +.bd B 3 +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds ? ? +. ds ! ! +. ds / +. ds q +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' +. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +.ds oe o\h'-(\w'o'u*4/10)'e +.ds Oe O\h'-(\w'O'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds v \h'-1'\o'\(aa\(ga' +. ds _ \h'-1'^ +. ds . \h'-1'. +. ds 3 3 +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +. ds oe oe +. ds Oe OE +.\} +.rm #[ #] #H #V #F C +.SH "NAME" +Yarrow_Init, Yarrow_Poll, Yarrow_Input, Yarrow_Status, Yarrow_Output, Yarrow_New_Source, Yarrow_Register_Source_Estimator, Yarrow Final \- cryptographic pseudo-random number generator +.SH "SYNOPSIS" +int \fIYarrow_Init\fR\|(Yarrow_CTX *y, const char *filename); +.PP +int \fIYarrow_New_Source\fR\|(Yarrow_CTX* y, unsigned* source_id); +.PP +int \fIYarrow_Poll\fR\|(Yarrow_CTX *y, unsigned source_id) +.PP +int \fIYarrow_Input\fR\|( Yarrow_CTX* y, unsigned source_id, + const void* sample, size_t size, + size_t entropy_bits); +.PP +int \fIYarrow_Status\fR\|(Yarrow_CTX* y, int *num_sources, + unsigned *source_id, size_t *entropy_bits, + size_t *entropy_max); +.PP +int \fIYarrow_Output\fR\|(Yarrow_CTX* y, void* out, size_t size); +.PP +int \fIYarrow_Register_Source_Estimator\fR\|(Yarrow_CTX* y, + unsigned source_id, + size_t (*estimator)(const void* sample, + size_t size)); +.PP +int \fIYarrow_Final\fR\|(Yarrow_CTX* y); +.SH "DESCRIPTION" +\fIYarrow_Init()\fR initializes a \fBYarrow_CTX\fR structure. \fBfilename\fR can +be NULL, or the path to a seed file that Yarrow will use to store the +PRNG state for use in later sessions. Returns \fBYARROW_OK\fR if the +PRNG is seeded on exit, or \fBYARROW_NOT_SEEDED\fR if the PRNG is not yet +seeded. +.PP +\fIYarrow_New_Source()\fR associates entropy sources such as keyboard input, +mouse movements and other unpredictable events with a +\fBYarrow_CTX\fR. The function assigns a unique number to the new source, +and places it in \fBsource_id\fR. +.PP +\fIYarrow_Poll()\fR gathers entropy from the state of the machine and adds +it to the source \fBsource_id\fR. The source has to be allocated by the +user with Yarrow_New_Source. Returns \fBYARROW_OK\fR if the PRNG is +seeded on exit, or \fBYARROW_NOT_SEEDED\fR if the PRNG is not yet seeded. +.PP +\fIYarrow_Input()\fR is used to add randomness from the source \fBsource_id\fR +to the PRNG. It reads \fBsize\fR bytes at the address \fBsample\fR. An +estimate of the entropy in bits contained in the sample must be +specified as \fBentropy_bits\fR. +.PP +\fIYarrow_Status()\fR returns \fBYARROW_OK\fR if the PRNG has enough entropy to +produce output, and \fBYARROW_NOT_SEEDED\fR if calls to \fIYarrow_Output()\fR +would fail. +.PP +If num_sources is not NULL, the number of entropy sources that still +need to be seeded is returned in \fB*num_sources\fR. +.PP +If source_id is not NULL, the entropy source that is closest to its +threshold is returned in \fB*source_id\fR. \fB*source_id\fR is set to \-1 if +no sources have either reached their threshold or not collected any +entropy yet. +.PP +If not NULL, \fB*entropy_bits\fR is set to the current number of bits for +the source \fB*source_id\fR, and \fB*entropy_max\fR to the threshold. +.PP +\fIYarrow_Output()\fR generates \fBsize\fR bytes of cryptographically strong +pseudo-random output and places them at \fBout\fR. The return value must +always be checked. If an error occurs, the PRNG may produce +predictable data or no output at all. +.PP +\fIYarrow_Register_Source_Estimator()\fR registers an entropy estimator +for \fBsource_id\fR. An entropy estimator is a function that tries to +estimate the entropy in a sample and returns the entropy in bits +in order to detect abnormal situations in which the samples have a very +low entropy. +.PP +\fIYarrow_Final()\fR writes the PRNG state to the seed file and erases it +from memory. +.SH "RETURN VALUES" +All functions return \fBYARROW_OK\fR on success. Error conditions are reported +as follows: +.PP +.Vb 16 +\& YARROW_FAIL generic failure +\& YARROW_NOT_INIT YarrowInit() hasn't been called +\& YARROW_ALREADY_INIT YarrowInit() has already been called +\& YARROW_NO_DRIVER driver doesn't exist +\& YARROW_CANT_OPEN can't open driver +\& YARROW_BAD_SOURCE invalid source id +\& YARROW_TOO_MANY_SOURCES can't create any more source IDs +\& YARROW_BAD_ARG invalid argument +\& YARROW_ACCESS insufficient privileges +\& YARROW_NOMEM out of memory +\& YARROW_NORSRC a resource (apart from memory) is exhausted +\& YARROW_NOT_SEEDED not enough entropy to generate output +\& YARROW_LOCKING locking error +\& YARROW_NO_STATE there is no state to load +\& YARROW_STATE_ERROR error with state load or save +\& YARROW_NOT_IMPL not implemented +.Ve +.SH "AUTHORS" +Yarrow was designed by John Kelsey, Bruce Schneier and Niels Ferguson +of Counterpane Systems. This implementation is (C) 2000 by +Zero-Knowledge Systems Inc. + +.rn }` '' +.IX Title "YARROW 1" +.IX Name "Yarrow_Init, Yarrow_Poll, Yarrow_Input, Yarrow_Status, Yarrow_Output, Yarrow_New_Source, Yarrow_Register_Source_Estimator, Yarrow Final - cryptographic pseudo-random number generator" + +.IX Header "NAME" + +.IX Header "SYNOPSIS" + +.IX Header "DESCRIPTION" + +.IX Header "RETURN VALUES" + +.IX Header "AUTHORS" + diff --git a/src/lib/crypto/krb/prng/yarrow/yarrow.pod b/src/lib/crypto/krb/prng/yarrow/yarrow.pod new file mode 100644 index 000000000..7892ebbe6 --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/yarrow.pod @@ -0,0 +1,112 @@ +=pod + +=head1 NAME + +Yarrow_Init, Yarrow_Poll, Yarrow_Input, Yarrow_Status, Yarrow_Output, Yarrow_New_Source, Yarrow_Register_Source_Estimator, Yarrow Final - cryptographic pseudo-random number generator + +=head1 SYNOPSIS + +int Yarrow_Init(Yarrow_CTX *y, const char *filename); + +int Yarrow_New_Source(Yarrow_CTX* y, unsigned* source_id); + +int Yarrow_Poll(Yarrow_CTX *y, unsigned source_id) + +int Yarrow_Input( Yarrow_CTX* y, unsigned source_id, + const void* sample, size_t size, + size_t entropy_bits); + +int Yarrow_Status(Yarrow_CTX* y, int *num_sources, + unsigned *source_id, size_t *entropy_bits, + size_t *entropy_max); + +int Yarrow_Output(Yarrow_CTX* y, void* out, size_t size); + +int Yarrow_Register_Source_Estimator(Yarrow_CTX* y, + unsigned source_id, + size_t (*estimator)(const void* sample, + size_t size)); + +int Yarrow_Final(Yarrow_CTX* y); + +=head1 DESCRIPTION + +Yarrow_Init() initializes a B structure. B can +be NULL, or the path to a seed file that Yarrow will use to store the +PRNG state for use in later sessions. Returns B if the +PRNG is seeded on exit, or B if the PRNG is not yet +seeded. + +Yarrow_New_Source() associates entropy sources such as keyboard input, +mouse movements and other unpredictable events with a +B. The function assigns a unique number to the new source, +and places it in B. + +Yarrow_Poll() gathers entropy from the state of the machine and adds +it to the source B. The source has to be allocated by the +user with Yarrow_New_Source. Returns B if the PRNG is +seeded on exit, or B if the PRNG is not yet seeded. + +Yarrow_Input() is used to add randomness from the source B +to the PRNG. It reads B bytes at the address B. An +estimate of the entropy in bits contained in the sample must be +specified as B. + +Yarrow_Status() returns B if the PRNG has enough entropy to +produce output, and B if calls to Yarrow_Output() +would fail. + +If num_sources is not NULL, the number of entropy sources that still +need to be seeded is returned in B<*num_sources>. + +If source_id is not NULL, the entropy source that is closest to its +threshold is returned in B<*source_id>. B<*source_id> is set to -1 if +no sources have either reached their threshold or not collected any +entropy yet. + +If not NULL, B<*entropy_bits> is set to the current number of bits for +the source B<*source_id>, and B<*entropy_max> to the threshold. + +Yarrow_Output() generates B bytes of cryptographically strong +pseudo-random output and places them at B. The return value must +always be checked. If an error occurs, the PRNG may produce +predictable data or no output at all. + +Yarrow_Register_Source_Estimator() registers an entropy estimator +for B. An entropy estimator is a function that tries to +estimate the entropy in a sample and returns the entropy in bits +in order to detect abnormal situations in which the samples have a very +low entropy. + +Yarrow_Final() writes the PRNG state to the seed file and erases it +from memory. + +=head1 RETURN VALUES + +All functions return B on success. Error conditions are reported +as follows: + + YARROW_FAIL generic failure + YARROW_NOT_INIT YarrowInit() hasn't been called + YARROW_ALREADY_INIT YarrowInit() has already been called + YARROW_NO_DRIVER driver doesn't exist + YARROW_CANT_OPEN can't open driver + YARROW_BAD_SOURCE invalid source id + YARROW_TOO_MANY_SOURCES can't create any more source IDs + YARROW_BAD_ARG invalid argument + YARROW_ACCESS insufficient privileges + YARROW_NOMEM out of memory + YARROW_NORSRC a resource (apart from memory) is exhausted + YARROW_NOT_SEEDED not enough entropy to generate output + YARROW_LOCKING locking error + YARROW_NO_STATE there is no state to load + YARROW_STATE_ERROR error with state load or save + YARROW_NOT_IMPL not implemented + +=head1 AUTHORS + +Yarrow was designed by John Kelsey, Bruce Schneier and Niels Ferguson +of Counterpane Systems. This implementation is (C) 2000 by +Zero-Knowledge Systems Inc. + +=cut diff --git a/src/lib/crypto/krb/prng/yarrow/ycipher.c b/src/lib/crypto/krb/prng/yarrow/ycipher.c new file mode 100644 index 000000000..7222d94c5 --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/ycipher.c @@ -0,0 +1,89 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * lib/crypto/yarrow/ycipher.c + * + * Copyright (C) 2001, 2007 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. + * + * + * + * Routines to implement krb5 cipher operations. + */ +#include "k5-int.h" +#include "yarrow.h" +#include "ycipher.h" +#include "enc_provider.h" +#include "assert.h" + +int +krb5int_yarrow_cipher_init(CIPHER_CTX *ctx, unsigned const char * key) +{ + size_t keybytes, keylength; + const struct krb5_enc_provider *enc = &yarrow_enc_provider; + krb5_error_code ret; + krb5_data randombits; + krb5_keyblock keyblock; + + keybytes = enc->keybytes; + keylength = enc->keylength; + assert (keybytes == CIPHER_KEY_SIZE); + krb5_k_free_key(NULL, ctx->key); + ctx->key = NULL; + keyblock.contents = malloc(keylength); + keyblock.length = keylength; + keyblock.enctype = yarrow_enc_type; + if (keyblock.contents == NULL) + return (YARROW_NOMEM); + randombits.data = (char *) key; + randombits.length = keybytes; + ret = enc->make_key(&randombits, &keyblock); + if (ret != 0) + goto cleanup; + ret = krb5_k_create_key(NULL, &keyblock, &ctx->key); +cleanup: + free(keyblock.contents); + if (ret) + return YARROW_FAIL; + return YARROW_OK; +} + +int krb5int_yarrow_cipher_encrypt_block(CIPHER_CTX *ctx, + const unsigned char *in, + unsigned char *out) +{ + krb5_error_code ret; + krb5_crypto_iov iov; + const struct krb5_enc_provider *enc = &yarrow_enc_provider; + + memcpy(out, in, CIPHER_BLOCK_SIZE); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data(out, CIPHER_BLOCK_SIZE); + ret = enc->encrypt(ctx->key, 0, &iov, 1); + return (ret == 0) ? YARROW_OK : YARROW_FAIL; +} + +void +krb5int_yarrow_cipher_final(CIPHER_CTX *ctx) +{ + krb5_k_free_key(NULL, ctx->key); + ctx->key = NULL; +} diff --git a/src/lib/crypto/krb/prng/yarrow/ycipher.h b/src/lib/crypto/krb/prng/yarrow/ycipher.h new file mode 100644 index 000000000..4d7dc9dfd --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/ycipher.h @@ -0,0 +1,43 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef YCIPHER_H +#define YCIPHER_H + +/* block cipher interface */ + +typedef struct +{ + krb5_key key; +} CIPHER_CTX; + +/* We need to choose a cipher. To do this, choose an enc_provider. + * Be sure to update the block size and key size constants below; + * they are here because static data structures are sized based on + * them so they must be known at compile time./ Thus we cannot + * call the enc_provider function to get the info. + */ + +#define yarrow_enc_provider krb5int_enc_aes256 +#define yarrow_enc_type ENCTYPE_AES256_CTS_HMAC_SHA1_96 + +#define CIPHER_BLOCK_SIZE 16 +#define CIPHER_KEY_SIZE 32 + +#if defined( YARROW_NO_MATHLIB ) +/* see macros at end for functions evaluated */ +#define POW_CIPHER_KEY_SIZE 115792089237316195423570985008687907853269984665640564039457584007913129639936.0 +#define POW_CIPHER_BLOCK_SIZE 340282366920938463463374607431768211456.0 +#endif + + +int krb5int_yarrow_cipher_init (CIPHER_CTX *ctx, unsigned const char *key); +int krb5int_yarrow_cipher_encrypt_block +(CIPHER_CTX *ctx, const unsigned char *in, unsigned char *out); +void krb5int_yarrow_cipher_final (CIPHER_CTX *ctx); + +#if !defined( YARROW_NO_MATHLIB ) +#define POW_CIPHER_KEY_SIZE pow(2.0, CIPHER_KEY_SIZE * 8 / 3.0) +#define POW_CIPHER_BLOCK_SIZE pow(2.0, CIPHER_BLOCK_SIZE * 8) +#endif + +#endif /* YCIPHER_H */ diff --git a/src/lib/crypto/krb/prng/yarrow/yexcep.h b/src/lib/crypto/krb/prng/yarrow/yexcep.h new file mode 100644 index 000000000..f76f650e0 --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/yexcep.h @@ -0,0 +1,107 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef YEXCEP_H +#define YEXCEP_H + +/* yes, macros with gotos in them, but in the interests of + * avoiding repetition of code, and having less error prone + * error handling + * + * EXCEP_DECL - declares the return value and local state variables + * needed by the exception macros + * + * THROW( x ) - set return value to x and goto function cleanup + * section (CATCH: block). In the catch block, THROW + * does not goto catch label to avoid loops, and instead + * falls through to the next statement. + * + * EXCEP_OK - success return value (=1) + * + * EXCEP_FAIL - failure return value (=0), other user exceptions are + * given negative values (<0) + * + * TRY( x ) - if code returns value <= 0 TRY sets return value to + * that value and goes to function cleanup section + * (CATCH: block). In the catch block, TRY does not goto + * the catch label to avoid loops, and instead + * falls through to the next statement. The + * return value is set to the first non success value + * returned by a TRY, unless this is overridden by a THROW. + * + * CATCH: - start of catch block, also switches behavior of + * TRY and THROW to not goto CATCH: inside the catch + * block to avoid loops + * + * EXCEP_RET - return the current return value from the function + * equivlanet to return (EXCEPTION) + * + * EXCEPTION - current return value, is set to EXCEP_OK by EXCEP_DECL + * + * EXCEP_BOOL - convert current return value to EXCEP_OK, or EXCEP_FAIL + * (EXCEP_FAIL is anything other than EXCEP_OK) + * + */ + +/* example usage */ + +/* + * + * #define EXCEP_OK_COMMENT 2 + * #define EXCEP_NULL_PTR -1 + * #define EXCEP_OUT_OF_MEM -2 + * + * int bar( char *c ) + * { + * EXCEP_DECL; + * + * if ( !c ) { THROW( EXCEP_NULL_PTR ); } + * if ( *c == '\0' ) { THROW( EXCEP_FAIL ); ); + * if ( *c == '#' ) { SET( EXCEP_COMMENT ); } + * CATCH: + * EXCEP_RET; + * } + * + * int foo( char *c ) + * { + * EXCEP_DECL; + * int *p = NULL; + * + * if ( !c ) { THROW( EXCEP_NULL_PTR ); } + * TRY( bar( c ) ); + * if ( RETURN == EXCEP_COMMENT ) { print( "comment\n" ); } + * p = strdup( c ); + * if ( !p ) { THROW( EXCEP_OUT_OF_MEM ); } + * + * CATCH: + * if ( p ) { TRY( bar( p ) ); free( p ); } + * THROW( EXCEP_BOOL ); + * if ( EXCEPTION == EXCEP_OK ) { printf( "success\n" ); } + * EXCEP_RET; + * } + * + */ + +#define EXCEP_FAIL 0 +#define EXCEP_OK 1 +#define EXCEP_DECL int _thr = 0, _ret2 = 0, _ret = _ret2+EXCEP_OK + +#define THROW( x ) \ + do { \ + _ret = (x); \ + if( !_thr ) { goto _catch; } \ + } while ( 0 ) + +#define TRY( x ) \ + do { \ + _ret2 = (x); \ + if ( _ret > 0 && _ret2 <= 0 ) { THROW( _ret2 ); } \ + } while ( 0 ) + +#define SET( x ) (_ret = (x)) +#define EXCEP_RET return( _ret ) +#define EXCEPTION _ret +#define RETURN _ret2 +#define CATCH _catch: _thr = 1; if ( 0 ) { goto _foo; } _foo +#define EXCEP_BOOL ( _ret > 0 ? EXCEP_OK : EXCEP_FAIL ) + +#endif diff --git a/src/lib/crypto/krb/prng/yarrow/ylock.h b/src/lib/crypto/krb/prng/yarrow/ylock.h new file mode 100644 index 000000000..aacf786af --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/ylock.h @@ -0,0 +1,24 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef YLOCK_H +#define YLOCK_H + +#include "yarrow.h" + +/* these functions should return: + * + * YARROW_OK on success + * and YARROW_LOCKING on failure + */ + +#if 0 +static int LOCK( void ) { return (YARROW_OK); } +static int UNLOCK( void ) { return (YARROW_OK); } +#else +#include "k5-thread.h" +extern k5_mutex_t krb5int_yarrow_lock; +#define LOCK() (k5_mutex_lock(&krb5int_yarrow_lock) ? YARROW_LOCKING : YARROW_OK) +#define UNLOCK() (k5_mutex_unlock(&krb5int_yarrow_lock) ? YARROW_LOCKING : YARROW_OK) +#endif + +#endif /* YLOCK_H */ diff --git a/src/lib/crypto/krb/prng/yarrow/ystate.h b/src/lib/crypto/krb/prng/yarrow/ystate.h new file mode 100644 index 000000000..fd277d28a --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/ystate.h @@ -0,0 +1,28 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef YSTATE_H +#define YSTATE_H + +#ifdef YARROW_SAVE_STATE + +#include "ycipher.h" +#include "ytypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Yarrow_STATE { + byte seed[CIPHER_KEY_SIZE * 2]; /* 2k bits saved to seed file */ +} Yarrow_STATE; + +int STATE_Save( const char *filename, const struct Yarrow_STATE* state ); +int STATE_Load( const char *filename, struct Yarrow_STATE* state ); + +#ifdef __cplusplus +} +#endif + +#endif /* YARROW_SAVE_STATE */ + +#endif /* YSTATE_H */ diff --git a/src/lib/crypto/krb/prng/yarrow/ytypes.h b/src/lib/crypto/krb/prng/yarrow/ytypes.h new file mode 100644 index 000000000..9abbf8c9d --- /dev/null +++ b/src/lib/crypto/krb/prng/yarrow/ytypes.h @@ -0,0 +1,27 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef YTYPES_H +#define YTYPES_H + +#include +#include +#include "autoconf.h" +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#define byte unsigned char + +#define uint8 unsigned char +#define int8 signed char + + +#if defined(uint64) +# define COUNTER uint64 +#else +# define COUNTER krb5_ui_4 +#endif + +#define COUNTER_MAX ((COUNTER)0 - 1) + +#endif /* YTYPES_H */ diff --git a/src/lib/crypto/krb/yarrow/ASSUMPTIONS b/src/lib/crypto/krb/yarrow/ASSUMPTIONS deleted file mode 100644 index 3e3c99c49..000000000 --- a/src/lib/crypto/krb/yarrow/ASSUMPTIONS +++ /dev/null @@ -1,101 +0,0 @@ -Assumptions -=========== - -The Yarrow design, described in "Yarrow-160: Notes on the Design and -Analysis of the Yarrow Cryptographic Pseudonumber Generator" by John -Kelsey, Bruce Schneier and Niels Ferguson of Counterpane Systems -(available from http://www.counterpane.com/yarrow.html), left out some -implementation details and has some ambiguities in the protocol. ZKS -has to made some assumptions and taken some decisions in its -implementation of Yarrow. In the text, `we' represents ZKS. - -Here is the list of those assumptions: - -1) To simplify the code and speed up running time, we limit the number -of different sources to 20. This should be enough for most -applications. This can be changed by redefining YARROW_MAX_SOURCE in -yarrow.h. - -2) The Yarrow paper (in section 5.3) state that Pt is either -implementation dependent or dynamically adjusted. We chose to fix the -slow pool's Pt to 100 and the fast pool's Pt to 10. This can be -changed by redefining YARROW_FAST_PT and YARROW_SLOW_PT in yarrow.c. - -3) Initialization when there is no saved state is not discussed in the -Yarrow paper. We have defined that CPRNG is becomes seeded after a -slow reseed. During initialization, a slow reseed is triggered by -YARROW_K_OF_N_INIT_THRESH sources reaching the slow threshold -YARROW_SLOW_INIT_THRESH. During initialization, fast reseeds are -triggered when a source reaches the fast threshold -YARROW_FAST_INIT_THRESH. After reseed the behavior of the pools is -controlled by YARROW_K_OF_N_THRESH, YARROW_SLOW_THRESH and -YARROW_FAST_THRESH. - -Our default values for YARROW_K_OF_N_INIT_THRESH, -YARROW_SLOW_INIT_THRESH and YARROW_FAST_INIT_THRESH are the same as -YARROW_K_OF_N_THRESH, YARROW_SLOW_THRESH and YARROW_FAST_THRESH -respectively. Note this means that a Yarrow_Poll call by itself can -never put us in an initialized state, as it only works on one pool, -and the default YARROW_K_OF_N_INIT_THRESH value is 2. - -4) We define a function Yarrow_Poll which can gather entropy. The -user must allocate a source_id, and call Yarrow_Poll manually. -Yarrow_Poll just adds samples from the machines state to the source -given as an argument. - -5) Prior to initialization, Yarrow_Output will fail. - -6) The actions to take on state load are not described in the yarrow -paper, all it says is that 2k bytes should be written (and by -implication read back in somehow). We read in the 2k bytes, hash -them into the fast pool, and then do a forced fast reseed, and an -immediate state save. - -7) In step 2 of the reseed process, we must hash the value i. The -representation of this integer will affect the hash value. In our -code, i is a 64-bit unsigned value. We update the hash context using -the 64 bit big endian representation of i. - -8) Yarrow outputs random bits in blocks. If the calling function -requests less bits than available, then the unused bits are kept -in memory until the next call. In case of a reseed, we chose to -discard those leftover bits. - -9) The samples from one source must alternate between the two pools. -As a default, we initialize the first pool to send the sample too to -be the fast pool. This initialization is done only when a source is -added, not when we reseed from one. - -10) The Yarrow paper states that the maximum number of outputs between -reseeding is limited to min(2^n,2^(k/3)*Pg), but does not explain -what is to happen when this limit is reached. It could be the case -that we reach the limit but there is not enough entropy in the pools -to reseed. In our code, the Yarrow_Output_Block will do a forced -fast reseed. - -11) In the Yarrow paper, the limit on the number of outputs between -reseeding is expressed in number of outputs: - -#oututs <= min(2^n, 2^(k/3).Pg) - -but we redefine it in terms of gates by dividing the numbers by Pg, -the number of outputs per gate, and counting the number of gates -instead. This makes an overflow a little less likely. - -We don't use a bignum library, so in event of overflow, the limit in -number of gates before reseed (y->gates_limit) is reduced down to -2^64-1 (or 2^32-1 if 64 bit ints aren't available on the platform). - -12) The Yarrow paper describes that the cipher block C should be -incremented as part of the output function. We treat the bytes -of C as a big endian number to do the increment. - -13) Triple-DES key size. The yarrow paper uses the letter k to -represent the keysize in bits. Due to the parity bits, the size of k -is 192 bits. However the effective key size is actually 168 bits, as -the value of k is used in security limits, k must be 168 bits. The -paper uses k (eg set K to the next k output bits), so we have to do -the parity padding function, to copy bits 0-6 to 0-7, 7-13 to 8-15 -etc. The macro DES_Init performs the function of doing a DES key -schedule from a packed key (no parity bits), internally doing the -parity padding. Other ciphers are simpler as there is no parity. diff --git a/src/lib/crypto/krb/yarrow/LICENSE b/src/lib/crypto/krb/yarrow/LICENSE deleted file mode 100644 index c85475d7e..000000000 --- a/src/lib/crypto/krb/yarrow/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright 2000 by Zero-Knowledge Systems, Inc. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -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 Zero-Knowledge Systems, -Inc. not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. Zero-Knowledge Systems, Inc. makes no representations -about the suitability of this software for any purpose. It is -provided "as is" without express or implied warranty. - -ZERO-KNOWLEDGE SYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL ZERO-KNOWLEDGE SYSTEMS, INC. BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/src/lib/crypto/krb/yarrow/Makefile.in b/src/lib/crypto/krb/yarrow/Makefile.in deleted file mode 100644 index 55ae16ce3..000000000 --- a/src/lib/crypto/krb/yarrow/Makefile.in +++ /dev/null @@ -1,38 +0,0 @@ -mydir=lib/crypto/krb/yarrow -BUILDTOP=$(REL)..$(S)..$(S)..$(S).. -LOCALINCLUDES = -I$(srcdir)/.. \ - -I$(srcdir)/../../@CRYPTO_IMPL@ \ - -I$(srcdir)/../../@CRYPTO_IMPL@/sha1 \ - -I$(srcdir)/../../@CRYPTO_IMPL@/enc_provider -DEFS= - -##DOS##BUILDTOP = ..\..\..\.. -##DOS##PREFIXDIR=yarrow -##DOS##OBJFILE=..\$(OUTPRE)yarrow.lst - -PROG_LIBPATH=-L$(TOPLIBD) -PROG_RPATH=$(KRB5_LIBDIR) - -STLIBOBJS=\ - yarrow.o \ - ycipher.o -OBJS=\ - $(OUTPRE)yarrow.$(OBJEXT) \ - $(OUTPRE)ycipher.$(OBJEXT) - -SRCS=\ - $(srcdir)/yarrow.c \ - $(srcdir)/ycipher.c - -##DOS##LIBOBJS = $(OBJS) - -all-unix:: all-libobjs - -includes:: depend - -depend:: $(SRCS) - -clean-unix:: clean-libobjs - -@libobj_frag@ - diff --git a/src/lib/crypto/krb/yarrow/README b/src/lib/crypto/krb/yarrow/README deleted file mode 100644 index 3dd4b801a..000000000 --- a/src/lib/crypto/krb/yarrow/README +++ /dev/null @@ -1,94 +0,0 @@ -Yarrow - Secure Pseudo-Random Number Generator -============================================== - -This is an implementation of the cryptographic pseudo-random number -generator Yarrow. You are encouraged to use, modify, and incorporate -this code. Please see the accompanying LICENSE file for more details. - - -Yarrow can be used with OpenSSL 0.9.5a (http://www.openssl.org) and -other cryptographic libraries. - -The Yarrow design is described in "Yarrow-160: Notes on the Design and -Analysis of the Yarrow Cryptographic Pseudorandom Number Generator" by -John Kelsey, Bruce Schneier and Niels Ferguson of Counterpane Systems, -available from http://www.counterpane.com/yarrow.html - -The Yarrow function calls are described in the yarrow(3) manpage. - -Installation -============ - -By default, Yarrow is built with OpenSSL. If the OpenSSL headers are -not installed in the standard directory /usr/local/ssl/include, -set the path in the Makefile. - -If it is possible that an application using Yarrow will fork(), Yarrow -must be compiled with -DYARROW_DETECT_FORK (then the child process -will have to seed Yarrow again), or the Yarrow_CTX must be allocated -in shared memory. - -If compiled with -DYARROW_SAVE_STATE, Yarrow will use a seed file -specified in the Yarrow_Init call. - -When the settings in the Makefile are correct, run "make". - - -Yarrow with OpenSSL: -------------------- - -The macros YARROW_CIPHER_3DES (default), YARROW_CIPHER_BLOWFISH and -YARROW_CIPHER_IDEA for ciphers and YARROW_HASH_SHA1 (default) and -YARROW_HASH_MD5 for hash functions are available to select algorithms -from OpenSSL. - -CRYPTO_set_locking_callback() is required in multithreaded applications. - - -Yarrow with other cryptographic libraries: ------------------------------------------ - -The Yarrow implementation uses a symmetric cipher, a cryptographic -hash function and a mutex. By default, Yarrow calls OpenSSL. For use -with other cryptographic libraries, the following types and macros -should be defined: - -Symmetric cipher - ycipher.h: - - typedef struct { ... } CIPHER_CTX; - - #define CIPHER_BLOCK_SIZE ... - #define CIPHER_KEY_SIZE ... - - void CIPHER_Init(CIPHER_CTX *ctx, void *key); - void CIPHER_Encrypt_Block(CIPHER_CTX *ctx, void *in, void *out); - -Hash function - yhash.h: - - typedef struct { ... } HASH_CTX; - - #define HASH_DIGEST_SIZE ... - #define HASH_STATE_SIZE ... - - void HASH_Init(HASH_CTX *ctx); - void HASH_Update(HASH_CTX *ctx, const void *data, unsigned long size); - void HASH_Final(HASH_CTX *ctx, unsigned char *md); - -Mutex - ylock.h: - - int LOCK(void); - int UNLOCK(void); - -Learn More: ----------- - -It is Zero-Knowledge's hope that third party developers of yarrow will -collaborate to derive test vectors for yarrow. In an effort to further -this discussion, we have created a mailing list for developers and -interested parties. To subscribe, send an email to -"yarrow-request@zeroknowledge.com" with "subscribe" in the body of the -message. - -For more information, or if you have questions or comments regarding open -source at Zero-Knowledge Systems, please visit -http://opensource.zeroknowledge.com diff --git a/src/lib/crypto/krb/yarrow/TODO b/src/lib/crypto/krb/yarrow/TODO deleted file mode 100644 index bd133ecfd..000000000 --- a/src/lib/crypto/krb/yarrow/TODO +++ /dev/null @@ -1,9 +0,0 @@ -open issues: - -* when should the initial seed be considered complete? -* poll system ressources for randomness on startup? -* how frequently should the PRNG state be saved? -* how to react to fork()? -* what should the seed file contain, how should it be processed? -* test fork() hack -* test openSSL locks in multi-threaded environment diff --git a/src/lib/crypto/krb/yarrow/deps b/src/lib/crypto/krb/yarrow/deps deleted file mode 100644 index e668b3ee5..000000000 --- a/src/lib/crypto/krb/yarrow/deps +++ /dev/null @@ -1,29 +0,0 @@ -# -# Generated makefile dependencies follow. -# -yarrow.so yarrow.po $(OUTPRE)yarrow.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(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/plugin.h \ - $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h yarrow.c yarrow.h \ - ycipher.h yexcep.h ylock.h ystate.h ytypes.h -ycipher.so ycipher.po $(OUTPRE)ycipher.$(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/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ - $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - yarrow.h ycipher.c ycipher.h ytypes.h diff --git a/src/lib/crypto/krb/yarrow/yarrow.c b/src/lib/crypto/krb/yarrow/yarrow.c deleted file mode 100644 index 2eacd936b..000000000 --- a/src/lib/crypto/krb/yarrow/yarrow.c +++ /dev/null @@ -1,959 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -/* - * Yarrow - Cryptographic Pseudo-Random Number Generator - * Copyright (c) 2000 Zero-Knowledge Systems, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without fee, - * 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 Zero-Knowledge Systems, - * Inc. not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Zero-Knowledge Systems, Inc. makes no representations - * about the suitability of this software for any purpose. It is - * provided "as is" without express or implied warranty. - * - * See the accompanying LICENSE file for more information. - */ - -#include "k5-int.h" - -#include -#include -#ifdef _WIN32 -#include "port-sockets.h" -#else -# include -# include -#endif -#if !defined(YARROW_NO_MATHLIB) -#include -#endif - -#define YARROW_IMPL -#include "yarrow.h" -#include "ycipher.h" -#include "ylock.h" -#include "ystate.h" -#include "yexcep.h" - -#if defined( YARROW_DEBUG ) || defined( YARROW_TRACE ) -# include -#endif - -#undef TRACE -#if defined( YARROW_TRACE ) -extern int yarrow_verbose; -#define TRACE( x ) do { if (yarrow_verbose) { x } } while (0) -#else -#define TRACE( x ) -#endif - -#if defined(macintosh) -# define make_big_endian32(x) (x) -#else -# define make_big_endian32(x) htonl(x) -#endif - -#if defined( YARROW_DEBUG ) -static void hex_print(FILE* f, const char* var, void* data, size_t size); -#endif - -static void block_increment( void* block, const int sz ); -#if defined( YARROW_SAVE_STATE ) -static int Yarrow_Load_State( Yarrow_CTX *y ); -static int Yarrow_Save_State( Yarrow_CTX *y ); -#endif - -static int yarrow_gate_locked(Yarrow_CTX* y); - -static const byte zero_block[CIPHER_BLOCK_SIZE] = { 0, }; - -static const char* const yarrow_str_error[] = { - "ok", - "failed", - "failed: uninitialized", - "failed: already initialized", - "failed: no driver", - "failed: can't open driver", - "failed: invalid source id", - "failed: no more source ids available", - "failed: invalid argument", - "failed: insufficient privileges", - "failed: out of memory", - "failed: resource exhausted", - "failed: not enough entropy to generate output", - "failed: locking error", - "failed: no state to load", - "failed: state load or save failed", - "failed: not implemented" -}; - -/* calculate limits after initialization */ - -static void krb5int_yarrow_init_Limits(Yarrow_CTX* y) -{ - double tmp1, tmp2, limit; - /* max number of gates between reseeds -> exceed this, do forced reseed */ - - /* #oututs <= min(2^n, 2^(k/3).Pg) */ - - /* => #gates <= min(2^n/Pg, 2^(k/3)) */ - - tmp1 = POW_CIPHER_BLOCK_SIZE / y->Pg; - tmp2 = POW_CIPHER_KEY_SIZE; - limit = min(tmp1, tmp2); - if (limit < COUNTER_MAX) - { - y->gates_limit = limit; - } - else - { - y->gates_limit = COUNTER_MAX; - } -} - -static int yarrow_reseed_locked( Yarrow_CTX* y, int pool ); - -/* if the program was forked, the child must not operate on the same - PRNG state */ -#ifdef YARROW_DETECT_FORK - -static int -yarrow_input_locked( Yarrow_CTX* y, unsigned source_id, - const void *sample, - size_t size, size_t entropy_bits ); - -static int Yarrow_detect_fork(Yarrow_CTX *y) -{ - pid_t newpid; - EXCEP_DECL; - - /* this does not work for multi-threaded apps if threads have different - * pids */ - newpid = getpid(); - if ( y->pid != newpid ) - { - /* we input the pid twice, so it will get into the fast pool at least once - * Then we reseed. This doesn't really increase entropy, but does make the - * streams distinct assuming we already have good entropy*/ - y->pid = newpid; - TRY (yarrow_input_locked (y, 0, &newpid, - sizeof (newpid), 0)); - TRY (yarrow_input_locked (y, 0, &newpid, - sizeof (newpid), 0)); - TRY (yarrow_reseed_locked (y, YARROW_FAST_POOL)); - } - -CATCH: - EXCEP_RET; -} - -#else - -#define Yarrow_detect_fork(x) (YARROW_OK) - -#endif - -static void Yarrow_Make_Seeded( Yarrow_CTX* y ) -{ - TRACE( printf( "SEEDED," ); ); - y->seeded = 1; - - /* now we are seeded switch to _THRESH values */ - - y->slow_thresh = YARROW_SLOW_THRESH; - y->fast_thresh = YARROW_FAST_THRESH; - y->slow_k_of_n_thresh = YARROW_K_OF_N_THRESH; -} - -YARROW_DLL -int krb5int_yarrow_init(Yarrow_CTX* y, const char *filename) -{ - EXCEP_DECL; - int locked = 0; - - if (!y) { THROW( YARROW_BAD_ARG ); } - TRY( LOCK() ); - locked = 1; - - y->seeded = 0; - y->saved = 0; - -#if defined( YARROW_DETECT_FORK ) - y->pid = getpid(); -#endif - - y->entropyfile = filename; - y->num_sources = 0; - mem_zero(y->C, sizeof(y->C)); - HASH_Init(&y->pool[YARROW_FAST_POOL]); - HASH_Init(&y->pool[YARROW_SLOW_POOL]); - - mem_zero(y->K, sizeof(y->K)); - - mem_zero(&y->cipher, sizeof(y->cipher)); - - TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); - y->out_left = 0; - y->out_count = 0; - y->gate_count = 0; - y->Pg = YARROW_OUTPUTS_PER_GATE; - y->Pt[YARROW_FAST_POOL] = YARROW_FAST_PT; - y->Pt[YARROW_SLOW_POOL] = YARROW_SLOW_PT; - y->slow_k_of_n = 0; - - /* start with INIT_THRESH values, after seeded, switch to THRESH values */ - - y->slow_thresh = YARROW_SLOW_INIT_THRESH; - y->fast_thresh = YARROW_FAST_INIT_THRESH; - y->slow_k_of_n_thresh = YARROW_K_OF_N_INIT_THRESH; - - krb5int_yarrow_init_Limits(y); - -#if defined( YARROW_SAVE_STATE ) - if ( y->entropyfile != NULL ) - { - int ret = Yarrow_Load_State( y ); - if ( ret != YARROW_OK && ret != YARROW_NO_STATE ) - { - THROW( ret ); - } - - /* if load suceeded then write new state back immediately - */ - - /* Also check that it's not already saved, because the reseed in - * Yarrow_Load_State may trigger a save - */ - - if ( ret == YARROW_OK && !y->saved ) - { - TRY( Yarrow_Save_State( y ) ); - } - } -#endif - - if ( !y->seeded ) - { - THROW( YARROW_NOT_SEEDED ); - } - -CATCH: - if ( locked ) { TRY( UNLOCK() ); } - EXCEP_RET; -} - -static -int yarrow_input_maybe_locking( Yarrow_CTX* y, unsigned source_id, - const void* sample, - size_t size, size_t entropy_bits, - int do_lock ) -{ - EXCEP_DECL; - int ret; - int locked = 0; - Source* source; - size_t new_entropy; - size_t estimate; - - if (do_lock) { - TRY( LOCK() ); - locked = 1; - } - k5_assert_locked(&krb5int_yarrow_lock); - - if (!y) { THROW( YARROW_BAD_ARG ); } - - if (source_id >= y->num_sources) { THROW( YARROW_BAD_SOURCE ); } - - source = &y->source[source_id]; - - if(source->pool != YARROW_FAST_POOL && source->pool != YARROW_SLOW_POOL) - { - THROW( YARROW_BAD_SOURCE ); - } - - /* hash in the sample */ - - HASH_Update(&y->pool[source->pool], (const void*)sample, size); - - /* only update entropy estimate if pool is not full */ - - if ( (source->pool == YARROW_FAST_POOL && - source->entropy[source->pool] < y->fast_thresh) || - (source->pool == YARROW_SLOW_POOL && - source->entropy[source->pool] < y->slow_thresh) ) - { - new_entropy = min(entropy_bits, size * 8 * YARROW_ENTROPY_MULTIPLIER); - if (source->estimator) - { - estimate = source->estimator(sample, size); - new_entropy = min(new_entropy, estimate); - } - source->entropy[source->pool] += new_entropy; - if ( source->entropy[source->pool] > YARROW_POOL_SIZE ) - { - source->entropy[source->pool] = YARROW_POOL_SIZE; - } - - if (source->pool == YARROW_FAST_POOL) - { - if (source->entropy[YARROW_FAST_POOL] >= y->fast_thresh) - { - ret = yarrow_reseed_locked(y, YARROW_FAST_POOL); - if ( ret != YARROW_OK && ret != YARROW_NOT_SEEDED ) - { - THROW( ret ); - } - } - } - else - { - if (!source->reached_slow_thresh && - source->entropy[YARROW_SLOW_POOL] >= y->slow_thresh) - { - source->reached_slow_thresh = 1; - y->slow_k_of_n++; - if (y->slow_k_of_n >= y->slow_k_of_n_thresh) - { - y->slow_k_of_n = 0; - ret = yarrow_reseed_locked(y, YARROW_SLOW_POOL); - if ( ret != YARROW_OK && ret != YARROW_NOT_SEEDED ) - { - THROW( ret ); - } - } - } - } - } - - /* put samples in alternate pools */ - - source->pool = (source->pool + 1) % 2; - -CATCH: - if ( locked ) { TRY( UNLOCK() ); } - EXCEP_RET; -} - -YARROW_DLL -int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, - const void* sample, - size_t size, size_t entropy_bits ) -{ - return yarrow_input_maybe_locking(y, source_id, sample, size, - entropy_bits, 1); -} - -static int -yarrow_input_locked( Yarrow_CTX* y, unsigned source_id, - const void *sample, - size_t size, size_t entropy_bits ) -{ - return yarrow_input_maybe_locking(y, source_id, sample, size, - entropy_bits, 0); -} - -YARROW_DLL -int krb5int_yarrow_new_source(Yarrow_CTX* y, unsigned* source_id) -{ - EXCEP_DECL; - int locked = 0; - Source* source; - - if (!y) { THROW( YARROW_BAD_ARG ); } - - TRY( LOCK() ); - locked = 1; - - if (y->num_sources + 1 > YARROW_MAX_SOURCES) - { - THROW( YARROW_TOO_MANY_SOURCES ); - } - - *source_id = y->num_sources; - - source = &y->source[*source_id]; - - source->pool = YARROW_FAST_POOL; - source->entropy[YARROW_FAST_POOL] = 0; - source->entropy[YARROW_SLOW_POOL] = 0; - source->reached_slow_thresh = 0; - source->estimator = 0; - - y->num_sources++; -CATCH: - if ( locked ) { TRY( UNLOCK() ); } - EXCEP_RET; -} - -int krb5int_yarrow_register_source_estimator(Yarrow_CTX* y, unsigned source_id, - estimator_fn* fptr) -{ - EXCEP_DECL; - Source* source; - - if (!y) { THROW( YARROW_BAD_ARG ); } - if (source_id >= y->num_sources) { THROW( YARROW_BAD_SOURCE ); } - - source = &y->source[source_id]; - - source->estimator = fptr; - -CATCH: - EXCEP_RET; -} - -static int krb5int_yarrow_output_Block( Yarrow_CTX* y, void* out ) -{ - EXCEP_DECL; - - if (!y || !out) { THROW( YARROW_BAD_ARG ); } - - TRACE( printf( "OUT," ); ); - - /* perform a gate function after Pg outputs */ - - y->out_count++; - if (y->out_count >= y->Pg) - { - y->out_count = 0; - TRY( yarrow_gate_locked( y ) ); - - /* require new seed after reaching gates_limit */ - - y->gate_count++; - if ( y->gate_count >= y->gates_limit ) - { - y->gate_count = 0; - - /* not defined whether to do slow or fast reseed */ - - TRACE( printf( "OUTPUT LIMIT REACHED," ); ); - - TRY( yarrow_reseed_locked( y, YARROW_SLOW_POOL ) ); - } - } - - /* C <- (C + 1) mod 2^n */ - - block_increment( y->C, CIPHER_BLOCK_SIZE ); - - /* R <- E_k(C) */ - - TRY ( krb5int_yarrow_cipher_encrypt_block ( &y->cipher, y->C, out )); - -#if defined(YARROW_DEBUG) - printf("===\n"); - hex_print( stdout, "output: C", y->C, CIPHER_BLOCK_SIZE ); - hex_print( stdout, "output: K", y->K, CIPHER_KEY_SIZE ); - hex_print( stdout, "output: O", out, CIPHER_BLOCK_SIZE ); -#endif -CATCH: - EXCEP_RET; -} - -YARROW_DLL -int krb5int_yarrow_status( Yarrow_CTX* y, int *num_sources, unsigned *source_id, - size_t *entropy_bits, size_t *entropy_max ) -{ - EXCEP_DECL; - int num = y->slow_k_of_n_thresh; - int source = -1; - size_t emax = y->slow_thresh; - size_t entropy = 0; - unsigned i; - - if (!y) { THROW( YARROW_BAD_ARG ); } - TRY( Yarrow_detect_fork( y ) ); - - if (num_sources) { *num_sources = num; } - if (source_id) { *source_id = -1; } - if (entropy_bits) { *entropy_bits = 0; } - if (entropy_max) { *entropy_max = emax; } - - if (y->seeded) - { - if (num_sources) { *num_sources = 0; } - if (entropy_bits) { *entropy_bits = emax; } - THROW( YARROW_OK ); - } - - for (i = 0; i < y->num_sources; i++) - { - if (y->source[i].entropy[YARROW_SLOW_POOL] >= y->slow_thresh) - { - num--; - } - else if (y->source[i].entropy[YARROW_SLOW_POOL] > entropy) - { - source = i; - entropy = y->source[i].entropy[YARROW_SLOW_POOL]; - } - } - - if (num_sources) { *num_sources = num; } - if (source_id) { *source_id = source; } - if (entropy_bits) { *entropy_bits = entropy; } - THROW( YARROW_NOT_SEEDED ); - -CATCH: - EXCEP_RET; -} - -static int yarrow_output_locked(Yarrow_CTX*, void*, size_t); - -YARROW_DLL -int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ) -{ - EXCEP_DECL; - TRY( LOCK() ); - TRY( yarrow_output_locked(y, out, size)); -CATCH: - UNLOCK(); - EXCEP_RET; -} - -static -int yarrow_output_locked( Yarrow_CTX* y, void* out, size_t size ) -{ - EXCEP_DECL; - size_t left; - char* outp; - size_t use; - - if (!y || !out) { THROW( YARROW_BAD_ARG ); } - TRY( Yarrow_detect_fork( y ) ); - - if (!y->seeded) { THROW( YARROW_NOT_SEEDED ); } - - left = size; - outp = out; - - if (y->out_left > 0) - { - use = min(left, y->out_left); - mem_copy(outp, y->out + CIPHER_BLOCK_SIZE - y->out_left, use); - left -= use; - y->out_left -= use; - outp += use; - } - - for ( ; - left >= CIPHER_BLOCK_SIZE; - left -= CIPHER_BLOCK_SIZE, outp += CIPHER_BLOCK_SIZE) - { - TRY( krb5int_yarrow_output_Block(y, outp) ); - } - - if (left > 0) - { - TRY( krb5int_yarrow_output_Block(y, y->out) ); - mem_copy(outp, y->out, left); - y->out_left = CIPHER_BLOCK_SIZE - left; - } - -CATCH: - EXCEP_RET; -} - -static int yarrow_gate_locked(Yarrow_CTX* y) -{ - EXCEP_DECL; - byte new_K[CIPHER_KEY_SIZE]; - - if (!y) { THROW( YARROW_BAD_ARG ); } - - TRACE( printf( "GATE[" ); ); - - /* K <- Next k bits of PRNG output */ - - TRY( yarrow_output_locked(y, new_K, CIPHER_KEY_SIZE) ); - mem_copy(y->K, new_K, CIPHER_KEY_SIZE); - - /* need to resetup the key schedule as the key has changed */ - - TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); - -CATCH: - TRACE( printf( "]," ); ); - mem_zero(new_K, sizeof(new_K)); - EXCEP_RET; -} - -int krb5int_yarrow_gate(Yarrow_CTX* y) -{ - EXCEP_DECL; - byte new_K[CIPHER_KEY_SIZE]; - - if (!y) { THROW( YARROW_BAD_ARG ); } - - TRACE( printf( "GATE[" ); ); - - /* K <- Next k bits of PRNG output */ - - TRY( krb5int_yarrow_output(y, new_K, CIPHER_KEY_SIZE) ); - mem_copy(y->K, new_K, CIPHER_KEY_SIZE); - - /* need to resetup the key schedule as the key has changed */ - - TRY (krb5int_yarrow_cipher_init(&y->cipher, y->K)); - -CATCH: - TRACE( printf( "]," ); ); - mem_zero(new_K, sizeof(new_K)); - EXCEP_RET; -} - -#if defined( YARROW_SAVE_STATE ) -static int Yarrow_Load_State( Yarrow_CTX *y ) -{ - EXCEP_DECL; - Yarrow_STATE state; - - if ( !y ) { THROW( YARROW_BAD_ARG ); } - - if ( y->entropyfile ) - { - TRY( STATE_Load(y->entropyfile, &state) ); - TRACE( printf( "LOAD STATE," ); ); - -#if defined( YARROW_DEBUG ) - hex_print( stderr, "state.load", state.seed, sizeof(state.seed)); -#endif - - /* what to do here is not defined by the Yarrow paper */ - /* this is a place holder until we get some clarification */ - - HASH_Update( &y->pool[YARROW_FAST_POOL], - state.seed, sizeof(state.seed) ); - - Yarrow_Make_Seeded( y ); - - TRY( krb5int_yarrow_reseed(y, YARROW_FAST_POOL) ); - } -CATCH: - mem_zero(state.seed, sizeof(state.seed)); - EXCEP_RET; -} - -static int Yarrow_Save_State( Yarrow_CTX *y ) -{ - EXCEP_DECL; - Yarrow_STATE state; - - if ( !y ) { THROW( YARROW_BAD_ARG ); } - - if ( y->entropyfile && y->seeded ) - { - TRACE( printf( "SAVE STATE[" ); ); - TRY( krb5int_yarrow_output( y, state.seed, sizeof(state.seed) ) ); - TRY( STATE_Save(y->entropyfile, &state) ); - } - y->saved = 1; -# if defined(YARROW_DEBUG) - hex_print(stdout, "state.save", state.seed, sizeof(state.seed)); -# endif - -CATCH: - TRACE( printf( "]," ); ); - mem_zero(state.seed, sizeof(state.seed)); - EXCEP_RET; -} - -#endif - -static int yarrow_reseed_locked(Yarrow_CTX* y, int pool) -{ - EXCEP_DECL; - HASH_CTX* fast_pool; - HASH_CTX* slow_pool; - byte digest[HASH_DIGEST_SIZE]; - HASH_CTX hash; - byte v_0[HASH_DIGEST_SIZE]; - byte v_i[HASH_DIGEST_SIZE]; - krb5_ui_4 big_endian_int32; - COUNTER i; - - k5_assert_locked(&krb5int_yarrow_lock); - if (!y) { THROW( YARROW_BAD_ARG ); } - fast_pool = &y->pool[YARROW_FAST_POOL]; - slow_pool = &y->pool[YARROW_SLOW_POOL]; - if( pool != YARROW_FAST_POOL && pool != YARROW_SLOW_POOL ) - { - THROW( YARROW_BAD_ARG ); - } - - TRACE( printf( "%s RESEED,", - pool == YARROW_SLOW_POOL ? "SLOW" : "FAST" ); ); - - if (pool == YARROW_SLOW_POOL) - { - /* SLOW RESEED */ - - /* feed hash of slow pool into the fast pool */ - - - HASH_Final(slow_pool, digest); - - /* Each pool contains the running hash of all inputs fed into it - * since it was last used to carry out a reseed -- this implies - * that the pool must be reinitialized after a reseed - */ - - HASH_Init(slow_pool); /* reinitialize slow pool */ - HASH_Update(fast_pool, digest, sizeof(digest)); - - if (y->seeded == 0) - { - Yarrow_Make_Seeded( y ); - } - } - - /* step 1. v_0 <- hash of all inputs into fast pool */ - - HASH_Final(fast_pool, &v_0); - HASH_Init(fast_pool); /* reinitialize fast pool */ - - /* v_i <- v_0 */ - - mem_copy( v_i, v_0, sizeof(v_0) ); - - /* step 2. v_i = h(v_{i-1}|v_0|i) for i = 1,..,Pt */ - - /* note: this code has to work for Pt = 0 also */ - - for ( i = 0; i < y->Pt[pool]; i++ ) - { - HASH_Init(&hash); - HASH_Update(&hash, v_i, sizeof(v_i)); - HASH_Update(&hash, v_0, sizeof(v_0)); - big_endian_int32 = make_big_endian32(0); /* MS word */ - HASH_Update(&hash, &big_endian_int32, sizeof(krb5_ui_4)); - big_endian_int32 = make_big_endian32(i & 0xFFFFFFFF); /* LS word */ - HASH_Update(&hash, &big_endian_int32, sizeof(krb5_ui_4)); - HASH_Final(&hash, &v_i); - } - - /* step3. K = h'(h(v_Pt|K)) */ - - /* t = h(v_Pt|K) */ - - HASH_Init(&hash); - HASH_Update(&hash, v_i, sizeof(v_i)); - HASH_Update(&hash, y->K, sizeof(y->K)); - HASH_Final(&hash, v_i); - -#if defined(YARROW_DEBUG) - hex_print(stdout, "old K", y->K, sizeof(y->K)); -#endif - /* K <- h'(t) */ - - TRY( krb5int_yarrow_stretch(v_i, HASH_DIGEST_SIZE, y->K, CIPHER_KEY_SIZE) ); - - /* need to resetup the key schedule as the key has changed */ - - TRY(krb5int_yarrow_cipher_init(&y->cipher, y->K)); - -#if defined(YARROW_DEBUG) - hex_print(stdout, "new K", y->K, sizeof(y->K)); -#endif - - /* step 4. C <- E_k(0) */ - -#if defined(YARROW_DEBUG) - hex_print(stdout, "old C", y->C, sizeof(y->C)); -#endif - TRY (krb5int_yarrow_cipher_encrypt_block (&y->cipher, zero_block, y->C)); -#if defined(YARROW_DEBUG) - hex_print(stdout, "new C", y->C, sizeof(y->C)); -#endif - - /* discard part output from previous key */ - - y->out_left = 0; - - /* step 5. Reset all entropy estimate accumulators of the entropy - * accumulator to zero - */ - - for (i = 0; i < y->num_sources; i++) - { - y->source[i].entropy[pool] = 0; - if (pool == YARROW_SLOW_POOL) - { - /* if this is a slow reseed, reset the fast pool entropy - * accumulator also - */ - y->source[i].entropy[YARROW_FAST_POOL] = 0; - y->source[i].reached_slow_thresh = 0; - } - } - - /* step 7. If a seed file is in use, the next 2k bits of output - * are written to the seed file - */ - -#if defined( YARROW_SAVE_STATE ) - if ( y->seeded && y->entropyfile ) - { - TRY( Yarrow_Save_State( y ) ); - } -#endif - -CATCH: - /* step 6. Wipe the memory of all intermediate values - * - */ - - mem_zero( digest, sizeof(digest) ); - mem_zero( &hash, sizeof(hash) ); - mem_zero( v_0, sizeof(v_0) ); - mem_zero( v_i, sizeof(v_i) ); - - EXCEP_RET; -} -int krb5int_yarrow_reseed(Yarrow_CTX* y, int pool) -{ - int r; - LOCK(); - r = yarrow_reseed_locked(y, pool); - UNLOCK(); - return r; -} - -int krb5int_yarrow_stretch(const byte* m, size_t size, byte* out, size_t out_size) -{ - EXCEP_DECL; - const byte* s_i; - byte* outp; - int left; - unsigned int use; - HASH_CTX hash, save; - byte digest[HASH_DIGEST_SIZE]; - - if (m == NULL || size == 0 || out == NULL || out_size == 0) - { - THROW( YARROW_BAD_ARG ); - } - - /* - * s_0 = m - * s_1 = h(s_0 | ... | s_{i-1}) - * - * h'(m, k) = first k bits of (s_0 | s_1 | ...) - * - */ - - outp = out; - left = out_size; - - use = min(out_size, size); - mem_copy(outp, m, use); /* get k bits or as many as available */ - - s_i = (const byte*)m; /* pointer to s0 = m */ - outp += use; - left -= use; - - HASH_Init(&hash); - for ( ; - left > 0; - left -= HASH_DIGEST_SIZE) - { - HASH_Update(&hash, s_i, use); - - /* have to save hash state to one side as HASH_final changes state */ - - mem_copy(&save, &hash, sizeof(hash)); - HASH_Final(&hash, digest); - - use = min(HASH_DIGEST_SIZE, left); - mem_copy(outp, digest, use); - - /* put state back for next time */ - - mem_copy(&hash, &save, sizeof(hash)); - - s_i = outp; /* retain pointer to s_i */ - outp += use; - } - -CATCH: - mem_zero(&hash, sizeof(hash)); - mem_zero(digest, sizeof(digest)); - - EXCEP_RET; -} - -static void block_increment(void* block, const int sz) -{ - byte* b = block; - int i; - - for (i = sz-1; (++b[i]) == 0 && i > 0; i--) - { - ; /* nothing */ - } -} - -YARROW_DLL -int krb5int_yarrow_final(Yarrow_CTX* y) -{ - EXCEP_DECL; - int locked = 0; - - if (!y) { THROW( YARROW_BAD_ARG ); } - TRY( LOCK() ); - locked = 1; - -#if defined( YARROW_SAVE_STATE ) - if ( y->seeded && y->entropyfile ) - { - TRY( Yarrow_Save_State( y ) ); - } -#endif - -CATCH: - if ( y ) - { - krb5int_yarrow_cipher_final(&y->cipher); - mem_zero( y, sizeof(Yarrow_CTX) ); - } - if ( locked ) { TRY( UNLOCK() ); } - EXCEP_RET; -} - -YARROW_DLL -const char* krb5int_yarrow_str_error( int err ) -{ - err = 1-err; - if ( err < 0 || - (unsigned int) err >= sizeof( yarrow_str_error ) / sizeof( char* ) ) - { - err = 1-YARROW_FAIL; - } - return yarrow_str_error[ err ]; -} - -#if defined(YARROW_DEBUG) -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"); -} -#endif diff --git a/src/lib/crypto/krb/yarrow/yarrow.h b/src/lib/crypto/krb/yarrow/yarrow.h deleted file mode 100644 index 4f7cd5170..000000000 --- a/src/lib/crypto/krb/yarrow/yarrow.h +++ /dev/null @@ -1,186 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -#ifndef YARROW_H -#define YARROW_H - -#ifdef HAVE_UNISTD_H -#define YARROW_DETECT_FORK -#include -#endif -#define YARROW_NO_MATHLIB - -#include "ytypes.h" -#include -#include "ycipher.h" - -/* These error codes are returned by the functions below. */ - -#define YARROW_OK 1 /* All is well */ -#define YARROW_FAIL 0 /* generic failure */ -#define YARROW_NOT_INIT -1 /* YarrowInit hasn't been called */ -#define YARROW_ALREADY_INIT -2 /* YarrowInit has already been called */ -#define YARROW_NO_DRIVER -3 /* driver doesn't exist */ -#define YARROW_CANT_OPEN -4 /* can't open driver */ -#define YARROW_BAD_SOURCE -5 /* invalid source id */ -#define YARROW_TOO_MANY_SOURCES -6 /* can't create any more source ids */ -#define YARROW_BAD_ARG -7 /* invalid argument */ -#define YARROW_ACCESS -8 /* insufficient privileges */ -#define YARROW_NOMEM -9 /* out of memory */ -#define YARROW_NORSRC -10 /* a resource is exhausted */ -#define YARROW_NOT_SEEDED -11 /* not enough entropy to generate output */ -#define YARROW_LOCKING -12 /* locking error */ -#define YARROW_NO_STATE -13 /* there is no state to load */ -#define YARROW_STATE_ERROR -14 /* error with state load or save */ -#define YARROW_NOT_IMPL -15 /* not implemented */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Yarrow implementation and configuration parameters */ - -/* pool identification */ -#define YARROW_FAST_POOL 0 -#define YARROW_SLOW_POOL 1 - -#define YARROW_MAX_SOURCES 20 -#define YARROW_ENTROPY_MULTIPLIER 0.5 - -#define YARROW_POOL_SIZE (HASH_DIGEST_SIZE*8) - -#define YARROW_OUTPUTS_PER_GATE 10 /* Pg */ -#define YARROW_FAST_PT 10 -#define YARROW_SLOW_PT 100 - -/* thresholds to use once seeded */ - -#define YARROW_FAST_THRESH 100 -#define YARROW_SLOW_THRESH 160 -#define YARROW_K_OF_N_THRESH 2 - -/* The Yarrow paper does not specify when the initial seed should be - considered complete. Use the same conditions as a slow reseed */ - -#define YARROW_FAST_INIT_THRESH YARROW_FAST_THRESH -#define YARROW_SLOW_INIT_THRESH YARROW_SLOW_THRESH -#define YARROW_K_OF_N_INIT_THRESH YARROW_K_OF_N_THRESH - -/* sanity checks */ - -#if YARROW_FAST_THRESH > YARROW_POOL_SIZE -error "can't have higher YARROW_FAST_THRESH than pool size" -#endif - -#if YARROW_SLOW_THRESH > YARROW_POOL_SIZE -error "can't have higher YARROW_SLOW_THRESH than pool size" -#endif - -#if YARROW_FAST_INIT_THRESH > YARROW_POOL_SIZE -error "can't have higher YARROW_FAST_INIT_THRESH than pool size" -#endif - -#if YARROW_SLOW_INIT_THRESH > YARROW_POOL_SIZE -error "can't have higher YARROW_SLOW_INIT_THRESH than pool size" -#endif - -typedef size_t estimator_fn(const void* sample, size_t size); - -typedef struct -{ - int pool; - size_t entropy[2]; - int reached_slow_thresh; - estimator_fn* estimator; -} Source; - -typedef struct -{ - /* state */ - int seeded; - int saved; -#if defined( YARROW_DETECT_FORK ) - int pid; -#endif - Source source[YARROW_MAX_SOURCES]; - unsigned num_sources; - HASH_CTX pool[2]; - byte out[CIPHER_BLOCK_SIZE]; - unsigned out_left; - COUNTER out_count; - COUNTER gate_count; - COUNTER gates_limit; - byte C[CIPHER_BLOCK_SIZE]; - CIPHER_CTX cipher; - byte K[CIPHER_KEY_SIZE]; - - const char *entropyfile; - - /* parameters */ - COUNTER Pt[2]; - COUNTER Pg; - int slow_k_of_n; - - /* current thresholds */ - size_t slow_thresh; - size_t fast_thresh; - int slow_k_of_n_thresh; -} Yarrow_CTX; - -# define YARROW_DLL - - -YARROW_DLL -int krb5int_yarrow_init( Yarrow_CTX* y, const char *filename ); - - -YARROW_DLL -int krb5int_yarrow_input( Yarrow_CTX* y, unsigned source_id, - const void* sample, - size_t size, size_t entropy_bits ); - -YARROW_DLL -int krb5int_yarrow_status( Yarrow_CTX* y, int *num_sources, unsigned *source_id, - size_t *entropy_bits, size_t *entropy_max ); - -YARROW_DLL -int krb5int_yarrow_output( Yarrow_CTX* y, void* out, size_t size ); - -YARROW_DLL -int krb5int_yarrow_new_source( Yarrow_CTX* y, unsigned* source_id ); - -YARROW_DLL -int krb5int_yarrow_register_source_estimator( Yarrow_CTX* y, unsigned source_id, - estimator_fn* fptr ); - -YARROW_DLL -int krb5int_yarrow_stretch( const byte* m, size_t size, byte* out, size_t out_size ); - -YARROW_DLL -int krb5int_yarrow_reseed( Yarrow_CTX* y, int pool ); - -YARROW_DLL -int krb5int_yarrow_gate( Yarrow_CTX* y ); - -YARROW_DLL -int krb5int_yarrow_final( Yarrow_CTX* y ); - -YARROW_DLL -const char* krb5int_yarrow_str_error( int ); - - -# define mem_zero(p, n) memset((p), 0, (n)) -# define mem_copy(d, s, n) memcpy((d), (s), (n)) - - -#if !defined(WIN32) -# define min(x, y) ((x) < (y) ? (x) : (y)) -# define max(x, y) ((x) > (y) ? (x) : (y)) -#endif - - - -#ifdef __cplusplus -} -#endif - -#endif /* YARROW_H */ diff --git a/src/lib/crypto/krb/yarrow/yarrow.man b/src/lib/crypto/krb/yarrow/yarrow.man deleted file mode 100644 index a65b4e05c..000000000 --- a/src/lib/crypto/krb/yarrow/yarrow.man +++ /dev/null @@ -1,315 +0,0 @@ -.rn '' }` -''' $RCSfile$$Revision$$Date$ -''' -''' $Log$ -''' Revision 1.1 2001/11/08 21:51:57 hartmans -''' Add Yarrow from http://www.zeroknowledge.com/. -''' -''' This is version 0.1 of their Yarrow implementation. I have flattened the distribution, -''' copying files in the src directory directly into this directory. -''' -''' Revision 1.1.2.1 2000/08/13 21:11:24 adamb -''' added some more assumptions -''' included yarrow.man derived from yarrow.pod with pod2man -''' -''' -.de Sh -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp -.if t .sp .5v -.if n .sp -.. -.de Ip -.br -.ie \\n(.$>=3 .ne \\$3 -.el .ne 3 -.IP "\\$1" \\$2 -.. -.de Vb -.ft CW -.nf -.ne \\$1 -.. -.de Ve -.ft R - -.fi -.. -''' -''' -''' Set up \*(-- to give an unbreakable dash; -''' string Tr holds user defined translation string. -''' Bell System Logo is used as a dummy character. -''' -.tr \(*W-|\(bv\*(Tr -.ie n \{\ -.ds -- \(*W- -.ds PI pi -.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -.ds L" "" -.ds R" "" -''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of -''' \*(L" and \*(R", except that they are used on ".xx" lines, -''' such as .IP and .SH, which do another additional levels of -''' double-quote interpretation -.ds M" """ -.ds S" """ -.ds N" """"" -.ds T" """"" -.ds L' ' -.ds R' ' -.ds M' ' -.ds S' ' -.ds N' ' -.ds T' ' -'br\} -.el\{\ -.ds -- \(em\| -.tr \*(Tr -.ds L" `` -.ds R" '' -.ds M" `` -.ds S" '' -.ds N" `` -.ds T" '' -.ds L' ` -.ds R' ' -.ds M' ` -.ds S' ' -.ds N' ` -.ds T' ' -.ds PI \(*p -'br\} -.\" If the F register is turned on, we'll generate -.\" index entries out stderr for the following things: -.\" TH Title -.\" SH Header -.\" Sh Subsection -.\" Ip Item -.\" X<> Xref (embedded -.\" Of course, you have to process the output yourself -.\" in some meaninful fashion. -.if \nF \{ -.de IX -.tm Index:\\$1\t\\n%\t"\\$2" -.. -.nr % 0 -.rr F -.\} -.TH YARROW 1 "perl 5.005, patch 03" "13/Aug/2000" "User Contributed Perl Documentation" -.UC -.if n .hy 0 -.if n .na -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.de CQ \" put $1 in typewriter font -.ft CW -'if n "\c -'if t \\&\\$1\c -'if n \\&\\$1\c -'if n \&" -\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 -'.ft R -.. -.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 -. \" AM - accent mark definitions -.bd B 3 -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds ? ? -. ds ! ! -. ds / -. ds q -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' -. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] -.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' -.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' -.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -.ds oe o\h'-(\w'o'u*4/10)'e -.ds Oe O\h'-(\w'O'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds v \h'-1'\o'\(aa\(ga' -. ds _ \h'-1'^ -. ds . \h'-1'. -. ds 3 3 -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -. ds oe oe -. ds Oe OE -.\} -.rm #[ #] #H #V #F C -.SH "NAME" -Yarrow_Init, Yarrow_Poll, Yarrow_Input, Yarrow_Status, Yarrow_Output, Yarrow_New_Source, Yarrow_Register_Source_Estimator, Yarrow Final \- cryptographic pseudo-random number generator -.SH "SYNOPSIS" -int \fIYarrow_Init\fR\|(Yarrow_CTX *y, const char *filename); -.PP -int \fIYarrow_New_Source\fR\|(Yarrow_CTX* y, unsigned* source_id); -.PP -int \fIYarrow_Poll\fR\|(Yarrow_CTX *y, unsigned source_id) -.PP -int \fIYarrow_Input\fR\|( Yarrow_CTX* y, unsigned source_id, - const void* sample, size_t size, - size_t entropy_bits); -.PP -int \fIYarrow_Status\fR\|(Yarrow_CTX* y, int *num_sources, - unsigned *source_id, size_t *entropy_bits, - size_t *entropy_max); -.PP -int \fIYarrow_Output\fR\|(Yarrow_CTX* y, void* out, size_t size); -.PP -int \fIYarrow_Register_Source_Estimator\fR\|(Yarrow_CTX* y, - unsigned source_id, - size_t (*estimator)(const void* sample, - size_t size)); -.PP -int \fIYarrow_Final\fR\|(Yarrow_CTX* y); -.SH "DESCRIPTION" -\fIYarrow_Init()\fR initializes a \fBYarrow_CTX\fR structure. \fBfilename\fR can -be NULL, or the path to a seed file that Yarrow will use to store the -PRNG state for use in later sessions. Returns \fBYARROW_OK\fR if the -PRNG is seeded on exit, or \fBYARROW_NOT_SEEDED\fR if the PRNG is not yet -seeded. -.PP -\fIYarrow_New_Source()\fR associates entropy sources such as keyboard input, -mouse movements and other unpredictable events with a -\fBYarrow_CTX\fR. The function assigns a unique number to the new source, -and places it in \fBsource_id\fR. -.PP -\fIYarrow_Poll()\fR gathers entropy from the state of the machine and adds -it to the source \fBsource_id\fR. The source has to be allocated by the -user with Yarrow_New_Source. Returns \fBYARROW_OK\fR if the PRNG is -seeded on exit, or \fBYARROW_NOT_SEEDED\fR if the PRNG is not yet seeded. -.PP -\fIYarrow_Input()\fR is used to add randomness from the source \fBsource_id\fR -to the PRNG. It reads \fBsize\fR bytes at the address \fBsample\fR. An -estimate of the entropy in bits contained in the sample must be -specified as \fBentropy_bits\fR. -.PP -\fIYarrow_Status()\fR returns \fBYARROW_OK\fR if the PRNG has enough entropy to -produce output, and \fBYARROW_NOT_SEEDED\fR if calls to \fIYarrow_Output()\fR -would fail. -.PP -If num_sources is not NULL, the number of entropy sources that still -need to be seeded is returned in \fB*num_sources\fR. -.PP -If source_id is not NULL, the entropy source that is closest to its -threshold is returned in \fB*source_id\fR. \fB*source_id\fR is set to \-1 if -no sources have either reached their threshold or not collected any -entropy yet. -.PP -If not NULL, \fB*entropy_bits\fR is set to the current number of bits for -the source \fB*source_id\fR, and \fB*entropy_max\fR to the threshold. -.PP -\fIYarrow_Output()\fR generates \fBsize\fR bytes of cryptographically strong -pseudo-random output and places them at \fBout\fR. The return value must -always be checked. If an error occurs, the PRNG may produce -predictable data or no output at all. -.PP -\fIYarrow_Register_Source_Estimator()\fR registers an entropy estimator -for \fBsource_id\fR. An entropy estimator is a function that tries to -estimate the entropy in a sample and returns the entropy in bits -in order to detect abnormal situations in which the samples have a very -low entropy. -.PP -\fIYarrow_Final()\fR writes the PRNG state to the seed file and erases it -from memory. -.SH "RETURN VALUES" -All functions return \fBYARROW_OK\fR on success. Error conditions are reported -as follows: -.PP -.Vb 16 -\& YARROW_FAIL generic failure -\& YARROW_NOT_INIT YarrowInit() hasn't been called -\& YARROW_ALREADY_INIT YarrowInit() has already been called -\& YARROW_NO_DRIVER driver doesn't exist -\& YARROW_CANT_OPEN can't open driver -\& YARROW_BAD_SOURCE invalid source id -\& YARROW_TOO_MANY_SOURCES can't create any more source IDs -\& YARROW_BAD_ARG invalid argument -\& YARROW_ACCESS insufficient privileges -\& YARROW_NOMEM out of memory -\& YARROW_NORSRC a resource (apart from memory) is exhausted -\& YARROW_NOT_SEEDED not enough entropy to generate output -\& YARROW_LOCKING locking error -\& YARROW_NO_STATE there is no state to load -\& YARROW_STATE_ERROR error with state load or save -\& YARROW_NOT_IMPL not implemented -.Ve -.SH "AUTHORS" -Yarrow was designed by John Kelsey, Bruce Schneier and Niels Ferguson -of Counterpane Systems. This implementation is (C) 2000 by -Zero-Knowledge Systems Inc. - -.rn }` '' -.IX Title "YARROW 1" -.IX Name "Yarrow_Init, Yarrow_Poll, Yarrow_Input, Yarrow_Status, Yarrow_Output, Yarrow_New_Source, Yarrow_Register_Source_Estimator, Yarrow Final - cryptographic pseudo-random number generator" - -.IX Header "NAME" - -.IX Header "SYNOPSIS" - -.IX Header "DESCRIPTION" - -.IX Header "RETURN VALUES" - -.IX Header "AUTHORS" - diff --git a/src/lib/crypto/krb/yarrow/yarrow.pod b/src/lib/crypto/krb/yarrow/yarrow.pod deleted file mode 100644 index 7892ebbe6..000000000 --- a/src/lib/crypto/krb/yarrow/yarrow.pod +++ /dev/null @@ -1,112 +0,0 @@ -=pod - -=head1 NAME - -Yarrow_Init, Yarrow_Poll, Yarrow_Input, Yarrow_Status, Yarrow_Output, Yarrow_New_Source, Yarrow_Register_Source_Estimator, Yarrow Final - cryptographic pseudo-random number generator - -=head1 SYNOPSIS - -int Yarrow_Init(Yarrow_CTX *y, const char *filename); - -int Yarrow_New_Source(Yarrow_CTX* y, unsigned* source_id); - -int Yarrow_Poll(Yarrow_CTX *y, unsigned source_id) - -int Yarrow_Input( Yarrow_CTX* y, unsigned source_id, - const void* sample, size_t size, - size_t entropy_bits); - -int Yarrow_Status(Yarrow_CTX* y, int *num_sources, - unsigned *source_id, size_t *entropy_bits, - size_t *entropy_max); - -int Yarrow_Output(Yarrow_CTX* y, void* out, size_t size); - -int Yarrow_Register_Source_Estimator(Yarrow_CTX* y, - unsigned source_id, - size_t (*estimator)(const void* sample, - size_t size)); - -int Yarrow_Final(Yarrow_CTX* y); - -=head1 DESCRIPTION - -Yarrow_Init() initializes a B structure. B can -be NULL, or the path to a seed file that Yarrow will use to store the -PRNG state for use in later sessions. Returns B if the -PRNG is seeded on exit, or B if the PRNG is not yet -seeded. - -Yarrow_New_Source() associates entropy sources such as keyboard input, -mouse movements and other unpredictable events with a -B. The function assigns a unique number to the new source, -and places it in B. - -Yarrow_Poll() gathers entropy from the state of the machine and adds -it to the source B. The source has to be allocated by the -user with Yarrow_New_Source. Returns B if the PRNG is -seeded on exit, or B if the PRNG is not yet seeded. - -Yarrow_Input() is used to add randomness from the source B -to the PRNG. It reads B bytes at the address B. An -estimate of the entropy in bits contained in the sample must be -specified as B. - -Yarrow_Status() returns B if the PRNG has enough entropy to -produce output, and B if calls to Yarrow_Output() -would fail. - -If num_sources is not NULL, the number of entropy sources that still -need to be seeded is returned in B<*num_sources>. - -If source_id is not NULL, the entropy source that is closest to its -threshold is returned in B<*source_id>. B<*source_id> is set to -1 if -no sources have either reached their threshold or not collected any -entropy yet. - -If not NULL, B<*entropy_bits> is set to the current number of bits for -the source B<*source_id>, and B<*entropy_max> to the threshold. - -Yarrow_Output() generates B bytes of cryptographically strong -pseudo-random output and places them at B. The return value must -always be checked. If an error occurs, the PRNG may produce -predictable data or no output at all. - -Yarrow_Register_Source_Estimator() registers an entropy estimator -for B. An entropy estimator is a function that tries to -estimate the entropy in a sample and returns the entropy in bits -in order to detect abnormal situations in which the samples have a very -low entropy. - -Yarrow_Final() writes the PRNG state to the seed file and erases it -from memory. - -=head1 RETURN VALUES - -All functions return B on success. Error conditions are reported -as follows: - - YARROW_FAIL generic failure - YARROW_NOT_INIT YarrowInit() hasn't been called - YARROW_ALREADY_INIT YarrowInit() has already been called - YARROW_NO_DRIVER driver doesn't exist - YARROW_CANT_OPEN can't open driver - YARROW_BAD_SOURCE invalid source id - YARROW_TOO_MANY_SOURCES can't create any more source IDs - YARROW_BAD_ARG invalid argument - YARROW_ACCESS insufficient privileges - YARROW_NOMEM out of memory - YARROW_NORSRC a resource (apart from memory) is exhausted - YARROW_NOT_SEEDED not enough entropy to generate output - YARROW_LOCKING locking error - YARROW_NO_STATE there is no state to load - YARROW_STATE_ERROR error with state load or save - YARROW_NOT_IMPL not implemented - -=head1 AUTHORS - -Yarrow was designed by John Kelsey, Bruce Schneier and Niels Ferguson -of Counterpane Systems. This implementation is (C) 2000 by -Zero-Knowledge Systems Inc. - -=cut diff --git a/src/lib/crypto/krb/yarrow/ycipher.c b/src/lib/crypto/krb/yarrow/ycipher.c deleted file mode 100644 index 8a664ac31..000000000 --- a/src/lib/crypto/krb/yarrow/ycipher.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * lib/crypto/yarrow/ycipher.c - * - * Copyright (C) 2001, 2007 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. - * - * - * - * Routines to implement krb5 cipher operations. - */ -#include "k5-int.h" -#include "yarrow.h" -#include "ycipher.h" -#include "enc_provider.h" -#include "assert.h" - -int -krb5int_yarrow_cipher_init(CIPHER_CTX *ctx, unsigned const char * key) -{ - size_t keybytes, keylength; - const struct krb5_enc_provider *enc = &yarrow_enc_provider; - krb5_error_code ret; - krb5_data randombits; - krb5_keyblock keyblock; - - keybytes = enc->keybytes; - keylength = enc->keylength; - assert (keybytes == CIPHER_KEY_SIZE); - krb5_k_free_key(NULL, ctx->key); - ctx->key = NULL; - keyblock.contents = malloc(keylength); - keyblock.length = keylength; - keyblock.enctype = yarrow_enc_type; - if (keyblock.contents == NULL) - return (YARROW_NOMEM); - randombits.data = (char *) key; - randombits.length = keybytes; - ret = enc->make_key(&randombits, &keyblock); - if (ret != 0) - goto cleanup; - ret = krb5_k_create_key(NULL, &keyblock, &ctx->key); -cleanup: - free(keyblock.contents); - if (ret) - return YARROW_FAIL; - return YARROW_OK; -} - -int krb5int_yarrow_cipher_encrypt_block(CIPHER_CTX *ctx, - const unsigned char *in, - unsigned char *out) -{ - krb5_error_code ret; - krb5_crypto_iov iov; - const struct krb5_enc_provider *enc = &yarrow_enc_provider; - - /* - This can happen if ENOMEM in initializing the key - which happens on init or during reseeding - */ - if (!ctx->key) - return YARROW_FAIL; - memcpy(out, in, CIPHER_BLOCK_SIZE); - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = make_data(out, CIPHER_BLOCK_SIZE); - ret = enc->encrypt(ctx->key, 0, &iov, 1); - return (ret == 0) ? YARROW_OK : YARROW_FAIL; -} - -void -krb5int_yarrow_cipher_final(CIPHER_CTX *ctx) -{ - krb5_k_free_key(NULL, ctx->key); - ctx->key = NULL; -} diff --git a/src/lib/crypto/krb/yarrow/ycipher.h b/src/lib/crypto/krb/yarrow/ycipher.h deleted file mode 100644 index 4d7dc9dfd..000000000 --- a/src/lib/crypto/krb/yarrow/ycipher.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -#ifndef YCIPHER_H -#define YCIPHER_H - -/* block cipher interface */ - -typedef struct -{ - krb5_key key; -} CIPHER_CTX; - -/* We need to choose a cipher. To do this, choose an enc_provider. - * Be sure to update the block size and key size constants below; - * they are here because static data structures are sized based on - * them so they must be known at compile time./ Thus we cannot - * call the enc_provider function to get the info. - */ - -#define yarrow_enc_provider krb5int_enc_aes256 -#define yarrow_enc_type ENCTYPE_AES256_CTS_HMAC_SHA1_96 - -#define CIPHER_BLOCK_SIZE 16 -#define CIPHER_KEY_SIZE 32 - -#if defined( YARROW_NO_MATHLIB ) -/* see macros at end for functions evaluated */ -#define POW_CIPHER_KEY_SIZE 115792089237316195423570985008687907853269984665640564039457584007913129639936.0 -#define POW_CIPHER_BLOCK_SIZE 340282366920938463463374607431768211456.0 -#endif - - -int krb5int_yarrow_cipher_init (CIPHER_CTX *ctx, unsigned const char *key); -int krb5int_yarrow_cipher_encrypt_block -(CIPHER_CTX *ctx, const unsigned char *in, unsigned char *out); -void krb5int_yarrow_cipher_final (CIPHER_CTX *ctx); - -#if !defined( YARROW_NO_MATHLIB ) -#define POW_CIPHER_KEY_SIZE pow(2.0, CIPHER_KEY_SIZE * 8 / 3.0) -#define POW_CIPHER_BLOCK_SIZE pow(2.0, CIPHER_BLOCK_SIZE * 8) -#endif - -#endif /* YCIPHER_H */ diff --git a/src/lib/crypto/krb/yarrow/yexcep.h b/src/lib/crypto/krb/yarrow/yexcep.h deleted file mode 100644 index f76f650e0..000000000 --- a/src/lib/crypto/krb/yarrow/yexcep.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -#ifndef YEXCEP_H -#define YEXCEP_H - -/* yes, macros with gotos in them, but in the interests of - * avoiding repetition of code, and having less error prone - * error handling - * - * EXCEP_DECL - declares the return value and local state variables - * needed by the exception macros - * - * THROW( x ) - set return value to x and goto function cleanup - * section (CATCH: block). In the catch block, THROW - * does not goto catch label to avoid loops, and instead - * falls through to the next statement. - * - * EXCEP_OK - success return value (=1) - * - * EXCEP_FAIL - failure return value (=0), other user exceptions are - * given negative values (<0) - * - * TRY( x ) - if code returns value <= 0 TRY sets return value to - * that value and goes to function cleanup section - * (CATCH: block). In the catch block, TRY does not goto - * the catch label to avoid loops, and instead - * falls through to the next statement. The - * return value is set to the first non success value - * returned by a TRY, unless this is overridden by a THROW. - * - * CATCH: - start of catch block, also switches behavior of - * TRY and THROW to not goto CATCH: inside the catch - * block to avoid loops - * - * EXCEP_RET - return the current return value from the function - * equivlanet to return (EXCEPTION) - * - * EXCEPTION - current return value, is set to EXCEP_OK by EXCEP_DECL - * - * EXCEP_BOOL - convert current return value to EXCEP_OK, or EXCEP_FAIL - * (EXCEP_FAIL is anything other than EXCEP_OK) - * - */ - -/* example usage */ - -/* - * - * #define EXCEP_OK_COMMENT 2 - * #define EXCEP_NULL_PTR -1 - * #define EXCEP_OUT_OF_MEM -2 - * - * int bar( char *c ) - * { - * EXCEP_DECL; - * - * if ( !c ) { THROW( EXCEP_NULL_PTR ); } - * if ( *c == '\0' ) { THROW( EXCEP_FAIL ); ); - * if ( *c == '#' ) { SET( EXCEP_COMMENT ); } - * CATCH: - * EXCEP_RET; - * } - * - * int foo( char *c ) - * { - * EXCEP_DECL; - * int *p = NULL; - * - * if ( !c ) { THROW( EXCEP_NULL_PTR ); } - * TRY( bar( c ) ); - * if ( RETURN == EXCEP_COMMENT ) { print( "comment\n" ); } - * p = strdup( c ); - * if ( !p ) { THROW( EXCEP_OUT_OF_MEM ); } - * - * CATCH: - * if ( p ) { TRY( bar( p ) ); free( p ); } - * THROW( EXCEP_BOOL ); - * if ( EXCEPTION == EXCEP_OK ) { printf( "success\n" ); } - * EXCEP_RET; - * } - * - */ - -#define EXCEP_FAIL 0 -#define EXCEP_OK 1 -#define EXCEP_DECL int _thr = 0, _ret2 = 0, _ret = _ret2+EXCEP_OK - -#define THROW( x ) \ - do { \ - _ret = (x); \ - if( !_thr ) { goto _catch; } \ - } while ( 0 ) - -#define TRY( x ) \ - do { \ - _ret2 = (x); \ - if ( _ret > 0 && _ret2 <= 0 ) { THROW( _ret2 ); } \ - } while ( 0 ) - -#define SET( x ) (_ret = (x)) -#define EXCEP_RET return( _ret ) -#define EXCEPTION _ret -#define RETURN _ret2 -#define CATCH _catch: _thr = 1; if ( 0 ) { goto _foo; } _foo -#define EXCEP_BOOL ( _ret > 0 ? EXCEP_OK : EXCEP_FAIL ) - -#endif diff --git a/src/lib/crypto/krb/yarrow/ylock.h b/src/lib/crypto/krb/yarrow/ylock.h deleted file mode 100644 index aacf786af..000000000 --- a/src/lib/crypto/krb/yarrow/ylock.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -#ifndef YLOCK_H -#define YLOCK_H - -#include "yarrow.h" - -/* these functions should return: - * - * YARROW_OK on success - * and YARROW_LOCKING on failure - */ - -#if 0 -static int LOCK( void ) { return (YARROW_OK); } -static int UNLOCK( void ) { return (YARROW_OK); } -#else -#include "k5-thread.h" -extern k5_mutex_t krb5int_yarrow_lock; -#define LOCK() (k5_mutex_lock(&krb5int_yarrow_lock) ? YARROW_LOCKING : YARROW_OK) -#define UNLOCK() (k5_mutex_unlock(&krb5int_yarrow_lock) ? YARROW_LOCKING : YARROW_OK) -#endif - -#endif /* YLOCK_H */ diff --git a/src/lib/crypto/krb/yarrow/ystate.h b/src/lib/crypto/krb/yarrow/ystate.h deleted file mode 100644 index fd277d28a..000000000 --- a/src/lib/crypto/krb/yarrow/ystate.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -#ifndef YSTATE_H -#define YSTATE_H - -#ifdef YARROW_SAVE_STATE - -#include "ycipher.h" -#include "ytypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Yarrow_STATE { - byte seed[CIPHER_KEY_SIZE * 2]; /* 2k bits saved to seed file */ -} Yarrow_STATE; - -int STATE_Save( const char *filename, const struct Yarrow_STATE* state ); -int STATE_Load( const char *filename, struct Yarrow_STATE* state ); - -#ifdef __cplusplus -} -#endif - -#endif /* YARROW_SAVE_STATE */ - -#endif /* YSTATE_H */ diff --git a/src/lib/crypto/krb/yarrow/ytypes.h b/src/lib/crypto/krb/yarrow/ytypes.h deleted file mode 100644 index 9abbf8c9d..000000000 --- a/src/lib/crypto/krb/yarrow/ytypes.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ - -#ifndef YTYPES_H -#define YTYPES_H - -#include -#include -#include "autoconf.h" -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#define byte unsigned char - -#define uint8 unsigned char -#define int8 signed char - - -#if defined(uint64) -# define COUNTER uint64 -#else -# define COUNTER krb5_ui_4 -#endif - -#define COUNTER_MAX ((COUNTER)0 - 1) - -#endif /* YTYPES_H */ diff --git a/src/lib/crypto/nss/Makefile.in b/src/lib/crypto/nss/Makefile.in index f6b457b4a..c50a74a84 100644 --- a/src/lib/crypto/nss/Makefile.in +++ b/src/lib/crypto/nss/Makefile.in @@ -1,11 +1,12 @@ mydir=lib/crypto/nss BUILDTOP=$(REL)..$(S)..$(S).. -SUBDIRS=des aes camellia md4 md5 sha1 enc_provider hash_provider +SUBDIRS=des aes camellia md4 md5 sha1 sha2 enc_provider hash_provider LOCALINCLUDES = -I$(srcdir)/../krb \ -I$(srcdir)/../krb/hash_provider \ -I$(srcdir)/des \ -I$(srcdir)/aes \ -I$(srcdir)/sha1 \ + -I$(srcdir)/sha2 \ -I$(srcdir)/md4 \ -I$(srcdir)/md5 \ -I$(srcdir)/enc_provider \ @@ -35,7 +36,7 @@ SRCS=\ $(srcdir)/pbkdf2.c STOBJLISTS= des/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST sha1/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST \ @@ -43,7 +44,7 @@ STOBJLISTS= des/OBJS.ST md4/OBJS.ST \ OBJS.ST SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST sha1/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST \ @@ -71,6 +72,9 @@ all-windows:: cd ..\sha1 @echo Making in crypto\sha1 $(MAKE) -$(MFLAGS) + cd ..\sha2 + @echo Making in crypto\sh2a + $(MAKE) -$(MFLAGS) cd ..\hash_provider @echo Making in crypto\hash_provider $(MAKE) -$(MFLAGS) @@ -95,6 +99,9 @@ clean-windows:: cd ..\md5 @echo Making clean in crypto\md5 $(MAKE) -$(MFLAGS) clean + cd ..\sha2 + @echo Making clean in crypto\sha2 + $(MAKE) -$(MFLAGS) clean cd ..\sha1 @echo Making clean in crypto\sha1 $(MAKE) -$(MFLAGS) clean @@ -125,6 +132,9 @@ check-windows:: cd ..\sha1 @echo Making check in crypto\sha1 $(MAKE) -$(MFLAGS) check + cd ..\sha2 + @echo Making check in crypto\sha2 + $(MAKE) -$(MFLAGS) check cd ..\hash_provider @echo Making check in crypto\hash_provider $(MAKE) -$(MFLAGS) check diff --git a/src/lib/crypto/openssl/Makefile.in b/src/lib/crypto/openssl/Makefile.in index 6efdbda74..f333c17ab 100644 --- a/src/lib/crypto/openssl/Makefile.in +++ b/src/lib/crypto/openssl/Makefile.in @@ -1,11 +1,12 @@ mydir=lib/crypto/openssl BUILDTOP=$(REL)..$(S)..$(S).. -SUBDIRS=camellia des aes md4 md5 sha1 enc_provider hash_provider +SUBDIRS=camellia des aes md4 md5 sha1 sha2 enc_provider hash_provider LOCALINCLUDES = -I$(srcdir)/../krb \ -I$(srcdir)/../krb/hash_provider \ -I$(srcdir)/des \ -I$(srcdir)/aes \ -I$(srcdir)/sha1 \ + -I$(srcdir)/sha2 \ -I$(srcdir)/md4 \ -I$(srcdir)/md5 \ -I$(srcdir)/enc_provider \ @@ -36,14 +37,14 @@ SRCS=\ $(srcdir)/pbkdf2.c STOBJLISTS= des/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST sha1/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST \ OBJS.ST SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST sha1/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST @@ -70,6 +71,9 @@ all-windows:: cd ..\sha1 @echo Making in crypto\sha1 $(MAKE) -$(MFLAGS) + cd ..\sha2 + @echo Making in crypto\sha2 + $(MAKE) -$(MFLAGS) cd ..\hash_provider @echo Making in crypto\hash_provider $(MAKE) -$(MFLAGS) @@ -94,6 +98,9 @@ clean-windows:: cd ..\sha1 @echo Making clean in crypto\sha1 $(MAKE) -$(MFLAGS) clean + cd ..\sha2 + @echo Making clean in crypto\sha2 + $(MAKE) -$(MFLAGS) clean cd ..\hash_provider @echo Making clean in crypto\hash_provider $(MAKE) -$(MFLAGS) clean diff --git a/src/lib/crypto/openssl/sha2/Makefile.in b/src/lib/crypto/openssl/sha2/Makefile.in new file mode 100644 index 000000000..6a4a27648 --- /dev/null +++ b/src/lib/crypto/openssl/sha2/Makefile.in @@ -0,0 +1,31 @@ +mydir=lib/crypto/openssl/sha2 +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=sha2 +##DOS##OBJFILE=..\$(OUTPRE)sha256.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= sha256.o + +OBJS= $(OUTPRE)sha256.$(OBJEXT) + +SRCS= $(srcdir)/sha256.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/openssl/sha2/deps b/src/lib/crypto/openssl/sha2/deps new file mode 100644 index 000000000..9a63c3313 --- /dev/null +++ b/src/lib/crypto/openssl/sha2/deps @@ -0,0 +1,13 @@ +# +# Generated makefile dependencies follow. +# +sha256.so sha256.po $(OUTPRE)sha256.$(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 sha256.c sha2.h diff --git a/src/lib/crypto/openssl/sha2/sha2.h b/src/lib/crypto/openssl/sha2/sha2.h new file mode 100644 index 000000000..a80fbcb7a --- /dev/null +++ b/src/lib/crypto/openssl/sha2/sha2.h @@ -0,0 +1,42 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * lib/crypto/openssl/sha2/sha2.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 _SHA2_DEFINED + +#include "k5-int.h" +#include +#include + +#define _SHA2_DEFINED + +#define SHA2_DIGESTSIZE 32 + +#define sha2Init SHA256_Init +#define sha2Update SHA256_Update +#define sha2Final SHA256_Final + +#endif /* _SHA2_DEFINED */ diff --git a/src/lib/crypto/openssl/sha2/sha256.c b/src/lib/crypto/openssl/sha2/sha256.c new file mode 100644 index 000000000..c57805203 --- /dev/null +++ b/src/lib/crypto/openssl/sha2/sha256.c @@ -0,0 +1,28 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/sha2/sha256.c + * + * 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 "sha2.h" + diff --git a/src/util/collected-client-lib/Makefile.in b/src/util/collected-client-lib/Makefile.in index d11d77b77..f23f1e5cb 100644 --- a/src/util/collected-client-lib/Makefile.in +++ b/src/util/collected-client-lib/Makefile.in @@ -52,7 +52,8 @@ STOBJLISTS= \ ../../lib/crypto/@CRYPTO_IMPL@/arcfour/OBJS.ST \ ../../lib/crypto/@CRYPTO_IMPL@/aes/OBJS.ST \ ../../lib/crypto/@CRYPTO_IMPL@/camellia/OBJS.ST \ - ../../lib/crypto/krb/yarrow/OBJS.ST \ + ../../lib/crypto/krb/prng/OBJS.ST \ + ../../lib/crypto/krb/prng/@PRNG_ALG@/OBJS.ST \ ../../lib/crypto/krb/OBJS.ST \ ../../lib/crypto/@CRYPTO_IMPL@/OBJS.ST \ ../../lib/crypto/OBJS.ST \ -- cgit