From: Sam Hartman Date: Fri, 16 Nov 2001 15:00:48 +0000 (+0000) Subject: * Link Yarrow into the build X-Git-Tag: krb5-1.3-alpha1~953 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f8207302ef9b1ff8517bb6f528ab4e195b219fc7;p=krb5.git * Link Yarrow into the build * Use Yarrow as the PRNG with the compatibility API * Write most of new PRNG entropy API * Write but (currently) do not use PRNG test harness * Fix Yarrow ciphers not to depend on libkrb5 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13982 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/ChangeLog b/src/ChangeLog index a699a5e1a..d6571cd8e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2001-11-16 Sam Hartman + + * Makefile.in (FILES): Add lib/crypto/yarrow + 2001-10-29 Jeff Altman * Makefile.in - Windows configuration for src/lib/crypto/arcfour diff --git a/src/Makefile.in b/src/Makefile.in index 462c76e54..e72df6d90 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -138,6 +138,7 @@ WINMAKEFILES=Makefile \ lib\crypto\raw\Makefile lib\crypto\old\Makefile \ lib\crypto\sha1\Makefile lib\crypto\arcfour\Makefile \ lib\crypto\md4\Makefile lib\crypto\md5\Makefile \ +lib\crypto\yarrow\Makefile \ lib\des425\Makefile \ lib\gssapi\Makefile lib\gssapi\generic\Makefile \ lib\gssapi\krb5\Makefile lib\gssapi\mechglue\Makefile \ @@ -317,6 +318,7 @@ FILES= ./* \ lib/crypto/enc_provider/* lib/crypto/hash_provider/* \ lib/crypto/keyhash_provider/* lib/crypto/old/* lib/crypto/raw/* \ lib/crypto/sha1/* lib/crypto/arcfour/* lib/crypto/md4/* lib/crypto/md5/* \ +lib/crypto/yarrow/* \ lib/des425/* lib/gssapi/* lib/gssapi/generic/* lib/gssapi/krb5/* \ lib/gssapi/mechglue/* lib/krb4/* \ lib/krb5/* lib/krb5/asn.1/* lib/krb5/krb/* \ diff --git a/src/include/ChangeLog b/src/include/ChangeLog index e1818dde5..9c1f3e6d3 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,12 @@ +2001-11-15 Sam Hartman + + * krb5.hin: Add krb5_c_random_add_entropy and + krb5_c_random_os_entropy + +2001-11-14 Sam Hartman + + * krb5.hin: Added definitions of random sources + 2001-11-06 Sam Hartman * k5-int.h: Add krb5int_des_init_state and krb5int_default_free_state diff --git a/src/include/krb5.hin b/src/include/krb5.hin index 88185c2e9..cd27bdbdc 100644 --- a/src/include/krb5.hin +++ b/src/include/krb5.hin @@ -353,6 +353,27 @@ typedef struct _krb5_enc_data { #define CKSUMTYPE_HMAC_SHA1_DES3 0x000c #define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /*Microsoft md5 hmac cksumtype*/ +/* The following are entropy source designations. Whenever + * krb5_C_random_add_entropy is called, one of these source ids is passed + * in. This allows the library to better estimate bits of + * entropy in the sample and to keep track of what sources of entropy have + * contributed enough entropy. Sources marked internal MUST NOT be + * used by applications outside the Kerberos library +*/ + +enum { + KRB5_C_RANDSOURCE_OLDAPI = 0, /*calls to krb5_C_RANDOM_SEED (INTERNAL)*/ + KRB5_C_RANDSOURCE_OSRAND = 1, /* /dev/random or equivalent (internal)*/ + KRB5_C_RANDSOURCE_TRUSTEDPARTY = 2, /* From KDC or other trusted party*/ + /*This source should be used carefully; data in this category + * should be from a third party trusted to give random bits + * For example keys issued by the KDC in the application server. + */ + KRB5_C_RANDSOURCE_TIMING = 3, /* Timing of operations*/ + KRB5_C_RANDSOURCE_EXTERNAL_PROTOCOL = 4, /*Protocol data possibly from attacker*/ + KRB5_C_RANDSOURCE_MAX = 5 /*Do not use; maximum source ID*/ +}; + #ifndef krb5_roundup /* round x up to nearest multiple of y */ #define krb5_roundup(x, y) ((((x) + (y) - 1)/(y))*(y)) @@ -405,11 +426,33 @@ krb5_error_code KRB5_CALLCONV (krb5_context context, krb5_enctype enctype, krb5_keyblock *k5_random_key); +/* Register a new entropy sample with the PRNG. may cause +* the PRNG to be reseeded, although this is not guaranteed. See previous randsource definitions +* for information on how each source should be used. +*/ +krb5_error_code KRB5_CALLCONV + krb5_c_random_add_entropy +(krb5_context context, unsigned int randsource_id, const krb5_data *data); + + krb5_error_code KRB5_CALLCONV krb5_c_random_make_octets (krb5_context context, krb5_data *data); +/* +* Collect entropy from the OS if possible. strong requests that as strong +* of a source of entropy as available be used. Setting strong may +* increase the probability of blocking and should not be used for normal +* applications. Good uses include seeding the PRNG for kadmind +* and realm setup. +* If successful is non-null, then successful is set to 1 if the OS provided +* entropy else zero. +*/ krb5_error_code KRB5_CALLCONV +krb5_c_random_os_entropy +(krb5_context context, int strong, int *success); + +/*deprecated*/ krb5_error_code KRB5_CALLCONV krb5_c_random_seed (krb5_context context, krb5_data *data); diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index 562fbace3..295728927 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,3 +1,18 @@ +2001-11-15 Sam Hartman + + * t_prng.c: New file for PRNG tests + + * prng.c (krb5_c_random_seed): Deprecated in favor of + krb5_c_random_add_entropy + +2001-11-14 Sam Hartman + + * prng.c : adapt to yarrow + +2001-11-09 Sam Hartman + + * configure.in Makefile.in: Generate makefile for yarrow + 2001-11-07 Ken Raeburn * state.c (krb5_c_init_state, krb5_c_free_state): Use diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index 39f70d8fd..e6b85a825 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -3,10 +3,11 @@ myfulldir=lib/crypto mydir=. BUILDTOP=$(REL)$(U)$(S)$(U) LOCAL_SUBDIRS=crc32 des dk enc_provider hash_provider keyhash_provider \ - md4 md5 old raw sha1 arcfour + md4 md5 old raw sha1 arcfour yarrow LOCALINCLUDES = -I$(srcdir)/enc_provider \ -I$(srcdir)/hash_provider -I$(srcdir)/keyhash_provider \ - -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/dk -I$(srcdir)/arcfour + -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/dk -I$(srcdir)/arcfour \ + -I$(srcdir)/yarrow -I$(srcdir)/sha1 RUN_SETUP = @KRB5_RUN_ENV@ PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) @@ -18,7 +19,7 @@ PROG_RPATH=$(KRB5_LIBDIR) ##DOSOBJFILEDEP =$(OUTPRE)crypto.lst $(OUTPRE)des.lst $(OUTPRE)md4.lst $(OUTPRE)md5.lst $(OUTPRE)sha1.lst $(OUTPRE)arcfour.lst $(OUTPRE)crc32.lst $(OUTPRE)dk.lst $(OUTPRE)old.lst $(OUTPRE)raw.lst $(OUTPRE)enc_prov.lst $(OUTPRE)hash_pro.lst $(OUTPRE)kh_pro.lst MAC_SUBDIRS = crc32 des dk enc_provider hash_provider keyhash_provider \ - md4 md5 old raw sha1 arcfour + md4 md5 old raw sha1 arcfour yarrow PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) @@ -122,6 +123,7 @@ RELDIR=crypto STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ hash_provider/OBJS.ST keyhash_provider/OBJS.ST md4/OBJS.ST \ md5/OBJS.ST old/OBJS.ST raw/OBJS.ST sha1/OBJS.ST arcfour/OBJS.ST \ + yarrow/OBJS.ST \ OBJS.ST # No dependencies. Record places to find this shared object if the target @@ -141,7 +143,7 @@ libcrypto.lib: clean-unix:: clean-liblinks clean-libs clean-libobjs -check-unix:: t_nfold t_encrypt +check-unix:: t_nfold t_encrypt t_prng $(RUN_SETUP) ./t_nfold $(RUN_SETUP) ./t_encrypt @@ -151,6 +153,10 @@ t_nfold$(EXEEXT): t_nfold.$(OBJEXT) nfold.$(OBJEXT) t_encrypt$(EXEEXT): t_encrypt.$(OBJEXT) nfold.$(OBJEXT) $(CC_LINK) -o $@ t_encrypt.$(OBJEXT) -lk5crypto -lcom_err +t_prng$(EXEEXT): t_prng.$(OBJEXT) + $(CC_LINK) -o $@ t_prng.$(OBJEXT) -lk5crypto -lcom_err + + clean:: $(RM) t_nfold.o t_nfold t_encrypt t_encrypt.o diff --git a/src/lib/crypto/configure.in b/src/lib/crypto/configure.in index acfef8d7f..16dda7b6d 100644 --- a/src/lib/crypto/configure.in +++ b/src/lib/crypto/configure.in @@ -5,7 +5,7 @@ AC_PROG_ARCHIVE_ADD AC_PROG_RANLIB AC_PROG_INSTALL -AC_CHECK_HEADERS(memory.h) +AC_CHECK_HEADERS(memory.h unistd.h) KRB5_RUN_FLAGS KRB5_BUILD_PROGRAM @@ -31,4 +31,5 @@ K5_GEN_MAKEFILE(old, libobj) K5_GEN_MAKEFILE(raw, libobj) K5_GEN_MAKEFILE(sha1, libobj) K5_GEN_MAKEFILE(arcfour, libobj) +K5_GEN_MAKEFILE(yarrow, libobj) K5_AC_OUTPUT diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c index 685915d4f..f3a6838bd 100644 --- a/src/lib/crypto/prng.c +++ b/src/lib/crypto/prng.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 1998 by the FundsXpress, INC. - * + * Copyright (C) 2001 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 @@ -13,150 +13,104 @@ * 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 FundsXpress. not be used in advertising or publicity pertaining + * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of + * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "k5-int.h" #include "enc_provider.h" +#include -/* This random number generator is a feedback generator based on a - block cipher. It uses triple-DES by default now, but can be - changed, since everything uses it abstractly. - - As new seed data comes in, the old state is folded with the new - seed into new state. Each time random bytes are requested, the - seed is used as a key and cblock, and the encryption is used as the - output. The output is fed back as new seed data, as described - above. */ - -static const struct krb5_enc_provider *const enc = &krb5int_enc_des3; +#include "yarrow.h" +static Yarrow_CTX y_ctx; +static int inited=0; -/* XXX state. Should it be in krb5_context? */ +/* Helper function to estimate entropy based on sample length + * and where it comes from. + */ -static int inited = 0; -static size_t blocksize, keybytes, keylength; -static unsigned int random_count; -/* keybytes | state-block | encblock | key | new-keybytes | new-state-block */ -static unsigned char *random_state; -#define STATE (random_state) -#define STATEKEY (STATE) -#define STATEBLOCK (STATEKEY+keybytes) -#define STATESIZE (keybytes+blocksize) -#define OUTPUT (STATE) -#define OUTPUTSIZE (STATESIZE+blocksize) -#define RANDBLOCK (STATEBLOCK+blocksize) -#define KEYCONTENTS (RANDBLOCK+blocksize) -#define NEWSTATE (KEYCONTENTS+keylength) -#define ALLSTATESIZE (keybytes+blocksize*2+keylength+keybytes+blocksize) +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); +} krb5_error_code KRB5_CALLCONV -krb5_c_random_seed(krb5_context context, krb5_data *data) +krb5_c_random_add_entropy (krb5_context context, unsigned int randsource, + const krb5_data *data) { - unsigned char *fold_input; - - if (inited == 0) { - /* This does a bunch of malloc'ing up front, so that - generating random keys doesn't have to malloc, so it can't - fail. Seeding still malloc's, but that's less common. */ - - enc->block_size(&blocksize); - enc->keysize(&keybytes, &keylength); - if ((random_state = (unsigned char *) malloc(ALLSTATESIZE)) == NULL) - return(ENOMEM); - random_count = 0; - inited = 1; - - krb5_nfold(data->length*8, (unsigned char *) data->data, - STATESIZE*8, STATE); - - return(0); + int yerr; + + if (inited == 0) { + unsigned i; + 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++ ) { + unsigned source_id; + if (krb5int_yarrow_new_source (&y_ctx, &source_id) != YARROW_OK ) + return KRB5_CRYPTO_INTERNAL; + assert (source_id == i); } - - if ((fold_input = - (unsigned char *) malloc(data->length+STATESIZE)) == NULL) - return(ENOMEM); - - memcpy(fold_input, data->data, data->length); - memcpy(fold_input+data->length, STATE, STATESIZE); - - krb5_nfold((data->length+STATESIZE)*8, fold_input, - STATESIZE*8, STATE); - free(fold_input); - return(0); + inited=1; + + } + 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) +krb5_c_random_seed +(krb5_context context, krb5_data *data) { - krb5_error_code ret; - krb5_data data1, data2; - krb5_keyblock key; - int bytes; - - if (inited == 0) { - /* I need some entropy. I'd use the current time and pid, but - that could cause portability problems. And besides, as an - entropy source, the quality just sucks. */ - abort(); - } - - bytes = 0; - - while (bytes < data->length) { - if (random_count == 0) { - /* set up random krb5_data, and key to be filled in */ - data1.length = keybytes; - data1.data = (char *) STATEKEY; - key.length = keylength; - key.contents = KEYCONTENTS; - - /* fill it in */ - if ((ret = ((*(enc->make_key))(&data1, &key)))) - return(ret); - - /* encrypt the block */ - data1.length = blocksize; - data1.data = (char *) STATEBLOCK; - data2.length = blocksize; - data2.data = (char *) RANDBLOCK; - if ((ret = ((*(enc->encrypt))(&key, NULL, &data1, &data2)))) - return(ret); - - /* Fold the new output back into the state. */ - - krb5_nfold(OUTPUTSIZE*8, OUTPUT, STATESIZE*8, NEWSTATE); - memcpy(STATE, NEWSTATE, STATESIZE); - - random_count = blocksize; - } + return (krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_OLDAPI, data)); +} - if ((data->length - bytes) <= random_count) { - memcpy(data->data + bytes, RANDBLOCK+(blocksize-random_count), - data->length - bytes); - random_count -= (data->length - bytes); - break; - } - memcpy(data->data + bytes, RANDBLOCK+(blocksize - random_count), - random_count); - bytes += random_count; - random_count = 0; +krb5_error_code KRB5_CALLCONV +krb5_c_random_make_octets(krb5_context context, krb5_data *data) +{ + int yerr; + assert (inited); + 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 prng_cleanup (void) { - if (inited) free (random_state); + if (inited) krb5int_yarrow_final (&y_ctx); inited = 0; } diff --git a/src/lib/crypto/t_prng.c b/src/lib/crypto/t_prng.c new file mode 100644 index 000000000..74fc84a9c --- /dev/null +++ b/src/lib/crypto/t_prng.c @@ -0,0 +1,85 @@ +/* + * lib/crypto/t_prng.c + * + * Copyright (C) 2001 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. + * + * This file contains tests for the PRNG code in Kerberos. IT reads + *an input file, and writes an output file. It is assumed that the + *output file will be diffed against expected output to see whether + *regression tests pass. The input file is very primitive format. It + *is composed of alternating seeds and outputs. The first line in + *the file is an integer source Id from the krb5_c_randsource enum in + *krb5.h. Then an integer seed length is be + *read. Then that many bytes (encoded in hex) is read; whitspace or + *newlines may be inserted between bytes. Then after the seed data is + *a integer describing how many bytes of output should be written. + *Then another source ID and seed length is read. If the seed length + *is 0, the source id is ignored and the seed is not seeded. + */ + +#include "k5-int.h" +#include + +int main () { + krb5_error_code ret; + krb5_data input, output; + unsigned int source_id, seed_length; + unsigned int i; + while (1) { + /* Read source*/ + if (scanf ("%u", &source_id ) == EOF ) + break; + /* Read seed length*/ + if (scanf ("%u", &seed_length) == EOF) + break; + if (seed_length ) { + unsigned int lc; + assert ((input.data = malloc(seed_length)) != NULL); + for (lc = seed_length; lc > 0; lc--) { + scanf ("%2x", &i); + input.data[lc] = (unsigned) (i&0xff); + } + input.length = seed_length; + assert (krb5_c_random_add_entropy (0, source_id, &input) == 0); + free (input.data); + input.data = NULL; + } + if (scanf ("%u", &i) == EOF) + break; + assert ((output.data = malloc (i)) != NULL); + output.length = i; + ret = krb5_c_random_make_octets (0, &output); + if (ret) + printf ("failed\n"); + else { + for (; i > 0; i--) { + printf ("%2x", + (unsigned int) ((unsigned char ) output.data[output.length-i])); + } + printf ("\n"); + } + free (output.data); + output.data = NULL; + } + return (0); +} diff --git a/src/lib/crypto/yarrow/ChangeLog b/src/lib/crypto/yarrow/ChangeLog index fad87f165..fdca6742e 100644 --- a/src/lib/crypto/yarrow/ChangeLog +++ b/src/lib/crypto/yarrow/ChangeLog @@ -1,3 +1,7 @@ +2001-11-14 Sam Hartman + + * ycipher.c (krb5int_yarrow_cipher_init): Use free not free_keyblock_contents + 2001-11-09 Sam Hartman * Makefile.in: New file diff --git a/src/lib/crypto/yarrow/ycipher.c b/src/lib/crypto/yarrow/ycipher.c index b2c7a9672..983f7a2a3 100644 --- a/src/lib/crypto/yarrow/ycipher.c +++ b/src/lib/crypto/yarrow/ycipher.c @@ -33,7 +33,8 @@ #include "enc_provider.h" #include "assert.h" -int krb5int_yarrow_cipher_init +int +krb5int_yarrow_cipher_init (CIPHER_CTX *ctx, unsigned const char * key) { @@ -43,8 +44,10 @@ int krb5int_yarrow_cipher_init krb5_data randombits; enc->keysize (&keybytes, &keylength); assert (keybytes == CIPHER_KEY_SIZE); - if (ctx->key.contents) - krb5_free_keyblock_contents (0, &ctx->key); + if (ctx->key.contents) { + memset (ctx->key.contents, 0, ctx->key.length); + free (ctx->key.contents); + } ctx->key.contents = (void *) malloc (keylength); ctx->key.length = keylength; if (ctx->key.contents == NULL) @@ -53,7 +56,9 @@ int krb5int_yarrow_cipher_init randombits.length = keybytes; ret = enc->make_key (&randombits, &ctx->key); if (ret) { - krb5_free_keyblock_contents (0, &ctx->key); + memset (ctx->key.contents, 0, ctx->key.length); + free(ctx->key.contents); + ctx->key.contents = NULL; return (YARROW_FAIL); } return (YARROW_OK);