diff options
| author | Zhanna Tsitkov <tsitkova@mit.edu> | 2009-08-03 14:19:16 +0000 |
|---|---|---|
| committer | Zhanna Tsitkov <tsitkova@mit.edu> | 2009-08-03 14:19:16 +0000 |
| commit | 3c40c7f134b4e87baa43b0cacb435b6f96245e2f (patch) | |
| tree | 2b1014db60c1d3941f17a4d00221e07cc5cece62 /src/lib/crypto/krb | |
| parent | ab7ffb919b4ee5ee5bc07f987d9163202a632e6a (diff) | |
| download | krb5-3c40c7f134b4e87baa43b0cacb435b6f96245e2f.tar.gz krb5-3c40c7f134b4e87baa43b0cacb435b6f96245e2f.tar.xz krb5-3c40c7f134b4e87baa43b0cacb435b6f96245e2f.zip | |
Crypto modularity proj: Separate files under crypto directory based on their functionality. Move Kerberos specific files into krb subdir and MIT specific - into builtin subdir. Place all tests into crypto_tests subfolder.
bigredbutton: whitespace
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22477 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto/krb')
113 files changed, 13079 insertions, 0 deletions
diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in new file mode 100644 index 000000000..887fa160f --- /dev/null +++ b/src/lib/crypto/krb/Makefile.in @@ -0,0 +1,253 @@ +thisconfigdir=../../.. +myfulldir=lib/crypto/krb +mydir=lib/crypto/krb +BUILDTOP=$(REL)..$(S)..$(S).. +SUBDIRS= crc32 dk enc_provider hash_provider keyhash_provider \ + old raw yarrow +LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/enc_provider -I$(srcdir)/dk \ + -I$(srcdir)/hash_provider -I$(srcdir)/keyhash_provider \ + -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/yarrow \ + -I$(srcdir)/../@CRYPTO_IMPL@/ -I$(srcdir)/../@CRYPTO_IMPL@/des \ + -I$(srcdir)/../@CRYPTO_IMPL@/aes -I$(srcdir)/../@CRYPTO_IMPL@/arcfour \ + -I$(srcdir)/../@CRYPTO_IMPL@/sha1 +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) +DEFS= + +##DOSBUILDTOP = ..\..\.. +##DOSLIBNAME=$(OUTPRE)crypto.lib +##DOSOBJFILE=$(OUTPRE)crypto.lst +##DOSOBJFILELIST=@$(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 @$(OUTPRE)yarrow.lst @$(OUTPRE)aes.lst +##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 $(OUTPRE)aes.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS=\ + aead.o \ + block_size.o \ + cf2.o \ + checksum_length.o \ + cksumtype_to_string.o \ + cksumtypes.o \ + coll_proof_cksum.o \ + combine_keys.o \ + crypto_length.o \ + crypto_libinit.o \ + default_state.o \ + decrypt.o \ + decrypt_iov.o \ + encrypt.o \ + encrypt_iov.o \ + encrypt_length.o \ + enctype_compare.o \ + enctype_to_string.o \ + etypes.o \ + keyblocks.o \ + keyed_cksum.o \ + keyed_checksum_types.o \ + keylengths.o \ + make_checksum.o \ + make_checksum_iov.o \ + make_random_key.o \ + mandatory_sumtype.o \ + nfold.o \ + old_api_glue.o \ + prf.o \ + prng.o \ + random_to_key.o \ + state.o \ + string_to_cksumtype.o \ + string_to_enctype.o \ + string_to_key.o \ + valid_cksumtype.o \ + valid_enctype.o \ + verify_checksum.o \ + verify_checksum_iov.o + +OBJS=\ + $(OUTPRE)aead.$(OBJEXT) \ + $(OUTPRE)block_size.$(OBJEXT) \ + $(OUTPRE)cf2$(OBJEXT) \ + $(OUTPRE)checksum_length.$(OBJEXT) \ + $(OUTPRE)cksumtype_to_string.$(OBJEXT) \ + $(OUTPRE)cksumtypes.$(OBJEXT) \ + $(OUTPRE)coll_proof_cksum.$(OBJEXT) \ + $(OUTPRE)combine_keys.$(OBJEXT) \ + $(OUTPRE)crypto_length.$(OBJEXT) \ + $(OUTPRE)crypto_libinit.$(OBJEXT) \ + $(OUTPRE)default_state.$(OBJEXT) \ + $(OUTPRE)decrypt.$(OBJEXT) \ + $(OUTPRE)decrypt_iov.$(OBJEXT) \ + $(OUTPRE)encrypt.$(OBJEXT) \ + $(OUTPRE)encrypt_iov.$(OBJEXT) \ + $(OUTPRE)encrypt_length.$(OBJEXT) \ + $(OUTPRE)enctype_compare.$(OBJEXT) \ + $(OUTPRE)enctype_to_string.$(OBJEXT) \ + $(OUTPRE)etypes.$(OBJEXT) \ + $(OUTPRE)keyblocks.$(OBJEXT) \ + $(OUTPRE)keyed_cksum.$(OBJEXT) \ + $(OUTPRE)keyed_checksum_types.$(OBJEXT) \ + $(OUTPRE)keylengths.$(OBJEXT) \ + $(OUTPRE)make_checksum.$(OBJEXT) \ + $(OUTPRE)make_checksum_iov.$(OBJEXT) \ + $(OUTPRE)make_random_key.$(OBJEXT) \ + $(OUTPRE)mandatory_sumtype.$(OBJEXT) \ + $(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) \ + $(OUTPRE)string_to_enctype.$(OBJEXT) \ + $(OUTPRE)string_to_key.$(OBJEXT) \ + $(OUTPRE)valid_cksumtype.$(OBJEXT) \ + $(OUTPRE)valid_enctype.$(OBJEXT) \ + $(OUTPRE)verify_checksum.$(OBJEXT) \ + $(OUTPRE)verify_checksum_iov.$(OBJEXT) + +SRCS=\ + $(srcdir)/aead.c \ + $(srcdir)/block_size.c \ + $(srcdir)/checksum_length.c \ + $(srcdir)/cksumtype_to_string.c \ + $(srcdir)/cksumtypes.c \ + $(srcdir)/coll_proof_cksum.c \ + $(srcdir)/combine_keys.c \ + $(srcdir)/crypto_length.c \ + $(srcdir)/crypto_libinit.c \ + $(srcdir)/default_state.c \ + $(srcdir)/decrypt.c \ + $(srcdir)/decrypt_iov.c \ + $(srcdir)/encrypt.c \ + $(srcdir)/encrypt_iov.c \ + $(srcdir)/encrypt_length.c \ + $(srcdir)/enctype_compare.c \ + $(srcdir)/enctype_to_string.c \ + $(srcdir)/etypes.c \ + $(srcdir)/keyblocks.c \ + $(srcdir)/keyed_cksum.c \ + $(srcdir)/keyed_checksum_types.c\ + $(srcdir)/keylengths.c \ + $(srcdir)/make_checksum.c \ + $(srcdir)/make_checksum_iov.c \ + $(srcdir)/make_random_key.c \ + $(srcdir)/mandatory_sumtype.c \ + $(srcdir)/nfold.c \ + $(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 \ + $(srcdir)/string_to_enctype.c \ + $(srcdir)/string_to_key.c \ + $(srcdir)/valid_cksumtype.c \ + $(srcdir)/valid_enctype.c \ + $(srcdir)/verify_checksum.c \ + $(srcdir)/verify_checksum_iov.c + +STOBJLISTS=crc32/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ + hash_provider/OBJS.ST keyhash_provider/OBJS.ST \ + old/OBJS.ST raw/OBJS.ST yarrow/OBJS.ST OBJS.ST + +SUBDIROBJLISTS=crc32/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ + hash_provider/OBJS.ST keyhash_provider/OBJS.ST \ + old/OBJS.ST raw/OBJS.ST yarrow/OBJS.ST OBJS.ST + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs + +all-windows:: + cd crc32 + @echo Making in crypto\crc32 + $(MAKE) -$(MFLAGS) + cd ..\dk + @echo Making in crypto\dk + $(MAKE) -$(MFLAGS) + cd ..\enc_provider + @echo Making in crypto\enc_provider + $(MAKE) -$(MFLAGS) + cd ..\hash_provider + @echo Making in crypto\hash_provider + $(MAKE) -$(MFLAGS) + cd ..\keyhash_provider + @echo Making in crypto\keyhash_provider + $(MAKE) -$(MFLAGS) + cd ..\old + @echo Making in crypto\old + $(MAKE) -$(MFLAGS) + cd ..\raw + @echo Making in crypto\raw + $(MAKE) -$(MFLAGS) + cd ..\yarrow + @echo Making in crypto\yarrow + $(MAKE) -$(MFLAGS) + cd .. + +clean-windows:: + cd crc32 + @echo Making in clean crypto\crc32 + $(MAKE) -$(MFLAGS) clean + cd ..\dk + @echo Making clean in crypto\dk + $(MAKE) -$(MFLAGS) clean + cd ..\enc_provider + @echo Making clean in crypto\enc_provider + $(MAKE) -$(MFLAGS) clean + cd ..\hash_provider + @echo Making clean in crypto\hash_provider + $(MAKE) -$(MFLAGS) clean + cd ..\keyhash_provider + @echo Making clean in crypto\keyhash_provider + $(MAKE) -$(MFLAGS) clean + cd ..\old + @echo Making clean in crypto\old + $(MAKE) -$(MFLAGS) clean + cd ..\raw + @echo Making clean in crypto\raw + $(MAKE) -$(MFLAGS) clean + cd ..\yarrow + @echo Making clean in crypto\yarrow + $(MAKE) -$(MFLAGS) clean + cd .. + +check-windows:: + cd crc32 + @echo Making in check crypto\crc32 + $(MAKE) -$(MFLAGS) check + cd ..\dk + @echo Making check in crypto\dk + $(MAKE) -$(MFLAGS) check + cd ..\enc_provider + @echo Making check in crypto\enc_provider + $(MAKE) -$(MFLAGS) check + cd ..\hash_provider + @echo Making check in crypto\hash_provider + $(MAKE) -$(MFLAGS) check + cd ..\keyhash_provider + @echo Making check in crypto\keyhash_provider + $(MAKE) -$(MFLAGS) check + cd ..\md4 + @echo Making check in crypto\old + $(MAKE) -$(MFLAGS) check + cd ..\raw + @echo Making check in crypto\raw + $(MAKE) -$(MFLAGS) check + cd ..\yarrow + @echo Making check in crypto\yarrow + $(MAKE) -$(MFLAGS) check + cd .. + + +@lib_frag@ +@libobj_frag@ + diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c new file mode 100644 index 000000000..2d9a8353a --- /dev/null +++ b/src/lib/crypto/krb/aead.c @@ -0,0 +1,573 @@ +/* + * lib/crypto/aead.c + * + * Copyright 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 "etypes.h" +#include "cksumtypes.h" +#include "dk.h" +#include "aead.h" + +krb5_crypto_iov * +krb5int_c_locate_iov(krb5_crypto_iov *data, + size_t num_data, + krb5_cryptotype type) +{ + size_t i; + krb5_crypto_iov *iov = NULL; + + if (data == NULL) + return NULL; + + for (i = 0; i < num_data; i++) { + if (data[i].flags == type) { + if (iov == NULL) + iov = &data[i]; + else + return NULL; /* can't appear twice */ + } + } + + return iov; +} + +static krb5_error_code +make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output) +{ + krb5_data *sign_data; + size_t num_sign_data; + krb5_error_code ret; + size_t i, j; + + /* Create a checksum over all the data to be signed */ + for (i = 0, num_sign_data = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + num_sign_data++; + } + + /* XXX cleanup to avoid alloc */ + sign_data = (krb5_data *)calloc(num_sign_data, sizeof(krb5_data)); + if (sign_data == NULL) + return ENOMEM; + + for (i = 0, j = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + sign_data[j++] = iov->data; + } + + ret = hash_provider->hash(num_sign_data, sign_data, output); + + free(sign_data); + + return ret; +} + +krb5_error_code +krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *cksum_data) +{ + int e1, e2; + krb5_error_code ret; + + if (cksum_type->keyhash != NULL) { + /* check if key is compatible */ + + if (cksum_type->keyed_etype) { + for (e1=0; e1<krb5_enctypes_length; e1++) + if (krb5_enctypes_list[e1].etype == + cksum_type->keyed_etype) + break; + + for (e2=0; e2<krb5_enctypes_length; e2++) + if (krb5_enctypes_list[e2].etype == key->enctype) + break; + + if ((e1 == krb5_enctypes_length) || + (e2 == krb5_enctypes_length) || + (krb5_enctypes_list[e1].enc != krb5_enctypes_list[e2].enc)) { + ret = KRB5_BAD_ENCTYPE; + goto cleanup; + } + } + + if (cksum_type->keyhash->hash_iov == NULL) { + return KRB5_BAD_ENCTYPE; + } + + ret = (*(cksum_type->keyhash->hash_iov))(key, usage, 0, + data, num_data, cksum_data); + } else if (cksum_type->flags & KRB5_CKSUMFLAG_DERIVE) { + ret = krb5int_dk_make_checksum_iov(cksum_type->hash, + key, usage, data, num_data, + cksum_data); + } else { + ret = make_unkeyed_checksum_iov(cksum_type->hash, data, num_data, + cksum_data); + } + + if (ret == 0) { + if (cksum_type->trunc_size) { + cksum_data->length = cksum_type->trunc_size; + } + } + +cleanup: + if (ret != 0) { + memset(cksum_data->data, 0, cksum_data->length); + } + + return ret; +} + +const struct krb5_cksumtypes * +krb5int_c_find_checksum_type(krb5_cksumtype cksumtype) +{ + size_t i; + + for (i = 0; i < krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) + break; + } + + if (i == krb5_cksumtypes_length) + return NULL; + + return &krb5_cksumtypes_list[i]; +} + +#ifdef DEBUG_IOV +static void +dump_block(const char *tag, + size_t i, + size_t j, + unsigned char *block, + size_t block_size) +{ + size_t k; + + printf("[%s: %d.%d] ", tag, i, j); + + for (k = 0; k < block_size; k++) + printf("%02x ", block[k] & 0xFF); + + printf("\n"); +} +#endif + +static int +process_block_p(const krb5_crypto_iov *data, + size_t num_data, + struct iov_block_state *iov_state, + size_t i) +{ + const krb5_crypto_iov *iov = &data[i]; + int process_block; + + switch (iov->flags) { + case KRB5_CRYPTO_TYPE_SIGN_ONLY: + process_block = iov_state->include_sign_only; + break; + case KRB5_CRYPTO_TYPE_PADDING: + process_block = (iov_state->pad_to_boundary == 0); + break; + case KRB5_CRYPTO_TYPE_HEADER: + process_block = (iov_state->ignore_header == 0); + break; + case KRB5_CRYPTO_TYPE_DATA: + process_block = 1; + break; + default: + process_block = 0; + break; + } + + return process_block; +} + +/* + * Returns TRUE if, having reached the end of the current buffer, + * we should pad the rest of the block with zeros. + */ +static int +pad_to_boundary_p(const krb5_crypto_iov *data, + size_t num_data, + struct iov_block_state *iov_state, + size_t i, + size_t j) +{ + /* If the pad_to_boundary flag is unset, return FALSE */ + if (iov_state->pad_to_boundary == 0) + return 0; + + /* If we haven't got any data, we need to get some */ + if (j == 0) + return 0; + + /* No boundary between adjacent buffers marked for processing */ + if (data[iov_state->iov_pos].flags == data[i].flags) + return 0; + + return 1; +} + +krb5_boolean +krb5int_c_iov_get_block(unsigned char *block, + size_t block_size, + const krb5_crypto_iov *data, + size_t num_data, + struct iov_block_state *iov_state) +{ + size_t i, j = 0; + + for (i = iov_state->iov_pos; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + size_t nbytes; + + if (!process_block_p(data, num_data, iov_state, i)) + continue; + + if (pad_to_boundary_p(data, num_data, iov_state, i, j)) + break; + + iov_state->iov_pos = i; + + nbytes = iov->data.length - iov_state->data_pos; + if (nbytes > block_size - j) + nbytes = block_size - j; + + memcpy(block + j, iov->data.data + iov_state->data_pos, nbytes); + + iov_state->data_pos += nbytes; + j += nbytes; + + assert(j <= block_size); + + if (j == block_size) + break; + + assert(iov_state->data_pos == iov->data.length); + + iov_state->data_pos = 0; + } + + iov_state->iov_pos = i; + + if (j != block_size) + memset(block + j, 0, block_size - j); + +#ifdef DEBUG_IOV + dump_block("get_block", i, j, block, block_size); +#endif + + return (iov_state->iov_pos < num_data); +} + +krb5_boolean +krb5int_c_iov_put_block(const krb5_crypto_iov *data, + size_t num_data, + unsigned char *block, + size_t block_size, + struct iov_block_state *iov_state) +{ + size_t i, j = 0; + + for (i = iov_state->iov_pos; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + size_t nbytes; + + if (!process_block_p(data, num_data, iov_state, i)) + continue; + + if (pad_to_boundary_p(data, num_data, iov_state, i, j)) + break; + + iov_state->iov_pos = i; + + nbytes = iov->data.length - iov_state->data_pos; + if (nbytes > block_size - j) + nbytes = block_size - j; + + memcpy(iov->data.data + iov_state->data_pos, block + j, nbytes); + + iov_state->data_pos += nbytes; + j += nbytes; + + assert(j <= block_size); + + if (j == block_size) + break; + + assert(iov_state->data_pos == iov->data.length); + + iov_state->data_pos = 0; + } + + iov_state->iov_pos = i; + +#ifdef DEBUG_IOV + dump_block("put_block", i, j, block, block_size); +#endif + + return (iov_state->iov_pos < num_data); +} + +krb5_error_code +krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage keyusage, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_error_code ret; + unsigned int header_len, trailer_len, padding_len; + krb5_crypto_iov *iov; + krb5_crypto_iov *stream; + size_t i, j; + int got_data = 0; + + stream = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM); + assert(stream != NULL); + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER, &header_len); + if (ret != 0) + return ret; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &trailer_len); + if (ret != 0) + return ret; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &padding_len); + if (ret != 0) + return ret; + + if (stream->data.length < header_len + trailer_len) + return KRB5_BAD_MSIZE; + + iov = (krb5_crypto_iov *)calloc(num_data + 2, sizeof(krb5_crypto_iov)); + if (iov == NULL) + return ENOMEM; + + i = 0; + + iov[i].flags = KRB5_CRYPTO_TYPE_HEADER; /* takes place of STREAM */ + iov[i].data.data = stream->data.data; + iov[i].data.length = header_len; + i++; + + for (j = 0; j < num_data; j++) { + if (data[j].flags == KRB5_CRYPTO_TYPE_DATA) { + if (got_data) { + free(iov); + return KRB5_BAD_MSIZE; + } + + got_data++; + + data[j].data.data = stream->data.data + header_len; + data[j].data.length = stream->data.length - header_len - trailer_len; + } + if (data[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY || + data[j].flags == KRB5_CRYPTO_TYPE_DATA) + iov[i++] = data[j]; + } + + /* XXX not self-describing with respect to length, this is the best we can do */ + iov[i].flags = KRB5_CRYPTO_TYPE_PADDING; + iov[i].data.data = NULL; + iov[i].data.length = 0; + i++; + + iov[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + iov[i].data.data = stream->data.data + stream->data.length - trailer_len; + iov[i].data.length = trailer_len; + i++; + + assert(i <= num_data + 2); + + ret = aead->decrypt_iov(aead, enc, hash, key, keyusage, ivec, iov, i); + + free(iov); + + return ret; +} + +krb5_error_code +krb5int_c_padding_length(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t data_length, + unsigned int *pad_length) +{ + unsigned int padding; + krb5_error_code ret; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &padding); + if (ret != 0) + return ret; + + if (padding == 0 || (data_length % padding) == 0) + *pad_length = 0; + else + *pad_length = padding - (data_length % padding); + + return 0; +} + +krb5_error_code +krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + krb5_crypto_iov iov[4]; + krb5_error_code ret; + unsigned int header_len = 0; + unsigned int padding_len = 0; + unsigned int trailer_len = 0; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER, + &header_len); + if (ret != 0) + return ret; + + ret = krb5int_c_padding_length(aead, enc, hash, input->length, &padding_len); + if (ret != 0) + return ret; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, + &trailer_len); + if (ret != 0) + return ret; + + if (output->length < header_len + input->length + padding_len + trailer_len) + return KRB5_BAD_MSIZE; + + iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; + iov[0].data.data = output->data; + iov[0].data.length = header_len; + + iov[1].flags = KRB5_CRYPTO_TYPE_DATA; + iov[1].data.data = iov[0].data.data + iov[0].data.length; + iov[1].data.length = input->length; + memcpy(iov[1].data.data, input->data, input->length); + + iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; + iov[2].data.data = iov[1].data.data + iov[1].data.length; + iov[2].data.length = padding_len; + + iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER; + iov[3].data.data = iov[2].data.data + iov[2].data.length; + iov[3].data.length = trailer_len; + + ret = aead->encrypt_iov(aead, enc, hash, key, + usage, ivec, + iov, sizeof(iov)/sizeof(iov[0])); + + if (ret != 0) + zap(iov[1].data.data, iov[1].data.length); + + output->length = iov[0].data.length + iov[1].data.length + + iov[2].data.length + iov[3].data.length; + + return ret; +} + +krb5_error_code +krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + krb5_crypto_iov iov[2]; + krb5_error_code ret; + + iov[0].flags = KRB5_CRYPTO_TYPE_STREAM; + iov[0].data.data = malloc(input->length); + if (iov[0].data.data == NULL) + return ENOMEM; + + memcpy(iov[0].data.data, input->data, input->length); + iov[0].data.length = input->length; + + iov[1].flags = KRB5_CRYPTO_TYPE_DATA; + iov[1].data.data = NULL; + iov[1].data.length = 0; + + ret = krb5int_c_iov_decrypt_stream(aead, enc, hash, key, + usage, ivec, + iov, sizeof(iov)/sizeof(iov[0])); + if (ret != 0) + goto cleanup; + + if (output->length < iov[1].data.length) { + ret = KRB5_BAD_MSIZE; + goto cleanup; + } + + memcpy(output->data, iov[1].data.data, iov[1].data.length); + output->length = iov[1].data.length; + +cleanup: + zap(iov[0].data.data, iov[0].data.length); + free(iov[0].data.data); + + return ret; +} + +void +krb5int_c_encrypt_length_aead_compat(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length) +{ + unsigned int header_len = 0; + unsigned int padding_len = 0; + unsigned int trailer_len = 0; + + aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER, &header_len); + krb5int_c_padding_length(aead, enc, hash, inputlen, &padding_len); + aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &trailer_len); + + *length = header_len + inputlen + padding_len + trailer_len; +} + diff --git a/src/lib/crypto/krb/aead.h b/src/lib/crypto/krb/aead.h new file mode 100644 index 000000000..2c99eb868 --- /dev/null +++ b/src/lib/crypto/krb/aead.h @@ -0,0 +1,123 @@ +/* + * lib/crypto/aead.h + * + * Copyright 2008, 2009 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 "cksumtypes.h" + +/* AEAD helpers */ + +krb5_crypto_iov * +krb5int_c_locate_iov(krb5_crypto_iov *data, + size_t num_data, + krb5_cryptotype type); + +krb5_error_code +krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *cksum_data); + +const struct krb5_cksumtypes * +krb5int_c_find_checksum_type(krb5_cksumtype cksumtype); + +#define ENCRYPT_CONF_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER) + +#define ENCRYPT_DATA_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \ + (_iov)->flags == KRB5_CRYPTO_TYPE_PADDING) + +#define ENCRYPT_IOV(_iov) (ENCRYPT_CONF_IOV(_iov) || ENCRYPT_DATA_IOV(_iov)) + +#define SIGN_IOV(_iov) (ENCRYPT_IOV(_iov) || \ + (_iov)->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY ) + +struct iov_block_state { + size_t iov_pos; /* index into iov array */ + size_t data_pos; /* index into iov contents */ + unsigned int ignore_header : 1; /* have/should we process HEADER */ + unsigned int include_sign_only : 1; /* should we process SIGN_ONLY blocks */ + unsigned int pad_to_boundary : 1; /* should we zero fill blocks until next buffer */ +}; + +#define IOV_BLOCK_STATE_INIT(_state) ((_state)->iov_pos = \ + (_state)->data_pos = \ + (_state)->ignore_header = \ + (_state)->include_sign_only = \ + (_state)->pad_to_boundary = 0) + +krb5_boolean +krb5int_c_iov_get_block(unsigned char *block, + size_t block_size, + const krb5_crypto_iov *data, + size_t num_data, + struct iov_block_state *iov_state); + +krb5_boolean +krb5int_c_iov_put_block(const krb5_crypto_iov *data, + size_t num_data, + unsigned char *block, + size_t block_size, + struct iov_block_state *iov_state); + +krb5_error_code +krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage keyusage, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data); + +krb5_error_code +krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output); + +krb5_error_code +krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output); + +void +krb5int_c_encrypt_length_aead_compat(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length); + +krb5_error_code +krb5int_c_padding_length(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t data_length, + unsigned int *pad_length); diff --git a/src/lib/crypto/krb/block_size.c b/src/lib/crypto/krb/block_size.c new file mode 100644 index 000000000..e4c11e869 --- /dev/null +++ b/src/lib/crypto/krb/block_size.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_block_size(krb5_context context, krb5_enctype enctype, + size_t *blocksize) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + *blocksize = krb5_enctypes_list[i].enc->block_size; + + return(0); +} diff --git a/src/lib/crypto/krb/cf2.c b/src/lib/crypto/krb/cf2.c new file mode 100644 index 000000000..4e25641e8 --- /dev/null +++ b/src/lib/crypto/krb/cf2.c @@ -0,0 +1,154 @@ +/* + * lib/crypto/cf2.c + * + * Copyright (C) 2009 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. + * + * + * + * Implement KRB_FX_CF2 function per + *draft-ietf-krb-wg-preauth-framework-09. Take two keys and two + *pepper strings as input and return a combined key. + */ + +#include <k5-int.h> +#include <assert.h> +#include "etypes.h" + + +/* + * Call the PRF function multiple times with the pepper prefixed with + * a count byte to get enough bits of output. + */ +static krb5_error_code +prf_plus( krb5_context context, krb5_keyblock *k,const char *pepper, + size_t keybytes, char **out) +{ + krb5_error_code retval = 0; + size_t prflen, iterations; + krb5_data out_data; + krb5_data in_data; + char *buffer = NULL; + struct k5buf prf_inbuf; + krb5int_buf_init_dynamic(&prf_inbuf); + krb5int_buf_add_len( &prf_inbuf, "\001", 1); + krb5int_buf_add( &prf_inbuf, pepper); + retval = krb5_c_prf_length( context, k->enctype, &prflen); + if (retval != 0) + goto cleanup; + iterations = keybytes/prflen; + if ((keybytes%prflen) != 0) + iterations++; + assert(iterations <= 254); + buffer = malloc(iterations*prflen); + if (buffer == NULL) { + retval = ENOMEM; + goto cleanup; + } + if (krb5int_buf_len( &prf_inbuf) == -1) { + retval = ENOMEM; + goto cleanup; + } + in_data.length = (krb5_int32) krb5int_buf_len( &prf_inbuf); + in_data.data = krb5int_buf_data( &prf_inbuf); + out_data.length = prflen; + out_data.data = buffer; + + while (iterations > 0) { + retval = krb5_c_prf( context, k, &in_data, &out_data); + if (retval != 0) + goto cleanup; + out_data.data += prflen; + in_data.data[0]++; + iterations--; + } + cleanup: + if (retval == 0 ) + *out = buffer; + else{ + if (buffer != NULL) + free(buffer); + } + krb5int_free_buf( &prf_inbuf); + return retval; +} + + +krb5_error_code KRB5_CALLCONV +krb5_c_fx_cf2_simple(krb5_context context, + krb5_keyblock *k1, const char *pepper1, + krb5_keyblock *k2, const char *pepper2, + krb5_keyblock **out) +{ + const struct krb5_keytypes *out_enctype; + size_t keybytes, keylength, i; + char *prf1 = NULL, *prf2 = NULL; + krb5_data keydata; + krb5_enctype out_enctype_num; + krb5_error_code retval = 0; + krb5_keyblock *out_key = NULL; + + + if (k1 == NULL ||!krb5_c_valid_enctype(k1->enctype)) + return KRB5_BAD_ENCTYPE; + if (k2 == NULL || !krb5_c_valid_enctype(k2->enctype)) + return KRB5_BAD_ENCTYPE; + out_enctype_num = k1->enctype; + assert(out != NULL); + assert ((out_enctype = find_enctype(out_enctype_num)) != NULL); + if (out_enctype->prf == NULL) { + if (context) + krb5int_set_error(&(context->err) , KRB5_CRYPTO_INTERNAL, + "Enctype %d has no PRF", out_enctype_num); + return KRB5_CRYPTO_INTERNAL; + } + keybytes = out_enctype->enc->keybytes; + keylength = out_enctype->enc->keylength; + + retval = prf_plus( context, k1, pepper1, keybytes, &prf1); + if (retval != 0) + goto cleanup; + retval = prf_plus( context, k2, pepper2, keybytes, &prf2); + if (retval != 0) + goto cleanup; + for (i = 0; i < keybytes; i++) + prf1[i] ^= prf2[i]; + zap(prf2, keybytes); + retval = krb5int_c_init_keyblock( context, out_enctype_num, keylength, &out_key); + if (retval != 0) + goto cleanup; + keydata.data = prf1; + keydata.length = keybytes; + retval = out_enctype->enc->make_key( &keydata, out_key); + + cleanup: + if (retval == 0) + *out = out_key; + else krb5int_c_free_keyblock( context, out_key); + if (prf1 != NULL) { + zap(prf1, keybytes); + free(prf1); + } + if (prf2 != NULL) + free(prf2); + return retval; +} diff --git a/src/lib/crypto/krb/checksum_length.c b/src/lib/crypto/krb/checksum_length.c new file mode 100644 index 000000000..28846a671 --- /dev/null +++ b/src/lib/crypto/krb/checksum_length.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype, + size_t *length) +{ + unsigned int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + if (krb5_cksumtypes_list[i].keyhash) + *length = krb5_cksumtypes_list[i].keyhash->hashsize; + else if (krb5_cksumtypes_list[i].trunc_size) + *length = krb5_cksumtypes_list[i].trunc_size; + else + *length = krb5_cksumtypes_list[i].hash->hashsize; + + return(0); +} + diff --git a/src/lib/crypto/krb/cksumtype_to_string.c b/src/lib/crypto/krb/cksumtype_to_string.c new file mode 100644 index 000000000..ee1d50ba5 --- /dev/null +++ b/src/lib/crypto/krb/cksumtype_to_string.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_cksumtype_to_string(krb5_cksumtype cksumtype, char *buffer, size_t buflen) +{ + unsigned int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) { + if (strlcpy(buffer, krb5_cksumtypes_list[i].out_string, + buflen) >= buflen) + return(ENOMEM); + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/krb/cksumtypes.c b/src/lib/crypto/krb/cksumtypes.c new file mode 100644 index 000000000..037e53f49 --- /dev/null +++ b/src/lib/crypto/krb/cksumtypes.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "hash_provider.h" +#include "keyhash_provider.h" +#include "cksumtypes.h" + +const struct krb5_cksumtypes krb5_cksumtypes_list[] = { + { CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF, + "crc32", { 0 }, "CRC-32", + 0, NULL, + &krb5int_hash_crc32 }, + + { CKSUMTYPE_RSA_MD4, 0, + "md4", { 0 }, "RSA-MD4", + 0, NULL, + &krb5int_hash_md4 }, + { CKSUMTYPE_RSA_MD4_DES, 0, + "md4-des", { 0 }, "RSA-MD4 with DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md4des, + NULL }, + + { CKSUMTYPE_DESCBC, 0, + "des-cbc", { 0 }, "DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_descbc, + NULL }, + + { CKSUMTYPE_RSA_MD5, 0, + "md5", { 0 }, "RSA-MD5", + 0, NULL, + &krb5int_hash_md5 }, + { CKSUMTYPE_RSA_MD5_DES, 0, + "md5-des", { 0 }, "RSA-MD5 with DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md5des, + NULL }, + + { CKSUMTYPE_NIST_SHA, 0, + "sha", { 0 }, "NIST-SHA", + 0, NULL, + &krb5int_hash_sha1 }, + + { CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE, + "hmac-sha1-des3", { "hmac-sha1-des3-kd" }, "HMAC-SHA1 DES3 key", + 0, NULL, + &krb5int_hash_sha1 }, + { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0, + "hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" }, + "Microsoft HMAC MD5 (RC4 key)", + ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, + NULL }, + + { CKSUMTYPE_HMAC_SHA1_96_AES128, KRB5_CKSUMFLAG_DERIVE, + "hmac-sha1-96-aes128", { 0 }, "HMAC-SHA1 AES128 key", + 0, NULL, + &krb5int_hash_sha1, 12 }, + { CKSUMTYPE_HMAC_SHA1_96_AES256, KRB5_CKSUMFLAG_DERIVE, + "hmac-sha1-96-aes256", { 0 }, "HMAC-SHA1 AES256 key", + 0, NULL, + &krb5int_hash_sha1, 12 }, + { CKSUMTYPE_MD5_HMAC_ARCFOUR, 0, + "md5-hmac-rc4", { 0 }, "Microsoft MD5 HMAC (RC4 key)", + ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_md5_hmac, + NULL } +}; + +const unsigned int krb5_cksumtypes_length = +sizeof(krb5_cksumtypes_list)/sizeof(struct krb5_cksumtypes); diff --git a/src/lib/crypto/krb/cksumtypes.h b/src/lib/crypto/krb/cksumtypes.h new file mode 100644 index 000000000..c667e8abe --- /dev/null +++ b/src/lib/crypto/krb/cksumtypes.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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. + */ + +#ifndef CKSUMTYPES_H +#define CKSUMTYPES_H +#include "k5-int.h" + +struct krb5_cksumtypes { + krb5_cksumtype ctype; + unsigned int flags; + char *name; + char *aliases[2]; + char *out_string; + /* if the hash is keyed, this is the etype it is keyed with. + Actually, it can be keyed by any etype which has the same + enc_provider as the specified etype. DERIVE checksums can + be keyed with any valid etype. */ + krb5_enctype keyed_etype; + /* I can't statically initialize a union, so I'm just going to use + two pointers here. The keyhash is used if non-NULL. If NULL, + then HMAC/hash with derived keys is used if the relevant flag + is set. Otherwise, a non-keyed hash is computed. This is all + kind of messy, but so is the krb5 api. */ + const struct krb5_keyhash_provider *keyhash; + const struct krb5_hash_provider *hash; + /* This just gets uglier and uglier. In the key derivation case, + we produce an hmac. To make the hmac code work, we can't hack + the output size indicated by the hash provider, but we may want + a truncated hmac. If we want truncation, this is the number of + bytes we truncate to; it should be 0 otherwise. */ + unsigned int trunc_size; +}; + +#define KRB5_CKSUMFLAG_DERIVE 0x0001 +#define KRB5_CKSUMFLAG_NOT_COLL_PROOF 0x0002 + +extern const struct krb5_cksumtypes krb5_cksumtypes_list[]; +extern const unsigned int krb5_cksumtypes_length; +#endif diff --git a/src/lib/crypto/krb/coll_proof_cksum.c b/src/lib/crypto/krb/coll_proof_cksum.c new file mode 100644 index 000000000..85fb57b9b --- /dev/null +++ b/src/lib/crypto/krb/coll_proof_cksum.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_boolean KRB5_CALLCONV +krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype) +{ + unsigned int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == ctype) + return((krb5_cksumtypes_list[i].flags & + KRB5_CKSUMFLAG_NOT_COLL_PROOF)?0:1); + } + + /* ick, but it's better than coredumping, which is what the + old code would have done */ + return(0); +} + +krb5_boolean KRB5_CALLCONV +is_coll_proof_cksum(krb5_cksumtype ctype) +{ + return krb5_c_is_coll_proof_cksum (ctype); +} diff --git a/src/lib/crypto/krb/combine_keys.c b/src/lib/crypto/krb/combine_keys.c new file mode 100644 index 000000000..3d9765164 --- /dev/null +++ b/src/lib/crypto/krb/combine_keys.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2002 Naval Research Laboratory (NRL/CCS) + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the software, + * derivative works or modified versions, and any portions thereof. + * + * NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER + * RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Key combination function. + * + * If Key1 and Key2 are two keys to be combined, the algorithm to combine + * them is as follows. + * + * Definitions: + * + * k-truncate is defined as truncating to the key size the input. + * + * DR is defined as the generate "random" data from a key + * (defined in crypto draft) + * + * DK is defined as the key derivation function (krb5_derive_key()) + * + * (note: | means "concatenate") + * + * Combine key algorithm: + * + * R1 = DR(Key1, n-fold(Key2)) [ Output is length of Key1 ] + * R2 = DR(Key2, n-fold(Key1)) [ Output is length of Key2 ] + * + * rnd = n-fold(R1 | R2) [ Note: output size of nfold must be appropriately + * sized for random-to-key function ] + * tkey = random-to-key(rnd) + * Combine-Key(Key1, Key2) = DK(tkey, CombineConstant) + * + * CombineConstant is defined as the byte string: + * + * { 0x63 0x6f 0x6d 0x62 0x69 0x6e 0x65 }, which corresponds to the + * ASCII encoding of the string "combine" + */ + +#include "k5-int.h" +#include "etypes.h" +#include "dk.h" + +static krb5_error_code dr +(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey, + unsigned char *outdata, const krb5_data *in_constant); + +/* + * We only support this combine_keys algorithm for des and 3des keys. + * Everything else should use the PRF defined in the crypto framework. + * We don't implement that yet. + */ + +static krb5_boolean enctype_ok (krb5_enctype e) +{ + switch (e) { + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES3_CBC_SHA1: + return 1; + default: + return 0; + } +} + +krb5_error_code krb5int_c_combine_keys +(krb5_context context, krb5_keyblock *key1, krb5_keyblock *key2, krb5_keyblock *outkey) +{ + unsigned char *r1, *r2, *combined, *rnd, *output; + size_t keybytes, keylength; + const struct krb5_enc_provider *enc; + krb5_data input, randbits; + krb5_keyblock tkey; + krb5_error_code ret; + int i, myalloc = 0; + if (!(enctype_ok(key1->enctype)&&enctype_ok(key2->enctype))) + return (KRB5_CRYPTO_INTERNAL); + + + if (key1->length != key2->length || key1->enctype != key2->enctype) + return (KRB5_CRYPTO_INTERNAL); + + /* + * Find our encryption algorithm + */ + + for (i = 0; i < krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key1->enctype) + break; + } + + if (i == krb5_enctypes_length) + return (KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + keybytes = enc->keybytes; + keylength = enc->keylength; + + /* + * Allocate and set up buffers + */ + + if ((r1 = (unsigned char *) malloc(keybytes)) == NULL) + return (ENOMEM); + + if ((r2 = (unsigned char *) malloc(keybytes)) == NULL) { + free(r1); + return (ENOMEM); + } + + if ((rnd = (unsigned char *) malloc(keybytes)) == NULL) { + free(r1); + free(r2); + return (ENOMEM); + } + + if ((combined = (unsigned char *) malloc(keybytes * 2)) == NULL) { + free(r1); + free(r2); + free(rnd); + return (ENOMEM); + } + + if ((output = (unsigned char *) malloc(keylength)) == NULL) { + free(r1); + free(r2); + free(rnd); + free(combined); + return (ENOMEM); + } + + /* + * Get R1 and R2 (by running the input keys through the DR algorithm. + * Note this is most of derive-key, but not all. + */ + + input.length = key2->length; + input.data = (char *) key2->contents; + if ((ret = dr(enc, key1, r1, &input))) + goto cleanup; + +#if 0 + { + int i; + printf("R1 ="); + for (i = 0; i < keybytes; i++) + printf(" %02x", (unsigned char) r1[i]); + printf("\n"); + } +#endif + + input.length = key1->length; + input.data = (char *) key1->contents; + if ((ret = dr(enc, key2, r2, &input))) + goto cleanup; + +#if 0 + { + int i; + printf("R2 ="); + for (i = 0; i < keybytes; i++) + printf(" %02x", (unsigned char) r2[i]); + printf("\n"); + } +#endif + + /* + * Concatenate the two keys together, and then run them through + * n-fold to reduce them to a length appropriate for the random-to-key + * operation. Note here that krb5_nfold() takes sizes in bits, hence + * the multiply by 8. + */ + + memcpy(combined, r1, keybytes); + memcpy(combined + keybytes, r2, keybytes); + + krb5_nfold((keybytes * 2) * 8, combined, keybytes * 8, rnd); + +#if 0 + { + int i; + printf("rnd ="); + for (i = 0; i < keybytes; i++) + printf(" %02x", (unsigned char) rnd[i]); + printf("\n"); + } +#endif + + /* + * Run the "random" bits through random-to-key to produce a encryption + * key. + */ + + randbits.length = keybytes; + randbits.data = (char *) rnd; + tkey.length = keylength; + tkey.contents = output; + + if ((ret = (*(enc->make_key))(&randbits, &tkey))) + goto cleanup; + +#if 0 + { + int i; + printf("tkey ="); + for (i = 0; i < tkey.length; i++) + printf(" %02x", (unsigned char) tkey.contents[i]); + printf("\n"); + } +#endif + + /* + * Run through derive-key one more time to produce the final key. + * Note that the input to derive-key is the ASCII string "combine". + */ + + input.length = 7; /* Note; change this if string length changes */ + input.data = "combine"; + + /* + * Just FYI: _if_ we have space here in the key, then simply use it + * without modification. But if the key is blank (no allocated storage) + * then allocate some memory for it. This allows programs to use one of + * the existing keys as the output key, _or_ pass in a blank keyblock + * for us to allocate. It's easier for us to allocate it since we already + * know the crypto library internals + */ + + if (outkey->length == 0 || outkey->contents == NULL) { + outkey->contents = (krb5_octet *) malloc(keylength); + if (!outkey->contents) { + ret = ENOMEM; + goto cleanup; + } + outkey->length = keylength; + outkey->enctype = key1->enctype; + myalloc = 1; + } + + if ((ret = krb5_derive_key(enc, &tkey, outkey, &input))) { + if (myalloc) { + free(outkey->contents); + outkey->contents = NULL; + } + goto cleanup; + } + +#if 0 + { + int i; + printf("output ="); + for (i = 0; i < outkey->length; i++) + printf(" %02x", (unsigned char) outkey->contents[i]); + printf("\n"); + } +#endif + + ret = 0; + +cleanup: + memset(r1, 0, keybytes); + memset(r2, 0, keybytes); + memset(rnd, 0, keybytes); + memset(combined, 0, keybytes * 2); + memset(output, 0, keylength); + + free(r1); + free(r2); + free(rnd); + free(combined); + free(output); + + return (ret); +} + +/* + * Our DR function; mostly taken from derive.c + */ + +static krb5_error_code dr +(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey, unsigned char *out, const krb5_data *in_constant) +{ + size_t blocksize, keybytes, keylength, n; + unsigned char *inblockdata, *outblockdata; + krb5_data inblock, outblock; + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + + /* allocate and set up buffers */ + + if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL) + return(ENOMEM); + + if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { + free(inblockdata); + return(ENOMEM); + } + + inblock.data = (char *) inblockdata; + inblock.length = blocksize; + + outblock.data = (char *) outblockdata; + outblock.length = blocksize; + + /* initialize the input block */ + + if (in_constant->length == inblock.length) { + memcpy(inblock.data, in_constant->data, inblock.length); + } else { + krb5_nfold(in_constant->length*8, (unsigned char *) in_constant->data, + inblock.length*8, (unsigned char *) inblock.data); + } + + /* loop encrypting the blocks until enough key bytes are generated */ + + n = 0; + while (n < keybytes) { + (*(enc->encrypt))(inkey, 0, &inblock, &outblock); + + if ((keybytes - n) <= outblock.length) { + memcpy(out+n, outblock.data, (keybytes - n)); + break; + } + + memcpy(out+n, outblock.data, outblock.length); + memcpy(inblock.data, outblock.data, outblock.length); + n += outblock.length; + } + + /* clean memory, free resources and exit */ + + memset(inblockdata, 0, blocksize); + memset(outblockdata, 0, blocksize); + + free(outblockdata); + free(inblockdata); + + return(0); +} + diff --git a/src/lib/crypto/krb/crc32/CRC.pm b/src/lib/crypto/krb/crc32/CRC.pm new file mode 100644 index 000000000..ee2ab2ae8 --- /dev/null +++ b/src/lib/crypto/krb/crc32/CRC.pm @@ -0,0 +1,156 @@ +# Copyright 2002 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. + +package CRC; + +# CRC: implement a CRC using the Poly package (yes this is slow) +# +# message M(x) = m_0 * x^0 + m_1 * x^1 + ... + m_(k-1) * x^(k-1) +# generator P(x) = p_0 * x^0 + p_1 * x^1 + ... + p_n * x^n +# remainder R(x) = r_0 * x^0 + r_1 * x^1 + ... + r_(n-1) * x^(n-1) +# +# R(x) = (x^n * M(x)) % P(x) +# +# Note that if F(x) = x^n * M(x) + R(x), then F(x) = 0 mod P(x) . +# +# In MIT Kerberos 5, R(x) is taken as the CRC, as opposed to what +# ISO 3309 does. +# +# ISO 3309 adds a precomplement and a postcomplement. +# +# The ISO 3309 postcomplement is of the form +# +# A(x) = x^0 + x^1 + ... + x^(n-1) . +# +# The ISO 3309 precomplement is of the form +# +# B(x) = x^k * A(x) . +# +# The ISO 3309 FCS is then +# +# (x^n * M(x)) % P(x) + B(x) % P(x) + A(x) , +# +# which is equivalent to +# +# (x^n * M(x) + B(x)) % P(x) + A(x) . +# +# In ISO 3309, the transmitted frame is +# +# F'(x) = x^n * M(x) + R(x) + R'(x) + A(x) , +# +# where +# +# R'(x) = B(x) % P(x) . +# +# Note that this means that if a new remainder is computed over the +# frame F'(x) (treating F'(x) as the new M(x)), it will be equal to a +# constant. +# +# F'(x) = 0 + R'(x) + A(x) mod P(x) , +# +# then +# +# (F'(x) + x^k * A(x)) * x^n +# +# = ((R'(x) + A(x)) + x^k * A(x)) * x^n mod P(x) +# +# = (x^k * A(x) + A(x) + x^k * A(x)) * x^n mod P(x) +# +# = (0 + A(x)) * x^n mod P(x) +# +# Note that (A(x) * x^n) % P(x) is a constant, and that this result +# depends on B(x) being x^k * A(x). + +use Carp; +use Poly; + +sub new { + my $self = shift; + my $class = ref($self) || $self; + my %args = @_; + $self = {bitsendian => "little"}; + bless $self, $class; + $self->setpoly($args{"Poly"}) if exists $args{"Poly"}; + $self->bitsendian($args{"bitsendian"}) + if exists $args{"bitsendian"}; + $self->{precomp} = $args{precomp} if exists $args{precomp}; + $self->{postcomp} = $args{postcomp} if exists $args{postcomp}; + return $self; +} + +sub setpoly { + my $self = shift; + my($arg) = @_; + croak "need a polynomial" if !$arg->isa("Poly"); + $self->{Poly} = $arg; + return $self; +} + +sub crc { + my $self = shift; + my $msg = Poly->new(@_); + my($order, $r, $precomp); + $order = $self->{Poly}->order; + # B(x) = x^k * precomp + $precomp = $self->{precomp} ? + $self->{precomp} * Poly->powers2poly(scalar(@_)) : Poly->new; + # R(x) = (x^n * M(x)) % P(x) + $r = ($msg * Poly->powers2poly($order)) % $self->{Poly}; + # B(x) % P(x) + $r += $precomp % $self->{Poly}; + $r += $self->{postcomp} if exists $self->{postcomp}; + return $r; +} + +# endianness of bits of each octet +# +# Note that the message is always treated as being sent in big-endian +# octet order. +# +# Usually, the message will be treated as bits being little-endian, +# since that is the common case for serial implementations that +# present data in octets; e.g., most UARTs shift octets onto the line +# in little-endian order, and protocols such as ISO 3309, V.42, +# etc. treat individual octets as being sent LSB-first. + +sub bitsendian { + my $self = shift; + my($arg) = @_; + croak "bad bit endianness" if $arg !~ /big|little/; + $self->{bitsendian} = $arg; + return $self; +} + +sub crcstring { + my $self = shift; + my($arg) = @_; + my($packstr, @m); + { + $packstr = "B*", last if $self->{bitsendian} =~ /big/; + $packstr = "b*", last if $self->{bitsendian} =~ /little/; + croak "bad bit endianness"; + }; + @m = split //, unpack $packstr, $arg; + return $self->crc(@m); +} + +1; diff --git a/src/lib/crypto/krb/crc32/Makefile.in b/src/lib/crypto/krb/crc32/Makefile.in new file mode 100644 index 000000000..d62b6edc1 --- /dev/null +++ b/src/lib/crypto/krb/crc32/Makefile.in @@ -0,0 +1,34 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/crc32 +mydir=lib/crypto/krb/crc32 +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=crc32 +##DOS##OBJFILE=..\$(OUTPRE)crc32.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + + +STLIBOBJS= crc32.o + +OBJS= $(OUTPRE)crc32.$(OBJEXT) + +SRCS= $(srcdir)/crc32.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs + +check-unix:: + +@libobj_frag@ + diff --git a/src/lib/crypto/krb/crc32/Poly.pm b/src/lib/crypto/krb/crc32/Poly.pm new file mode 100644 index 000000000..cad0f77b5 --- /dev/null +++ b/src/lib/crypto/krb/crc32/Poly.pm @@ -0,0 +1,182 @@ +# Copyright 2002 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. + +package Poly; + +# Poly: implements some basic operations on polynomials in the field +# of integers (mod 2). +# +# The rep is an array of coefficients, highest order term first. +# +# This is rather slow at the moment. + +use overload + '+' => \&add, + '-' => \&add, + '*' => \&mul, + '%' => sub {$_[2] ? mod($_[1], $_[0]) : mod($_[0], $_[1])}, + '/' => sub { $_[2] ? scalar(div($_[1], $_[0])) + : scalar(div($_[0], $_[1])) }, + '<=>' => sub {$_[2] ? pcmp($_[1], $_[0]) : pcmp($_[0], $_[1])}, + '""' => \&str +; + +use Carp; + +# doesn't do much beyond normalize and bless +sub new { + my $this = shift; + my $class = ref($this) || $this; + my(@x) = @_; + return bless [norm(@x)], $class; +} + +# stringified P(x) +sub pretty { + my(@x) = @{+shift}; + my $n = @x; + local $_; + return "0" if !@x; + return join " + ", map {$n--; $_ ? ("x^$n") : ()} @x; +} + +sub print { + my $self = shift; + print $self->pretty, "\n"; +} + +# This assumes normalization. +sub order { + my $self = shift; + return $#{$self}; +} + +sub str { + return overload::StrVal($_[0]); +} + +# strip leading zero coefficients +sub norm { + my(@x) = @_; + shift @x while @x && !$x[0]; + return @x; +} + +# multiply $self by the single term of power $n +sub multerm { + my($self, $n) = @_; + return $self->new(@$self, (0) x $n); +} + +# This is really an order comparison; different polys of same order +# compare equal. It also assumes prior normalization. +sub pcmp { + my @x = @{+shift}; + my @y = @{+shift}; + return @x <=> @y; +} + +# convenience constructor; takes list of non-zero terms +sub powers2poly +{ + my $self = shift; + my $poly = $self->new; + my $n; + foreach $n (@_) { + $poly += $one->multerm($n); + } + return $poly; +} + +sub add { + my $self = shift; + my @x = @$self; + my @y = @{+shift}; + my @r; + unshift @r, (pop @x || 0) ^ (pop @y || 0) + while @x || @y; + return $self->new(@r); +} + +sub mul { + my($self) = shift; + my @y = @{+shift}; + my $r = $self->new; + my $power = 0; + while (@y) { + $r += $self->multerm($power) if pop @y; + $power++; + } + return $r; +} + +sub oldmod { + my($self, $div) = @_; + my @num = @$self; + my @div = @$div; + my $r = $self->new(splice @num, 0, @div); + do { + push @$r, shift @num while @num && $r < $div; + $r += $div if $r >= $div; + } while @num; + return $r; +} + +sub div { + my($self, $div) = @_; + my $q = $self->new; + my $r = $self->new(@$self); + my $one = $self->new(1); + my ($tp, $power); + croak "divide by zero" if !@$div; + while ($div <= $r) { + $power = 0; + $power++ while ($tp = $div->multerm($power)) < $r; + $q += $one->multerm($power); + $r -= $tp; + } + return wantarray ? ($q, $r) : $q; +} + +sub mod { + (&div)[1]; +} + +# bits and octets both big-endian +sub hex { + my @x = @{+shift}; + my $minwidth = shift || 32; + unshift @x, 0 while @x % 8 || @x < $minwidth; + return unpack "H*", pack "B*", join "", @x; +} + +# bit-reversal of above +sub revhex { + my @x = @{+shift}; + my $minwidth = shift || 32; + unshift @x, 0 while @x % 8 || @x < $minwidth; + return unpack "H*", pack "B*", join "", reverse @x; +} + +$one = Poly->new(1); + +1; diff --git a/src/lib/crypto/krb/crc32/crc-32.h b/src/lib/crypto/krb/crc32/crc-32.h new file mode 100644 index 000000000..0efc00625 --- /dev/null +++ b/src/lib/crypto/krb/crc32/crc-32.h @@ -0,0 +1,71 @@ +/* + * include/krb5/crc-32.h + * + * Copyright 1989,1990 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. + * + * + * Definitions for the CRC-32 checksum + */ + +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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. + */ + + +#ifndef KRB5_CRC32__ +#define KRB5_CRC32__ + +#define CRC32_CKSUM_LENGTH 4 + +void +mit_crc32 (krb5_pointer in, size_t in_length, unsigned long *c); + +#ifdef CRC32_SHIFT4 +void mit_crc32_shift4(krb5_pointer /* in */, + size_t /* in_length */, + unsigned long * /* cksum */); +#endif + +#endif /* KRB5_CRC32__ */ diff --git a/src/lib/crypto/krb/crc32/crc.pl b/src/lib/crypto/krb/crc32/crc.pl new file mode 100644 index 000000000..b21b6b15d --- /dev/null +++ b/src/lib/crypto/krb/crc32/crc.pl @@ -0,0 +1,111 @@ +# Copyright 2002 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. + +use CRC; + +print "*** crudely testing polynomial functions ***\n"; + +$x = Poly->new(1,1,1,1); +$y = Poly->new(1,1); +print "x = @{[$x->pretty]}\ny = @{[$y->pretty]}\n"; +$q = $x / $y; +$r = $x % $y; +print $x->pretty, " = (", $y->pretty , ") * (", $q->pretty, + ") + ", $r->pretty, "\n"; +$q = $y / $x; +$r = $y % $x; +print "y / x = @{[$q->pretty]}\ny % x = @{[$r->pretty]}\n"; + +# ISO 3309 32-bit FCS polynomial +$fcs32 = Poly->powers2poly(32,26,23,22,16,12,11,10,8,7,5,4,2,1,0); +print "fcs32 = ", $fcs32->pretty, "\n"; + +$crc = CRC->new(Poly => $fcs32, bitsendian => "little"); + +print "\n"; + +print "*** little endian, no complementation ***\n"; +for ($i = 0; $i < 256; $i++) { + $r = $crc->crcstring(pack "C", $i); + printf ("%02x: ", $i) if !($i % 8); + print ($r->revhex, ($i % 8 == 7) ? "\n" : " "); +} + +print "\n"; + +print "*** little endian, 4 bits, no complementation ***\n"; +for ($i = 0; $i < 16; $i++) { + @m = (split //, unpack "b*", pack "C", $i)[0..3]; + $r = $crc->crc(@m); + printf ("%02x: ", $i) if !($i % 8); + print ($r->revhex, ($i % 8 == 7) ? "\n" : " "); +} + +print "\n"; + +print "*** test vectors for t_crc.c, little endian ***\n"; +for ($i = 1; $i <= 4; $i *=2) { + for ($j = 0; $j < $i * 8; $j++) { + @m = split //, unpack "b*", pack "V", 1 << $j; + splice @m, $i * 8; + $r = $crc->crc(@m); + $m = unpack "H*", pack "b*", join("", @m); + print "{HEX, \"$m\", 0x", $r->revhex, "},\n"; + } +} +@m = ("foo", "test0123456789", + "MASSACHVSETTS INSTITVTE OF TECHNOLOGY"); +foreach $m (@m) { + $r = $crc->crcstring($m); + print "{STR, \"$m\", 0x", $r->revhex, "},\n"; +} +__END__ + +print "*** big endian, no complementation ***\n"; +for ($i = 0; $i < 256; $i++) { + $r = $crc->crcstring(pack "C", $i); + printf ("%02x: ", $i) if !($i % 8); + print ($r->hex, ($i % 8 == 7) ? "\n" : " "); +} + +# all ones polynomial of order 31 +$ones = Poly->new((1) x 32); + +print "*** big endian, ISO-3309 style\n"; +$crc = CRC->new(Poly => $fcs32, + bitsendian => "little", + precomp => $ones, + postcomp => $ones); +for ($i = 0; $i < 256; $i++) { + $r = $crc->crcstring(pack "C", $i); + print ($r->hex, ($i % 8 == 7) ? "\n" : " "); +} + +for ($i = 0; $i < 0; $i++) { + $x = Poly->new((1) x 32, (0) x $i); + $y = Poly->new((1) x 32); + $f = ($x % $fcs32) + $y; + $r = (($f + $x) * Poly->powers2poly(32)) % $fcs32; + @out = @$r; + unshift @out, 0 while @out < 32; + print @out, "\n"; +} diff --git a/src/lib/crypto/krb/crc32/crc32.c b/src/lib/crypto/krb/crc32/crc32.c new file mode 100644 index 000000000..ef65476d9 --- /dev/null +++ b/src/lib/crypto/krb/crc32/crc32.c @@ -0,0 +1,192 @@ +/* + * lib/crypto/crc32/crc.c + * + * Copyright 1990, 2002 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. + * + * + * CRC-32/AUTODIN-II routines + */ + +#include "k5-int.h" +#include "crc-32.h" + +/* This table and block of comments are taken from code labeled: */ +/* + * Copyright (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + */ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +static u_long const crc_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + +void +mit_crc32(krb5_pointer in, size_t in_length, unsigned long *cksum) +{ + register u_char *data; + register u_long c = 0; + register int idx; + size_t i; + + data = (u_char *)in; + for (i = 0; i < in_length; i++) { + idx = (int) (data[i] ^ c); + idx &= 0xff; + c >>= 8; + c ^= crc_table[idx]; + } + + *cksum = c; +} + +#ifdef CRC32_SHIFT4 +static unsigned long const tbl4[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c +}; + +void +mit_crc32_shift4(krb5_pointer in, size_t in_length, unsigned long *cksum) +{ + register unsigned char *data, b; + register unsigned long c = 0; + size_t i; + + data = (u_char *)in; + for (i = 0; i < in_length; i++) { + b = data[i]; + c = (c >> 4) ^ tbl4[(b ^ c) & 0x0f]; + b >>= 4; + c = (c >> 4) ^ tbl4[(b ^ c) & 0x0f]; + } + *cksum = c; +} +#endif diff --git a/src/lib/crypto/krb/crc32/deps b/src/lib/crypto/krb/crc32/deps new file mode 100644 index 000000000..2558fe2fc --- /dev/null +++ b/src/lib/crypto/krb/crc32/deps @@ -0,0 +1,13 @@ +# +# Generated makefile dependencies follow. +# +crc32.so crc32.po $(OUTPRE)crc32.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h crc-32.h crc32.c diff --git a/src/lib/crypto/krb/crypto_length.c b/src/lib/crypto/krb/crypto_length.c new file mode 100644 index 000000000..d99d18b27 --- /dev/null +++ b/src/lib/crypto/krb/crypto_length.c @@ -0,0 +1,170 @@ +/* + * lib/crypto/crypto_length.c + * + * Copyright 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 "etypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_crypto_length(krb5_context context, + krb5_enctype enctype, + krb5_cryptotype type, + unsigned int *size) +{ + int i; + const struct krb5_keytypes *ktp = NULL; + krb5_error_code ret; + + for (i = 0; i < krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) { + ktp = &krb5_enctypes_list[i]; + break; + } + } + + if (ktp == NULL || ktp->aead == NULL) { + return KRB5_BAD_ENCTYPE; + } + + switch (type) { + case KRB5_CRYPTO_TYPE_EMPTY: + case KRB5_CRYPTO_TYPE_SIGN_ONLY: + *size = 0; + ret = 0; + break; + case KRB5_CRYPTO_TYPE_DATA: + *size = (size_t)~0; /* match Heimdal */ + ret = 0; + break; + case KRB5_CRYPTO_TYPE_HEADER: + case KRB5_CRYPTO_TYPE_PADDING: + case KRB5_CRYPTO_TYPE_TRAILER: + case KRB5_CRYPTO_TYPE_CHECKSUM: + ret = ktp->aead->crypto_length(ktp->aead, ktp->enc, ktp->hash, type, size); + break; + default: + ret = EINVAL; + break; + } + + return ret; +} + +krb5_error_code KRB5_CALLCONV +krb5_c_padding_length(krb5_context context, + krb5_enctype enctype, + size_t data_length, + unsigned int *pad_length) +{ + int i; + const struct krb5_keytypes *ktp = NULL; + + for (i = 0; i < krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) { + ktp = &krb5_enctypes_list[i]; + break; + } + } + + if (ktp == NULL || ktp->aead == NULL) { + return KRB5_BAD_ENCTYPE; + } + + return krb5int_c_padding_length(ktp->aead, ktp->enc, ktp->hash, data_length, pad_length); +} + +krb5_error_code KRB5_CALLCONV +krb5_c_crypto_length_iov(krb5_context context, + krb5_enctype enctype, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_error_code ret = 0; + size_t i; + const struct krb5_keytypes *ktp = NULL; + unsigned int data_length = 0, pad_length; + krb5_crypto_iov *padding = NULL; + + /* + * XXX need to rejig internal interface so we can accurately + * report variable header lengths + */ + + for (i = 0; i < (size_t)krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) { + ktp = &krb5_enctypes_list[i]; + break; + } + } + + if (ktp == NULL || ktp->aead == NULL) { + return KRB5_BAD_ENCTYPE; + } + + for (i = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + switch (iov->flags) { + case KRB5_CRYPTO_TYPE_DATA: + data_length += iov->data.length; + break; + case KRB5_CRYPTO_TYPE_PADDING: + if (padding != NULL) + return EINVAL; + + padding = iov; + break; + case KRB5_CRYPTO_TYPE_HEADER: + case KRB5_CRYPTO_TYPE_TRAILER: + case KRB5_CRYPTO_TYPE_CHECKSUM: + ret = ktp->aead->crypto_length(ktp->aead, ktp->enc, ktp->hash, iov->flags, &iov->data.length); + break; + case KRB5_CRYPTO_TYPE_EMPTY: + case KRB5_CRYPTO_TYPE_SIGN_ONLY: + default: + break; + } + + if (ret != 0) + break; + } + + if (ret != 0) + return ret; + + ret = krb5int_c_padding_length(ktp->aead, ktp->enc, ktp->hash, data_length, &pad_length); + if (ret != 0) + return ret; + + if (pad_length != 0 && padding == NULL) + return EINVAL; + + if (padding != NULL) + padding->data.length = pad_length; + + return 0; +} + diff --git a/src/lib/crypto/krb/crypto_libinit.c b/src/lib/crypto/krb/crypto_libinit.c new file mode 100644 index 000000000..91bf8ac22 --- /dev/null +++ b/src/lib/crypto/krb/crypto_libinit.c @@ -0,0 +1,33 @@ +#include <assert.h> +#include "k5-int.h" + +MAKE_INIT_FUNCTION(cryptoint_initialize_library); +MAKE_FINI_FUNCTION(cryptoint_cleanup_library); + +extern int krb5int_prng_init(void); +extern void krb5int_prng_cleanup (void); + +/* + * Initialize the crypto library. + */ + +int cryptoint_initialize_library (void) +{ + return krb5int_prng_init(); +} + +int krb5int_crypto_init(void) +{ + return CALL_INIT_FUNCTION(cryptoint_initialize_library); +} + +/* + * Clean up the crypto library state + */ + +void cryptoint_cleanup_library (void) +{ + if (!INITIALIZER_RAN(cryptoint_initialize_library)) + return; + krb5int_prng_cleanup (); +} diff --git a/src/lib/crypto/krb/decrypt.c b/src/lib/crypto/krb/decrypt.c new file mode 100644 index 000000000..74c38f6aa --- /dev/null +++ b/src/lib/crypto/krb/decrypt.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_decrypt(krb5_context context, const krb5_keyblock *key, + krb5_keyusage usage, const krb5_data *ivec, + const krb5_enc_data *input, krb5_data *output) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) { + krb5int_set_error(&context->err, KRB5_BAD_ENCTYPE, + "Bad encryption type (type %d unknown)", + key->enctype); + return(KRB5_BAD_ENCTYPE); + } + + if ((input->enctype != ENCTYPE_UNKNOWN) && + (krb5_enctypes_list[i].etype != input->enctype)) + return(KRB5_BAD_ENCTYPE); + + if (krb5_enctypes_list[i].decrypt == NULL) { + assert(krb5_enctypes_list[i].aead != NULL); + + return krb5int_c_decrypt_aead_compat(krb5_enctypes_list[i].aead, + krb5_enctypes_list[i].enc, + krb5_enctypes_list[i].hash, + key, usage, ivec, + &input->ciphertext, output); + } + + return((*(krb5_enctypes_list[i].decrypt)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, usage, ivec, &input->ciphertext, output)); +} diff --git a/src/lib/crypto/krb/decrypt_iov.c b/src/lib/crypto/krb/decrypt_iov.c new file mode 100644 index 000000000..1a98b0657 --- /dev/null +++ b/src/lib/crypto/krb/decrypt_iov.c @@ -0,0 +1,61 @@ +/* + * lib/crypto/encrypt_iov.c + * + * Copyright 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 "etypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_decrypt_iov(krb5_context context, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *cipher_state, + krb5_crypto_iov *data, + size_t num_data) +{ + int i; + const struct krb5_keytypes *ktp = NULL; + + for (i = 0; i < krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) { + ktp = &krb5_enctypes_list[i]; + break; + } + } + + if (ktp == NULL || ktp->aead == NULL) { + return KRB5_BAD_ENCTYPE; + } + + if (krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM) != NULL) { + return krb5int_c_iov_decrypt_stream(ktp->aead, ktp->enc, ktp->hash, + key, usage, cipher_state, data, num_data); + } + + return ktp->aead->decrypt_iov(ktp->aead, ktp->enc, ktp->hash, + key, usage, cipher_state, data, num_data); +} + diff --git a/src/lib/crypto/krb/default_state.c b/src/lib/crypto/krb/default_state.c new file mode 100644 index 000000000..33a189f26 --- /dev/null +++ b/src/lib/crypto/krb/default_state.c @@ -0,0 +1,63 @@ +/* + * 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. + * + * Section 6 (Encryption) of the Kerberos revisions document defines + * cipher states to be used to chain encryptions and decryptions + * together. Examples of cipher states include initialization vectors + * for CBC encription. Most Kerberos encryption systems can share + * code for initializing and freeing cipher states. This file + * contains that default code. + */ + +#include "k5-int.h" + +krb5_error_code krb5int_des_init_state +(const krb5_keyblock *key, krb5_keyusage usage, krb5_data *new_state ) +{ + new_state->length = 8; + new_state->data = (void *) malloc(8); + if (new_state->data) { + memset (new_state->data, 0, new_state->length); + /* We need to copy in the key for des-cbc-cr--ick, but that's how it works*/ + if (key->enctype == ENCTYPE_DES_CBC_CRC) { + memcpy (new_state->data, key->contents, new_state->length); + } + } else { + return ENOMEM; + } + return 0; +} + +krb5_error_code krb5int_default_free_state +(krb5_data *state) +{ + if (state->data) { + free (state->data); + state-> data = NULL; + state->length = 0; + } + return 0; +} + + + diff --git a/src/lib/crypto/krb/deps b/src/lib/crypto/krb/deps new file mode 100644 index 000000000..d7041bf76 --- /dev/null +++ b/src/lib/crypto/krb/deps @@ -0,0 +1,445 @@ +# +# Generated makefile dependencies follow. +# +aead.so aead.po $(OUTPRE)aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/dk/dk.h \ + aead.c aead.h cksumtypes.h etypes.h +block_size.so block_size.po $(OUTPRE)block_size.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + block_size.c etypes.h +checksum_length.so checksum_length.po $(OUTPRE)checksum_length.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + checksum_length.c cksumtypes.h +cksumtype_to_string.so cksumtype_to_string.po $(OUTPRE)cksumtype_to_string.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtype_to_string.c cksumtypes.h +cksumtypes.so cksumtypes.po $(OUTPRE)cksumtypes.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/hash_provider/hash_provider.h $(srcdir)/keyhash_provider/keyhash_provider.h \ + cksumtypes.c cksumtypes.h +coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtypes.h coll_proof_cksum.c +combine_keys.so combine_keys.po $(OUTPRE)combine_keys.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/dk/dk.h combine_keys.c etypes.h +crypto_length.so crypto_length.po $(OUTPRE)crypto_length.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + aead.h cksumtypes.h crypto_length.c etypes.h +crypto_libinit.so crypto_libinit.po $(OUTPRE)crypto_libinit.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + crypto_libinit.c +default_state.so default_state.po $(OUTPRE)default_state.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + default_state.c +decrypt.so decrypt.po $(OUTPRE)decrypt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h aead.h cksumtypes.h \ + decrypt.c etypes.h +decrypt_iov.so decrypt_iov.po $(OUTPRE)decrypt_iov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + aead.h cksumtypes.h decrypt_iov.c etypes.h +encrypt.so encrypt.po $(OUTPRE)encrypt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h aead.h cksumtypes.h \ + encrypt.c etypes.h +encrypt_iov.so encrypt_iov.po $(OUTPRE)encrypt_iov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + encrypt_iov.c etypes.h +encrypt_length.so encrypt_length.po $(OUTPRE)encrypt_length.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + aead.h cksumtypes.h encrypt_length.c etypes.h +enctype_compare.so enctype_compare.po $(OUTPRE)enctype_compare.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + enctype_compare.c etypes.h +enctype_to_string.so enctype_to_string.po $(OUTPRE)enctype_to_string.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + enctype_to_string.c etypes.h +etypes.so etypes.po $(OUTPRE)etypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../builtin/aes/aes_s2k.h \ + $(srcdir)/../builtin/arcfour/arcfour.h $(srcdir)/../builtin/des/des_int.h \ + $(srcdir)/dk/dk.h $(srcdir)/enc_provider/enc_provider.h \ + $(srcdir)/hash_provider/hash_provider.h $(srcdir)/old/old.h \ + $(srcdir)/raw/raw.h etypes.c etypes.h +keyblocks.so keyblocks.po $(OUTPRE)keyblocks.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + keyblocks.c +keyed_cksum.so keyed_cksum.po $(OUTPRE)keyed_cksum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtypes.h keyed_cksum.c +keyed_checksum_types.so keyed_checksum_types.po $(OUTPRE)keyed_checksum_types.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtypes.h etypes.h keyed_checksum_types.c +keylengths.so keylengths.po $(OUTPRE)keylengths.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h keylengths.c +make_checksum.so make_checksum.po $(OUTPRE)make_checksum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/dk/dk.h cksumtypes.h etypes.h make_checksum.c +make_checksum_iov.so make_checksum_iov.po $(OUTPRE)make_checksum_iov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + aead.h cksumtypes.h make_checksum_iov.c +make_random_key.so make_random_key.po $(OUTPRE)make_random_key.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h make_random_key.c +mandatory_sumtype.so mandatory_sumtype.po $(OUTPRE)mandatory_sumtype.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h mandatory_sumtype.c +nfold.so nfold.po $(OUTPRE)nfold.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h nfold.c +old_api_glue.so old_api_glue.po $(OUTPRE)old_api_glue.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + old_api_glue.c +prf.so prf.po $(OUTPRE)prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h etypes.h prf.c +cf2.so cf2.po $(OUTPRE)cf2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h cf2.c etypes.h +prng.so prng.po $(OUTPRE)prng.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../builtin/sha1/shs.h \ + $(srcdir)/enc_provider/enc_provider.h $(srcdir)/yarrow/yarrow.h \ + $(srcdir)/yarrow/ycipher.h $(srcdir)/yarrow/yhash.h \ + $(srcdir)/yarrow/ytypes.h prng.c +random_to_key.so random_to_key.po $(OUTPRE)random_to_key.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h random_to_key.c +state.so state.po $(OUTPRE)state.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h etypes.h state.c +string_to_cksumtype.so string_to_cksumtype.po $(OUTPRE)string_to_cksumtype.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtypes.h string_to_cksumtype.c +string_to_enctype.so string_to_enctype.po $(OUTPRE)string_to_enctype.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h string_to_enctype.c +string_to_key.so string_to_key.po $(OUTPRE)string_to_key.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h string_to_key.c +valid_cksumtype.so valid_cksumtype.po $(OUTPRE)valid_cksumtype.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtypes.h valid_cksumtype.c +valid_enctype.so valid_enctype.po $(OUTPRE)valid_enctype.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + etypes.h valid_enctype.c +verify_checksum.so verify_checksum.po $(OUTPRE)verify_checksum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + cksumtypes.h verify_checksum.c +verify_checksum_iov.so verify_checksum_iov.po $(OUTPRE)verify_checksum_iov.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + aead.h cksumtypes.h verify_checksum_iov.c diff --git a/src/lib/crypto/krb/dk/Makefile.in b/src/lib/crypto/krb/dk/Makefile.in new file mode 100644 index 000000000..b254523c5 --- /dev/null +++ b/src/lib/crypto/krb/dk/Makefile.in @@ -0,0 +1,53 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/dk +mydir=lib/crypto/dk +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../@CRYPTO_IMPL@ +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=dk +##DOS##OBJFILE=..\$(OUTPRE)dk.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS=\ + checksum.o \ + dk_aead.o \ + dk_decrypt.o \ + dk_encrypt.o \ + derive.o \ + dk_prf.o \ + stringtokey.o + +OBJS=\ + $(OUTPRE)checksum.$(OBJEXT) \ + $(OUTPRE)dk_aead.$(OBJEXT) \ + $(OUTPRE)dk_decrypt.$(OBJEXT) \ + $(OUTPRE)dk_encrypt.$(OBJEXT) \ + $(OUTPRE)derive.$(OBJEXT) \ + $(OUTPRE)dk_prf.$(OBJEXT) \ + $(OUTPRE)stringtokey.$(OBJEXT) + +SRCS=\ + $(srcdir)/checksum.c \ + $(srcdir)/dk_aead.c \ + $(srcdir)/dk_decrypt.c \ + $(srcdir)/dk_encrypt.c \ + $(srcdir)/dk_prf.c \ + $(srcdir)/derive.c \ + $(srcdir)/stringtokey.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/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c new file mode 100644 index 000000000..f4b18bf0c --- /dev/null +++ b/src/lib/crypto/krb/dk/checksum.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" +#include "dk.h" +#include "aead.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +krb5_error_code +krb5_dk_make_checksum(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *input, krb5_data *output) +{ + int i; + const struct krb5_enc_provider *enc; + size_t blocksize, keybytes, keylength; + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data datain; + unsigned char *kcdata; + krb5_keyblock kc; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + /* allocate and set to-be-derived keys */ + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + + /* key->length will be tested in enc->encrypt + output->length will be tested in krb5_hmac */ + + if ((kcdata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + + kc.contents = kcdata; + kc.length = keylength; + + /* derive the key */ + + datain.data = (char *) constantdata; + datain.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + datain.data[4] = (char) 0x99; + + if ((ret = krb5_derive_key(enc, key, &kc, &datain)) != 0) + goto cleanup; + + /* hash the data */ + + datain = *input; + + if ((ret = krb5_hmac(hash, &kc, 1, &datain, output)) != 0) + memset(output->data, 0, output->length); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(kcdata, 0, keylength); + + free(kcdata); + + return(ret); +} + +krb5_error_code +krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + int i; + const struct krb5_enc_provider *enc; + size_t blocksize, keybytes, keylength; + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data datain; + unsigned char *kcdata; + krb5_keyblock kc; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + /* allocate and set to-be-derived keys */ + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + + /* key->length will be tested in enc->encrypt + output->length will be tested in krb5_hmac */ + + if ((kcdata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + + kc.contents = kcdata; + kc.length = keylength; + + /* derive the key */ + + datain.data = (char *) constantdata; + datain.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + datain.data[4] = (char) 0x99; + + if ((ret = krb5_derive_key(enc, key, &kc, &datain)) != 0) + goto cleanup; + + /* hash the data */ + + if ((ret = krb5int_hmac_iov(hash, &kc, data, num_data, output)) != 0) + memset(output->data, 0, output->length); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(kcdata, 0, keylength); + + free(kcdata); + + return(ret); +} + diff --git a/src/lib/crypto/krb/dk/deps b/src/lib/crypto/krb/dk/deps new file mode 100644 index 000000000..28e8a089c --- /dev/null +++ b/src/lib/crypto/krb/dk/deps @@ -0,0 +1,79 @@ +# +# Generated makefile dependencies follow. +# +checksum.so checksum.po $(OUTPRE)checksum.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../aead.h $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h \ + checksum.c dk.h +dk_aead.so dk_aead.po $(OUTPRE)dk_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../aead.h \ + $(srcdir)/../cksumtypes.h dk.h dk_aead.c +dk_decrypt.so dk_decrypt.po $(OUTPRE)dk_decrypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + dk.h dk_decrypt.c +dk_encrypt.so dk_encrypt.po $(OUTPRE)dk_encrypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + dk.h dk_encrypt.c +dk_prf.so dk_prf.po $(OUTPRE)dk_prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h dk.h dk_prf.c +derive.so derive.po $(OUTPRE)derive.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h derive.c dk.h +stringtokey.so stringtokey.po $(OUTPRE)stringtokey.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + dk.h stringtokey.c diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c new file mode 100644 index 000000000..77b05fa1a --- /dev/null +++ b/src/lib/crypto/krb/dk/derive.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "dk.h" + +krb5_error_code +krb5_derive_key(const struct krb5_enc_provider *enc, + const krb5_keyblock *inkey, krb5_keyblock *outkey, + const krb5_data *in_constant) +{ + size_t blocksize, keybytes, keylength, n; + unsigned char *inblockdata, *outblockdata, *rawkey; + krb5_data inblock, outblock; + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + + if ((inkey->length != keylength) || + (outkey->length != keylength)) + return(KRB5_CRYPTO_INTERNAL); + + /* allocate and set up buffers */ + + if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL) + return(ENOMEM); + + if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { + free(inblockdata); + return(ENOMEM); + } + + if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { + free(outblockdata); + free(inblockdata); + return(ENOMEM); + } + + inblock.data = (char *) inblockdata; + inblock.length = blocksize; + + outblock.data = (char *) outblockdata; + outblock.length = blocksize; + + /* initialize the input block */ + + if (in_constant->length == inblock.length) { + memcpy(inblock.data, in_constant->data, inblock.length); + } else { + krb5_nfold(in_constant->length*8, (unsigned char *) in_constant->data, + inblock.length*8, (unsigned char *) inblock.data); + } + + /* loop encrypting the blocks until enough key bytes are generated */ + + n = 0; + while (n < keybytes) { + (*(enc->encrypt))(inkey, 0, &inblock, &outblock); + + if ((keybytes - n) <= outblock.length) { + memcpy(rawkey+n, outblock.data, (keybytes - n)); + break; + } + + memcpy(rawkey+n, outblock.data, outblock.length); + memcpy(inblock.data, outblock.data, outblock.length); + n += outblock.length; + } + + /* postprocess the key */ + + inblock.data = (char *) rawkey; + inblock.length = keybytes; + + (*(enc->make_key))(&inblock, outkey); + + /* clean memory, free resources and exit */ + + memset(inblockdata, 0, blocksize); + memset(outblockdata, 0, blocksize); + memset(rawkey, 0, keybytes); + + free(rawkey); + free(outblockdata); + free(inblockdata); + + return(0); +} + + +krb5_error_code +krb5_derive_random(const struct krb5_enc_provider *enc, + const krb5_keyblock *inkey, krb5_data *outrnd, + const krb5_data *in_constant) +{ + size_t blocksize, keybytes, keylength, n; + unsigned char *inblockdata, *outblockdata, *rawkey; + krb5_data inblock, outblock; + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + + if ((inkey->length != keylength) || + (outrnd->length != keybytes)) + return(KRB5_CRYPTO_INTERNAL); + + /* allocate and set up buffers */ + + if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL) + return(ENOMEM); + + if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { + free(inblockdata); + return(ENOMEM); + } + + if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { + free(outblockdata); + free(inblockdata); + return(ENOMEM); + } + + inblock.data = (char *) inblockdata; + inblock.length = blocksize; + + outblock.data = (char *) outblockdata; + outblock.length = blocksize; + + /* initialize the input block */ + + if (in_constant->length == inblock.length) { + memcpy(inblock.data, in_constant->data, inblock.length); + } else { + krb5_nfold(in_constant->length*8, (unsigned char *) in_constant->data, + inblock.length*8, (unsigned char *) inblock.data); + } + + /* loop encrypting the blocks until enough key bytes are generated */ + + n = 0; + while (n < keybytes) { + (*(enc->encrypt))(inkey, 0, &inblock, &outblock); + + if ((keybytes - n) <= outblock.length) { + memcpy(rawkey+n, outblock.data, (keybytes - n)); + break; + } + + memcpy(rawkey+n, outblock.data, outblock.length); + memcpy(inblock.data, outblock.data, outblock.length); + n += outblock.length; + } + + /* postprocess the key */ + + memcpy (outrnd->data, rawkey, keybytes); + + /* clean memory, free resources and exit */ + + memset(inblockdata, 0, blocksize); + memset(outblockdata, 0, blocksize); + memset(rawkey, 0, keybytes); + + free(rawkey); + free(outblockdata); + free(inblockdata); + + return(0); +} + +#if 0 +#include "etypes.h" +void +krb5_random2key (krb5_enctype enctype, krb5_data *inblock, + krb5_keyblock *outkey) +{ + int i; + const struct krb5_enc_provider *enc; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + abort (); + + enc = krb5_enctypes_list[i].enc; + + enc->make_key (inblock, outkey); +} +#endif diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h new file mode 100644 index 000000000..bc40134ef --- /dev/null +++ b/src/lib/crypto/krb/dk/dk.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +void krb5_dk_encrypt_length +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t input, size_t *length); + +krb5_error_code krb5_dk_encrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, krb5_data *output); + +void krb5int_aes_encrypt_length +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t input, size_t *length); + +krb5_error_code krb5int_aes_dk_encrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, krb5_data *output); + +krb5_error_code krb5_dk_decrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); + +krb5_error_code krb5int_aes_dk_decrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); + +krb5_error_code krb5int_dk_string_to_key +(const struct krb5_enc_provider *enc, + const krb5_data *string, const krb5_data *salt, + const krb5_data *params, krb5_keyblock *key); + +krb5_error_code +krb5int_dk_prf(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, const krb5_data *in, krb5_data *out); + +krb5_error_code krb5_derive_key +(const struct krb5_enc_provider *enc, + const krb5_keyblock *inkey, + krb5_keyblock *outkey, const krb5_data *in_constant); + +krb5_error_code krb5_dk_make_checksum +(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *input, krb5_data *output); + +krb5_error_code +krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output); + +krb5_error_code +krb5_derive_random(const struct krb5_enc_provider *enc, + const krb5_keyblock *inkey, krb5_data *outrnd, + const krb5_data *in_constant); + +/* AEAD */ + +extern const struct krb5_aead_provider krb5int_aead_dk; +extern const struct krb5_aead_provider krb5int_aead_aes; + +/* CCM */ + +void +krb5int_ccm_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length); + +extern const struct krb5_aead_provider krb5int_aead_ccm; + +krb5_error_code krb5int_ccm_encrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); + +krb5_error_code krb5int_ccm_decrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c new file mode 100644 index 000000000..e995f9ae6 --- /dev/null +++ b/src/lib/crypto/krb/dk/dk_aead.c @@ -0,0 +1,386 @@ +/* + * lib/crypto/dk/dk_aead.c + * + * Copyright 2008, 2009 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 "dk.h" +#include "aead.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +/* AEAD */ + +static krb5_error_code +krb5int_dk_crypto_length(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + krb5_cryptotype type, + unsigned int *length) +{ + switch (type) { + case KRB5_CRYPTO_TYPE_HEADER: + case KRB5_CRYPTO_TYPE_PADDING: + *length = enc->block_size; + break; + case KRB5_CRYPTO_TYPE_TRAILER: + case KRB5_CRYPTO_TYPE_CHECKSUM: + *length = hash->hashsize; + break; + default: + assert(0 && "invalid cryptotype passed to krb5int_dk_crypto_length"); + break; + } + + return 0; +} + +static krb5_error_code +krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data d1, d2; + krb5_crypto_iov *header, *trailer, *padding; + krb5_keyblock ke, ki; + size_t i; + unsigned int blocksize = 0; + unsigned int plainlen = 0; + unsigned int hmacsize = 0; + unsigned int padsize = 0; + unsigned char *cksum = NULL; + + ke.contents = ki.contents = NULL; + ke.length = ki.length = 0; + + /* E(Confounder | Plaintext | Pad) | Checksum */ + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &blocksize); + if (ret != 0) + return ret; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &hmacsize); + if (ret != 0) + return ret; + + for (i = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + if (iov->flags == KRB5_CRYPTO_TYPE_DATA) + plainlen += iov->data.length; + } + + /* Validate header and trailer lengths. */ + + header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); + if (header == NULL || header->data.length < enc->block_size) + return KRB5_BAD_MSIZE; + + trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); + if (trailer == NULL || trailer->data.length < hmacsize) + return KRB5_BAD_MSIZE; + + if (blocksize != 0) { + /* Check that the input data is correctly padded */ + if (plainlen % blocksize) + padsize = blocksize - (plainlen % blocksize); + } + + padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING); + if (padsize && (padding == NULL || padding->data.length < padsize)) + return KRB5_BAD_MSIZE; + + if (padding != NULL) { + memset(padding->data.data, 0, padsize); + padding->data.length = padsize; + } + + ke.length = enc->keylength; + ke.contents = malloc(ke.length); + if (ke.contents == NULL) { + ret = ENOMEM; + goto cleanup; + } + ki.length = enc->keylength; + ki.contents = malloc(ki.length); + if (ki.contents == NULL) { + ret = ENOMEM; + goto cleanup; + } + cksum = (unsigned char *)malloc(hash->hashsize); + if (cksum == NULL) { + ret = ENOMEM; + goto cleanup; + } + + /* derive the keys */ + + d1.data = (char *)constantdata; + d1.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + d1.data[4] = 0xAA; + + ret = krb5_derive_key(enc, key, &ke, &d1); + if (ret != 0) + goto cleanup; + + d1.data[4] = 0x55; + + ret = krb5_derive_key(enc, key, &ki, &d1); + if (ret != 0) + goto cleanup; + + /* generate confounder */ + + header->data.length = enc->block_size; + + ret = krb5_c_random_make_octets(/* XXX */ NULL, &header->data); + if (ret != 0) + goto cleanup; + + /* hash the plaintext */ + d2.length = hash->hashsize; + d2.data = (char *)cksum; + + ret = krb5int_hmac_iov(hash, &ki, data, num_data, &d2); + if (ret != 0) + goto cleanup; + + /* encrypt the plaintext (header | data | padding) */ + assert(enc->encrypt_iov != NULL); + + ret = enc->encrypt_iov(&ke, ivec, data, num_data); /* will update ivec */ + if (ret != 0) + goto cleanup; + + /* possibly truncate the hash */ + assert(hmacsize <= d2.length); + + memcpy(trailer->data.data, cksum, hmacsize); + trailer->data.length = hmacsize; + +cleanup: + if (ke.contents != NULL) { + memset(ke.contents, 0, ke.length); + free(ke.contents); + } + if (ki.contents != NULL) { + memset(ki.contents, 0, ki.length); + free(ki.contents); + } + if (cksum != NULL) { + free(cksum); + } + + return ret; +} + +static krb5_error_code +krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data d1; + krb5_crypto_iov *header, *trailer; + krb5_keyblock ke, ki; + size_t i; + unsigned int blocksize = 0; /* careful, this is enc block size not confounder len */ + unsigned int cipherlen = 0; + unsigned int hmacsize = 0; + unsigned char *cksum = NULL; + + if (krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM) != NULL) { + return krb5int_c_iov_decrypt_stream(aead, enc, hash, key, + usage, ivec, data, num_data); + } + + ke.contents = ki.contents = NULL; + ke.length = ki.length = 0; + + /* E(Confounder | Plaintext | Pad) | Checksum */ + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &blocksize); + if (ret != 0) + return ret; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &hmacsize); + if (ret != 0) + return ret; + + for (i = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_DATA_IOV(iov)) + cipherlen += iov->data.length; + } + + if (blocksize == 0) { + /* Check for correct input length in CTS mode */ + if (enc->block_size != 0 && cipherlen < enc->block_size) + return KRB5_BAD_MSIZE; + } else { + /* Check that the input data is correctly padded */ + if ((cipherlen % blocksize) != 0) + return KRB5_BAD_MSIZE; + } + + /* Validate header and trailer lengths */ + + header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); + if (header == NULL || header->data.length != enc->block_size) + return KRB5_BAD_MSIZE; + + trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); + if (trailer == NULL || trailer->data.length != hmacsize) + return KRB5_BAD_MSIZE; + + ke.length = enc->keylength; + ke.contents = malloc(ke.length); + if (ke.contents == NULL) { + ret = ENOMEM; + goto cleanup; + } + ki.length = enc->keylength; + ki.contents = malloc(ki.length); + if (ki.contents == NULL) { + ret = ENOMEM; + goto cleanup; + } + cksum = (unsigned char *)malloc(hash->hashsize); + if (cksum == NULL) { + ret = ENOMEM; + goto cleanup; + } + + /* derive the keys */ + + d1.data = (char *)constantdata; + d1.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + d1.data[4] = 0xAA; + + ret = krb5_derive_key(enc, key, &ke, &d1); + if (ret != 0) + goto cleanup; + + d1.data[4] = 0x55; + + ret = krb5_derive_key(enc, key, &ki, &d1); + if (ret != 0) + goto cleanup; + + /* decrypt the plaintext (header | data | padding) */ + assert(enc->decrypt_iov != NULL); + + ret = enc->decrypt_iov(&ke, ivec, data, num_data); /* will update ivec */ + if (ret != 0) + goto cleanup; + + /* verify the hash */ + d1.length = hash->hashsize; /* non-truncated length */ + d1.data = (char *)cksum; + + ret = krb5int_hmac_iov(hash, &ki, data, num_data, &d1); + if (ret != 0) + goto cleanup; + + /* compare only the possibly truncated length */ + if (memcmp(cksum, trailer->data.data, hmacsize) != 0) { + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto cleanup; + } + +cleanup: + if (ke.contents != NULL) { + memset(ke.contents, 0, ke.length); + free(ke.contents); + } + if (ki.contents != NULL) { + memset(ki.contents, 0, ki.length); + free(ki.contents); + } + if (cksum != NULL) { + free(cksum); + } + + return ret; +} + +const struct krb5_aead_provider krb5int_aead_dk = { + krb5int_dk_crypto_length, + krb5int_dk_encrypt_iov, + krb5int_dk_decrypt_iov +}; + +static krb5_error_code +krb5int_aes_crypto_length(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + krb5_cryptotype type, + unsigned int *length) +{ + switch (type) { + case KRB5_CRYPTO_TYPE_HEADER: + *length = enc->block_size; + break; + case KRB5_CRYPTO_TYPE_PADDING: + *length = 0; + break; + case KRB5_CRYPTO_TYPE_TRAILER: + case KRB5_CRYPTO_TYPE_CHECKSUM: + *length = 96 / 8; + break; + default: + assert(0 && "invalid cryptotype passed to krb5int_aes_crypto_length"); + break; + } + + return 0; +} + +const struct krb5_aead_provider krb5int_aead_aes = { + krb5int_aes_crypto_length, + krb5int_dk_encrypt_iov, + krb5int_dk_decrypt_iov +}; + diff --git a/src/lib/crypto/krb/dk/dk_decrypt.c b/src/lib/crypto/krb/dk/dk_decrypt.c new file mode 100644 index 000000000..c38c4d5bf --- /dev/null +++ b/src/lib/crypto/krb/dk/dk_decrypt.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "dk.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +static krb5_error_code +krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, + krb5_data *output, + size_t hmacsize, + int ivec_mode); + +krb5_error_code +krb5_dk_decrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage, + ivec, input, output, 0, 0); +} + +krb5_error_code +krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage, + ivec, input, output, 96 / 8, 1); +} + +static krb5_error_code +krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output, size_t hmacsize, + int ivec_mode) +{ + krb5_error_code ret; + size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen; + unsigned char *plaindata, *kedata, *kidata, *cksum, *cn; + krb5_keyblock ke, ki; + krb5_data d1, d2; + unsigned char constantdata[K5CLENGTH]; + + /* allocate and set up ciphertext and to-be-derived keys */ + + hashsize = hash->hashsize; + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + + if (hmacsize == 0) + hmacsize = hashsize; + else if (hmacsize > hashsize) + return KRB5KRB_AP_ERR_BAD_INTEGRITY; + + enclen = input->length - hmacsize; + + if ((kedata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { + free(kedata); + return(ENOMEM); + } + if ((plaindata = (unsigned char *) malloc(enclen)) == NULL) { + free(kidata); + free(kedata); + return(ENOMEM); + } + if ((cksum = (unsigned char *) malloc(hashsize)) == NULL) { + free(plaindata); + free(kidata); + free(kedata); + return(ENOMEM); + } + + ke.contents = kedata; + ke.length = keylength; + ki.contents = kidata; + ki.length = keylength; + + /* derive the keys */ + + d1.data = (char *) constantdata; + d1.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + d1.data[4] = (char) 0xAA; + + if ((ret = krb5_derive_key(enc, key, &ke, &d1)) != 0) + goto cleanup; + + d1.data[4] = 0x55; + + if ((ret = krb5_derive_key(enc, key, &ki, &d1)) != 0) + goto cleanup; + + /* decrypt the ciphertext */ + + d1.length = enclen; + d1.data = input->data; + + d2.length = enclen; + d2.data = (char *) plaindata; + + if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0) + goto cleanup; + + if (ivec != NULL && ivec->length == blocksize) { + if (ivec_mode == 0) + cn = (unsigned char *) d1.data + d1.length - blocksize; + else if (ivec_mode == 1) { + int nblocks = (d1.length + blocksize - 1) / blocksize; + cn = d1.data + blocksize * (nblocks - 2); + } else + abort(); + } else + cn = NULL; + + /* verify the hash */ + + d1.length = hashsize; + d1.data = (char *) cksum; + + if ((ret = krb5_hmac(hash, &ki, 1, &d2, &d1)) != 0) + goto cleanup; + + if (memcmp(cksum, input->data+enclen, hmacsize) != 0) { + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto cleanup; + } + + /* because this encoding isn't self-describing wrt length, the + best we can do here is to compute the length minus the + confounder. */ + + plainlen = enclen - blocksize; + + if (output->length < plainlen) + return(KRB5_BAD_MSIZE); + + output->length = plainlen; + + memcpy(output->data, d2.data+blocksize, output->length); + + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); + + ret = 0; + +cleanup: + memset(kedata, 0, keylength); + memset(kidata, 0, keylength); + memset(plaindata, 0, enclen); + memset(cksum, 0, hashsize); + + free(cksum); + free(plaindata); + free(kidata); + free(kedata); + + return(ret); +} + diff --git a/src/lib/crypto/krb/dk/dk_encrypt.c b/src/lib/crypto/krb/dk/dk_encrypt.c new file mode 100644 index 000000000..6596e53ce --- /dev/null +++ b/src/lib/crypto/krb/dk/dk_encrypt.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "dk.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +/* the spec says that the confounder size and padding are specific to + the encryption algorithm. This code (dk_encrypt_length and + dk_encrypt) assume the confounder is always the blocksize, and the + padding is always zero bytes up to the blocksize. If these + assumptions ever fails, the keytype table should be extended to + include these bits of info. */ + +void +krb5_dk_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length) +{ + size_t blocksize, hashsize; + + blocksize = enc->block_size; + hashsize = hash->hashsize; + *length = krb5_roundup(blocksize+inputlen, blocksize) + hashsize; +} + +krb5_error_code +krb5_dk_encrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + size_t blocksize, keybytes, keylength, plainlen, enclen; + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data d1, d2; + unsigned char *plaintext, *kedata, *kidata; + char *cn; + krb5_keyblock ke, ki; + + /* allocate and set up plaintext and to-be-derived keys */ + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + plainlen = krb5_roundup(blocksize+input->length, blocksize); + + krb5_dk_encrypt_length(enc, hash, input->length, &enclen); + + /* key->length, ivec will be tested in enc->encrypt */ + + if (output->length < enclen) + return(KRB5_BAD_MSIZE); + + if ((kedata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { + free(kedata); + return(ENOMEM); + } + if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) { + free(kidata); + free(kedata); + return(ENOMEM); + } + + ke.contents = kedata; + ke.length = keylength; + ki.contents = kidata; + ki.length = keylength; + + /* derive the keys */ + + d1.data = (char *) constantdata; + d1.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + d1.data[4] = (char) 0xAA; + + if ((ret = krb5_derive_key(enc, key, &ke, &d1))) + goto cleanup; + + d1.data[4] = 0x55; + + if ((ret = krb5_derive_key(enc, key, &ki, &d1))) + goto cleanup; + + /* put together the plaintext */ + + d1.length = blocksize; + d1.data = (char *) plaintext; + + if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &d1))) + goto cleanup; + + memcpy(plaintext+blocksize, input->data, input->length); + + memset(plaintext+blocksize+input->length, 0, + plainlen - (blocksize+input->length)); + + /* encrypt the plaintext */ + + d1.length = plainlen; + d1.data = (char *) plaintext; + + d2.length = plainlen; + d2.data = output->data; + + if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))) + goto cleanup; + + if (ivec != NULL && ivec->length == blocksize) + cn = d2.data + d2.length - blocksize; + else + cn = NULL; + + /* hash the plaintext */ + + d2.length = enclen - plainlen; + d2.data = output->data+plainlen; + + output->length = enclen; + + if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) { + memset(d2.data, 0, d2.length); + goto cleanup; + } + + /* update ivec */ + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(kedata, 0, keylength); + memset(kidata, 0, keylength); + memset(plaintext, 0, plainlen); + + free(plaintext); + free(kidata); + free(kedata); + + return(ret); +} + +/* Not necessarily "AES", per se, but "a CBC+CTS mode block cipher + with a 96-bit truncated HMAC". */ +void +krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length) +{ + size_t blocksize, hashsize; + + blocksize = enc->block_size; + hashsize = 96 / 8; + + /* No roundup, since CTS requires no padding once we've hit the + block size. */ + *length = blocksize+inputlen + hashsize; +} + +static krb5_error_code +trunc_hmac (const struct krb5_hash_provider *hash, + const krb5_keyblock *ki, unsigned int num, + const krb5_data *input, const krb5_data *output) +{ + size_t hashsize; + krb5_data tmp; + krb5_error_code ret; + + hashsize = hash->hashsize; + if (hashsize < output->length) + return KRB5_CRYPTO_INTERNAL; + tmp.length = hashsize; + tmp.data = malloc(hashsize); + if (tmp.data == NULL) + return ENOMEM; + ret = krb5_hmac(hash, ki, num, input, &tmp); + if (ret == 0) + memcpy(output->data, tmp.data, output->length); + memset(tmp.data, 0, hashsize); + free(tmp.data); + return ret; +} + +krb5_error_code +krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + size_t blocksize, keybytes, keylength, plainlen, enclen; + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data d1, d2; + unsigned char *plaintext, *kedata, *kidata; + char *cn; + krb5_keyblock ke, ki; + + /* allocate and set up plaintext and to-be-derived keys */ + + blocksize = enc->block_size; + keybytes = enc->keybytes; + keylength = enc->keylength; + plainlen = blocksize+input->length; + + krb5int_aes_encrypt_length(enc, hash, input->length, &enclen); + + /* key->length, ivec will be tested in enc->encrypt */ + + if (output->length < enclen) + return(KRB5_BAD_MSIZE); + + if ((kedata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { + free(kedata); + return(ENOMEM); + } + if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) { + free(kidata); + free(kedata); + return(ENOMEM); + } + + ke.contents = kedata; + ke.length = keylength; + ki.contents = kidata; + ki.length = keylength; + + /* derive the keys */ + + d1.data = (char *) constantdata; + d1.length = K5CLENGTH; + + store_32_be(usage, constantdata); + + d1.data[4] = (char) 0xAA; + + if ((ret = krb5_derive_key(enc, key, &ke, &d1))) + goto cleanup; + + d1.data[4] = 0x55; + + if ((ret = krb5_derive_key(enc, key, &ki, &d1))) + goto cleanup; + + /* put together the plaintext */ + + d1.length = blocksize; + d1.data = (char *) plaintext; + + if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &d1))) + goto cleanup; + + memcpy(plaintext+blocksize, input->data, input->length); + + /* Ciphertext stealing; there should be no more. */ + if (plainlen != blocksize + input->length) + abort(); + + /* encrypt the plaintext */ + + d1.length = plainlen; + d1.data = (char *) plaintext; + + d2.length = plainlen; + d2.data = output->data; + + if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))) + goto cleanup; + + if (ivec != NULL && ivec->length == blocksize) { + int nblocks = (d2.length + blocksize - 1) / blocksize; + cn = d2.data + blocksize * (nblocks - 2); + } else + cn = NULL; + + /* hash the plaintext */ + + d2.length = enclen - plainlen; + d2.data = output->data+plainlen; + if (d2.length != 96 / 8) + abort(); + + if ((ret = trunc_hmac(hash, &ki, 1, &d1, &d2))) { + memset(d2.data, 0, d2.length); + goto cleanup; + } + + output->length = enclen; + + /* update ivec */ + if (cn != NULL) { + memcpy(ivec->data, cn, blocksize); +#if 0 + { + int i; + printf("\n%s: output:", __func__); + for (i = 0; i < output->length; i++) { + if (i % 16 == 0) + printf("\n%s: ", __func__); + printf(" %02x", i[(unsigned char *)output->data]); + } + printf("\n%s: outputIV:", __func__); + for (i = 0; i < ivec->length; i++) { + if (i % 16 == 0) + printf("\n%s: ", __func__); + printf(" %02x", i[(unsigned char *)ivec->data]); + } + printf("\n"); fflush(stdout); + } +#endif + } + + /* ret is set correctly by the prior call */ + +cleanup: + memset(kedata, 0, keylength); + memset(kidata, 0, keylength); + memset(plaintext, 0, plainlen); + + free(plaintext); + free(kidata); + free(kedata); + + return(ret); +} + diff --git a/src/lib/crypto/krb/dk/dk_prf.c b/src/lib/crypto/krb/dk/dk_prf.c new file mode 100644 index 000000000..ec64caf16 --- /dev/null +++ b/src/lib/crypto/krb/dk/dk_prf.c @@ -0,0 +1,64 @@ +/* + * lib/crypto/dk/prf.c + * + * Copyright (C) 2004 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 an implementation of the RFC 3961 PRF for + *simplified profile enctypes. + */ + +#include "k5-int.h" +#include "dk.h" + +krb5_error_code +krb5int_dk_prf (const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + const krb5_data *in, krb5_data *out) +{ + krb5_data tmp; + krb5_data prfconst; + krb5_keyblock *kp = NULL; + krb5_error_code ret = 0; + + prfconst.data = (char *) "prf"; + prfconst.length = 3; + tmp.length = hash->hashsize; + tmp.data = malloc(hash->hashsize); + if (tmp.data == NULL) + return ENOMEM; + hash->hash(1, in, &tmp); + tmp.length = (tmp.length/enc->block_size)*enc->block_size; /*truncate to block size*/ + ret = krb5int_c_init_keyblock(0, key->enctype, + key->length, &kp); + if (ret == 0) + ret = krb5_derive_key(enc, key, kp, &prfconst); + if (ret == 0) + ret = enc->encrypt(kp, NULL, &tmp, out); + if (kp) + krb5int_c_free_keyblock(0, kp); + free (tmp.data); + return ret; +} diff --git a/src/lib/crypto/krb/dk/stringtokey.c b/src/lib/crypto/krb/dk/stringtokey.c new file mode 100644 index 000000000..0e54b849f --- /dev/null +++ b/src/lib/crypto/krb/dk/stringtokey.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "dk.h" + +static const unsigned char kerberos[] = "kerberos"; +#define kerberos_len (sizeof(kerberos)-1) + +krb5_error_code +krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, + const krb5_data *string, const krb5_data *salt, + const krb5_data *parms, krb5_keyblock *key) +{ + krb5_error_code ret; + size_t keybytes, keylength, concatlen; + unsigned char *concat, *foldstring, *foldkeydata; + krb5_data indata; + krb5_keyblock foldkey; + + /* key->length is checked by krb5_derive_key */ + + keybytes = enc->keybytes; + keylength = enc->keylength; + + concatlen = string->length+(salt?salt->length:0); + + if ((concat = (unsigned char *) malloc(concatlen)) == NULL) + return(ENOMEM); + if ((foldstring = (unsigned char *) malloc(keybytes)) == NULL) { + free(concat); + return(ENOMEM); + } + if ((foldkeydata = (unsigned char *) malloc(keylength)) == NULL) { + free(foldstring); + free(concat); + return(ENOMEM); + } + + /* construct input string ( = string + salt), fold it, make_key it */ + + memcpy(concat, string->data, string->length); + if (salt) + memcpy(concat+string->length, salt->data, salt->length); + + krb5_nfold(concatlen*8, concat, keybytes*8, foldstring); + + indata.length = keybytes; + indata.data = (char *) foldstring; + foldkey.length = keylength; + foldkey.contents = foldkeydata; + + (*(enc->make_key))(&indata, &foldkey); + + /* now derive the key from this one */ + + indata.length = kerberos_len; + indata.data = (char *) kerberos; + + if ((ret = krb5_derive_key(enc, &foldkey, key, &indata))) + memset(key->contents, 0, key->length); + + /* ret is set correctly by the prior call */ + + memset(concat, 0, concatlen); + memset(foldstring, 0, keybytes); + memset(foldkeydata, 0, keylength); + + free(foldkeydata); + free(foldstring); + free(concat); + + return(ret); +} diff --git a/src/lib/crypto/krb/enc_provider/Makefile.in b/src/lib/crypto/krb/enc_provider/Makefile.in new file mode 100644 index 000000000..2eedf1d9d --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/Makefile.in @@ -0,0 +1,41 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/enc_provider +mydir=lib/crypto/krb/enc_provider +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../../@CRYPTO_IMPL@/des -I$(srcdir)/../../@CRYPTO_IMPL@/arcfour \ + -I$(srcdir)/../../@CRYPTO_IMPL@/aes -I$(srcdir)/.. -I$(srcdir)/../../@CRYPTO_IMPL@ +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=enc_provider +##DOS##OBJFILE=..\$(OUTPRE)enc_prov.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= des.o des3.o rc4.o aes.o + +OBJS= \ + $(OUTPRE)des.$(OBJEXT) \ + $(OUTPRE)des3.$(OBJEXT) \ + $(OUTPRE)aes.$(OBJEXT) \ + $(OUTPRE)rc4.$(OBJEXT) + +SRCS= \ + $(srcdir)/des.c \ + $(srcdir)/des3.c \ + $(srcdir)/aes.c \ + $(srcdir)/rc4.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/enc_provider/aes.c b/src/lib/crypto/krb/enc_provider/aes.c new file mode 100644 index 000000000..060d119c4 --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/aes.c @@ -0,0 +1,415 @@ +/* + * lib/crypto/enc_provider/aes.c + * + * Copyright (C) 2003, 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 "aes.h" +#include "../aead.h" + +#if 0 +aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]); +aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]); +aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]); +aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]); +aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]); +#endif + +#define CHECK_SIZES 0 + +#if 0 +static void printd (const char *descr, krb5_data *d) { + int i, j; + const int r = 16; + + printf("%s:", descr); + + for (i = 0; i < d->length; i += r) { + printf("\n %04x: ", i); + for (j = i; j < i + r && j < d->length; j++) + printf(" %02x", 0xff & d->data[j]); +#ifdef SHOW_TEXT + for (; j < i + r; j++) + printf(" "); + printf(" "); + for (j = i; j < i + r && j < d->length; j++) { + int c = 0xff & d->data[j]; + printf("%c", isprint(c) ? c : '.'); + } +#endif + } + printf("\n"); +} +#endif + +static inline void enc(char *out, const char *in, aes_ctx *ctx) +{ + if (aes_enc_blk((const unsigned char *)in, (unsigned char *)out, ctx) + != aes_good) + abort(); +} +static inline void dec(char *out, const char *in, aes_ctx *ctx) +{ + if (aes_dec_blk((const unsigned char *)in, (unsigned char *)out, ctx) + != aes_good) + abort(); +} + +static void xorblock(char *out, const char *in) +{ + int z; + for (z = 0; z < BLOCK_SIZE; z++) + out[z] ^= in[z]; +} + +krb5_error_code +krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + aes_ctx ctx; + char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE]; + int nblocks = 0, blockno; + +/* CHECK_SIZES; */ + + if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) + abort(); + + if (ivec) + memcpy(tmp, ivec->data, BLOCK_SIZE); + else + memset(tmp, 0, BLOCK_SIZE); + + nblocks = (input->length + BLOCK_SIZE - 1) / BLOCK_SIZE; + + if (nblocks == 1) { + /* XXX Used for DK function. */ + enc(output->data, input->data, &ctx); + } else { + unsigned int nleft; + + for (blockno = 0; blockno < nblocks - 2; blockno++) { + xorblock(tmp, input->data + blockno * BLOCK_SIZE); + enc(tmp2, tmp, &ctx); + memcpy(output->data + blockno * BLOCK_SIZE, tmp2, BLOCK_SIZE); + + /* Set up for next block. */ + memcpy(tmp, tmp2, BLOCK_SIZE); + } + /* Do final CTS step for last two blocks (the second of which + may or may not be incomplete). */ + xorblock(tmp, input->data + (nblocks - 2) * BLOCK_SIZE); + enc(tmp2, tmp, &ctx); + nleft = input->length - (nblocks - 1) * BLOCK_SIZE; + memcpy(output->data + (nblocks - 1) * BLOCK_SIZE, tmp2, nleft); + memcpy(tmp, tmp2, BLOCK_SIZE); + + memset(tmp3, 0, sizeof(tmp3)); + memcpy(tmp3, input->data + (nblocks - 1) * BLOCK_SIZE, nleft); + xorblock(tmp, tmp3); + enc(tmp2, tmp, &ctx); + memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp2, BLOCK_SIZE); + if (ivec) + memcpy(ivec->data, tmp2, BLOCK_SIZE); + } + + return 0; +} + +krb5_error_code +krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + aes_ctx ctx; + char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE]; + int nblocks = 0, blockno; + + CHECK_SIZES; + + if (aes_dec_key(key->contents, key->length, &ctx) != aes_good) + abort(); + + if (ivec) + memcpy(tmp, ivec->data, BLOCK_SIZE); + else + memset(tmp, 0, BLOCK_SIZE); + + nblocks = (input->length + BLOCK_SIZE - 1) / BLOCK_SIZE; + + if (nblocks == 1) { + if (input->length < BLOCK_SIZE) + abort(); + dec(output->data, input->data, &ctx); + } else { + + for (blockno = 0; blockno < nblocks - 2; blockno++) { + dec(tmp2, input->data + blockno * BLOCK_SIZE, &ctx); + xorblock(tmp2, tmp); + memcpy(output->data + blockno * BLOCK_SIZE, tmp2, BLOCK_SIZE); + memcpy(tmp, input->data + blockno * BLOCK_SIZE, BLOCK_SIZE); + } + /* Do last two blocks, the second of which (next-to-last block + of plaintext) may be incomplete. */ + dec(tmp2, input->data + (nblocks - 2) * BLOCK_SIZE, &ctx); + /* Set tmp3 to last ciphertext block, padded. */ + memset(tmp3, 0, sizeof(tmp3)); + memcpy(tmp3, input->data + (nblocks - 1) * BLOCK_SIZE, + input->length - (nblocks - 1) * BLOCK_SIZE); + /* Set tmp2 to last (possibly partial) plaintext block, and + save it. */ + xorblock(tmp2, tmp3); + memcpy(output->data + (nblocks - 1) * BLOCK_SIZE, tmp2, + input->length - (nblocks - 1) * BLOCK_SIZE); + /* Maybe keep the trailing part, and copy in the last + ciphertext block. */ + memcpy(tmp2, tmp3, input->length - (nblocks - 1) * BLOCK_SIZE); + /* Decrypt, to get next to last plaintext block xor previous + ciphertext. */ + dec(tmp3, tmp2, &ctx); + xorblock(tmp3, tmp); + memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp3, BLOCK_SIZE); + if (ivec) + memcpy(ivec->data, input->data + (nblocks - 2) * BLOCK_SIZE, + BLOCK_SIZE); + } + + return 0; +} + +static krb5_error_code +krb5int_aes_encrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + aes_ctx ctx; + char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE]; + int nblocks = 0, blockno; + size_t input_length, i; + + if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) + abort(); + + if (ivec != NULL) + memcpy(tmp, ivec->data, BLOCK_SIZE); + else + memset(tmp, 0, BLOCK_SIZE); + + for (i = 0, input_length = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + input_length += iov->data.length; + } + + nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; + + assert(nblocks > 1); + + { + char blockN2[BLOCK_SIZE]; /* second last */ + char blockN1[BLOCK_SIZE]; /* last block */ + struct iov_block_state input_pos, output_pos; + + IOV_BLOCK_STATE_INIT(&input_pos); + IOV_BLOCK_STATE_INIT(&output_pos); + + for (blockno = 0; blockno < nblocks - 2; blockno++) { + char blockN[BLOCK_SIZE]; + + krb5int_c_iov_get_block((unsigned char *)blockN, BLOCK_SIZE, data, num_data, &input_pos); + xorblock(tmp, blockN); + enc(tmp2, tmp, &ctx); + krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2, BLOCK_SIZE, &output_pos); + + /* Set up for next block. */ + memcpy(tmp, tmp2, BLOCK_SIZE); + } + + /* Do final CTS step for last two blocks (the second of which + may or may not be incomplete). */ + + /* First, get the last two blocks */ + memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */ + krb5int_c_iov_get_block((unsigned char *)blockN2, BLOCK_SIZE, data, num_data, &input_pos); + krb5int_c_iov_get_block((unsigned char *)blockN1, BLOCK_SIZE, data, num_data, &input_pos); + + /* Encrypt second last block */ + xorblock(tmp, blockN2); + enc(tmp2, tmp, &ctx); + memcpy(blockN2, tmp2, BLOCK_SIZE); /* blockN2 now contains first block */ + memcpy(tmp, tmp2, BLOCK_SIZE); + + /* Encrypt last block */ + xorblock(tmp, blockN1); + enc(tmp2, tmp, &ctx); + memcpy(blockN1, tmp2, BLOCK_SIZE); + + /* Put the last two blocks back into the iovec (reverse order) */ + krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN1, BLOCK_SIZE, &output_pos); + krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN2, BLOCK_SIZE, &output_pos); + + if (ivec != NULL) + memcpy(ivec->data, blockN1, BLOCK_SIZE); + } + + return 0; +} + +static krb5_error_code +krb5int_aes_decrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + aes_ctx ctx; + char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE]; + int nblocks = 0, blockno; + unsigned int i; + size_t input_length; + + CHECK_SIZES; + + if (aes_dec_key(key->contents, key->length, &ctx) != aes_good) + abort(); + + if (ivec != NULL) + memcpy(tmp, ivec->data, BLOCK_SIZE); + else + memset(tmp, 0, BLOCK_SIZE); + + for (i = 0, input_length = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + input_length += iov->data.length; + } + + nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; + + assert(nblocks > 1); + + { + char blockN2[BLOCK_SIZE]; /* second last */ + char blockN1[BLOCK_SIZE]; /* last block */ + struct iov_block_state input_pos, output_pos; + + IOV_BLOCK_STATE_INIT(&input_pos); + IOV_BLOCK_STATE_INIT(&output_pos); + + for (blockno = 0; blockno < nblocks - 2; blockno++) { + char blockN[BLOCK_SIZE]; + + krb5int_c_iov_get_block((unsigned char *)blockN, BLOCK_SIZE, data, num_data, &input_pos); + dec(tmp2, blockN, &ctx); + xorblock(tmp2, tmp); + krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2, BLOCK_SIZE, &output_pos); + memcpy(tmp, blockN, BLOCK_SIZE); + } + + /* Do last two blocks, the second of which (next-to-last block + of plaintext) may be incomplete. */ + + /* First, get the last two encrypted blocks */ + memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */ + krb5int_c_iov_get_block((unsigned char *)blockN2, BLOCK_SIZE, data, num_data, &input_pos); + krb5int_c_iov_get_block((unsigned char *)blockN1, BLOCK_SIZE, data, num_data, &input_pos); + + /* Decrypt second last block */ + dec(tmp2, blockN2, &ctx); + /* Set tmp2 to last (possibly partial) plaintext block, and + save it. */ + xorblock(tmp2, blockN1); + memcpy(blockN2, tmp2, BLOCK_SIZE); + + /* Maybe keep the trailing part, and copy in the last + ciphertext block. */ + input_length %= BLOCK_SIZE; + memcpy(tmp2, blockN1, input_length ? input_length : BLOCK_SIZE); + dec(tmp3, tmp2, &ctx); + xorblock(tmp3, tmp); + /* Copy out ivec first before we clobber blockN1 with plaintext */ + if (ivec != NULL) + memcpy(ivec->data, blockN1, BLOCK_SIZE); + memcpy(blockN1, tmp3, BLOCK_SIZE); + + /* Put the last two blocks back into the iovec */ + krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN1, BLOCK_SIZE, &output_pos); + krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN2, BLOCK_SIZE, &output_pos); + } + + return 0; +} + +static krb5_error_code +k5_aes_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + if (key->length != 16 && key->length != 32) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != key->length) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + + memcpy(key->contents, randombits->data, randombits->length); + return(0); +} + +static krb5_error_code +krb5int_aes_init_state (const krb5_keyblock *key, krb5_keyusage usage, + krb5_data *state) +{ + state->length = 16; + state->data = (void *) malloc(16); + if (state->data == NULL) + return ENOMEM; + memset(state->data, 0, state->length); + return 0; +} + +const struct krb5_enc_provider krb5int_enc_aes128 = { + 16, + 16, 16, + krb5int_aes_encrypt, + krb5int_aes_decrypt, + k5_aes_make_key, + krb5int_aes_init_state, + krb5int_default_free_state, + krb5int_aes_encrypt_iov, + krb5int_aes_decrypt_iov +}; + +const struct krb5_enc_provider krb5int_enc_aes256 = { + 16, + 32, 32, + krb5int_aes_encrypt, + krb5int_aes_decrypt, + k5_aes_make_key, + krb5int_aes_init_state, + krb5int_default_free_state, + krb5int_aes_encrypt_iov, + krb5int_aes_decrypt_iov +}; + diff --git a/src/lib/crypto/krb/enc_provider/deps b/src/lib/crypto/krb/enc_provider/deps new file mode 100644 index 000000000..fa797cdfb --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/deps @@ -0,0 +1,50 @@ +# +# Generated makefile dependencies follow. +# +des.so des.po $(OUTPRE)des.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/des/des_int.h \ + $(srcdir)/../aead.h $(srcdir)/../cksumtypes.h des.c \ + enc_provider.h +des3.so des3.po $(OUTPRE)des3.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/des/des_int.h \ + $(srcdir)/../aead.h $(srcdir)/../cksumtypes.h des3.c +aes.so aes.po $(OUTPRE)aes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/aes/aes.h \ + $(srcdir)/../../builtin/aes/uitypes.h $(srcdir)/../aead.h \ + $(srcdir)/../cksumtypes.h aes.c enc_provider.h +rc4.so rc4.po $(OUTPRE)rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/arcfour/arcfour-int.h \ + $(srcdir)/../../builtin/arcfour/arcfour.h $(srcdir)/../aead.h \ + $(srcdir)/../cksumtypes.h enc_provider.h rc4.c diff --git a/src/lib/crypto/krb/enc_provider/des.c b/src/lib/crypto/krb/enc_provider/des.c new file mode 100644 index 000000000..547f6b976 --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/des.c @@ -0,0 +1,181 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "des_int.h" +#include "enc_provider.h" +#include "aead.h" + +static krb5_error_code +k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output, int enc) +{ + mit_des_key_schedule schedule; + + /* key->enctype was checked by the caller */ + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + switch (mit_des_key_sched(key->contents, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* this has a return value, but the code always returns zero */ + + mit_des_cbc_encrypt((krb5_pointer) input->data, + (krb5_pointer) output->data, input->length, + schedule, + (ivec + ? (const unsigned char *) ivec->data + : (const unsigned char *) mit_des_zeroblock), + enc); + + memset(schedule, 0, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + return(k5_des_docrypt(key, ivec, input, output, 1)); +} + +static krb5_error_code +k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + return(k5_des_docrypt(key, ivec, input, output, 0)); +} + +static krb5_error_code +k5_des_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != 7) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + key->length = 8; + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits */ + + memcpy(key->contents, randombits->data, randombits->length); + key->contents[7] = (((key->contents[0]&1)<<1) | ((key->contents[1]&1)<<2) | + ((key->contents[2]&1)<<3) | ((key->contents[3]&1)<<4) | + ((key->contents[4]&1)<<5) | ((key->contents[5]&1)<<6) | + ((key->contents[6]&1)<<7)); + + mit_des_fixup_key_parity(key->contents); + + return(0); +} + +static krb5_error_code +k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, + krb5_crypto_iov *data, size_t num_data, int enc) +{ + mit_des_key_schedule schedule; + size_t input_length = 0; + unsigned int i; + + /* key->enctype was checked by the caller */ + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + + for (i = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_DATA_IOV(iov)) + input_length += iov->data.length; + } + + if ((input_length % 8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + switch (mit_des_key_sched(key->contents, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* this has a return value, but the code always returns zero */ + if (enc) + krb5int_des_cbc_encrypt_iov(data, num_data, schedule, ivec ? ivec->data : NULL); + else + krb5int_des_cbc_decrypt_iov(data, num_data, schedule, ivec ? ivec->data : NULL); + + memset(schedule, 0, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des_encrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + return k5_des_docrypt_iov(key, ivec, data, num_data, 1); +} + +static krb5_error_code +k5_des_decrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + return k5_des_docrypt_iov(key, ivec, data, num_data, 0); +} + +const struct krb5_enc_provider krb5int_enc_des = { + 8, + 7, 8, + k5_des_encrypt, + k5_des_decrypt, + k5_des_make_key, + krb5int_des_init_state, + krb5int_default_free_state, + k5_des_encrypt_iov, + k5_des_decrypt_iov +}; diff --git a/src/lib/crypto/krb/enc_provider/des3.c b/src/lib/crypto/krb/enc_provider/des3.c new file mode 100644 index 000000000..412c994a7 --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/des3.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "des_int.h" +#include "../aead.h" + +static krb5_error_code +validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, const krb5_data *output, + mit_des3_key_schedule *schedule) +{ + /* key->enctype was checked by the caller */ + + if (key->length != 24) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + *schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + return 0; +} + +static krb5_error_code +validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_crypto_iov *data, size_t num_data, + mit_des3_key_schedule *schedule) +{ + size_t i, input_length; + + for (i = 0, input_length = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + input_length += iov->data.length; + } + + if (key->length != 24) + return(KRB5_BAD_KEYSIZE); + if ((input_length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + *schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + return 0; +} + +static krb5_error_code +k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + mit_des3_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule(key, ivec, input, output, &schedule); + if (err) + return err; + + /* this has a return value, but the code always returns zero */ + krb5int_des3_cbc_encrypt((krb5_pointer) input->data, + (krb5_pointer) output->data, input->length, + schedule[0], schedule[1], schedule[2], + ivec?(const unsigned char *) ivec->data:(const unsigned char *)mit_des_zeroblock); + + zap(schedule, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + mit_des3_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule(key, ivec, input, output, &schedule); + if (err) + return err; + + /* this has a return value, but the code always returns zero */ + krb5int_des3_cbc_decrypt((krb5_pointer) input->data, + (krb5_pointer) output->data, input->length, + schedule[0], schedule[1], schedule[2], + ivec?(const unsigned char *) ivec->data:(const unsigned char *)mit_des_zeroblock); + + zap(schedule, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des3_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + int i; + + if (key->length != 24) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != 21) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + key->length = 24; + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits. Do this three times. */ + + for (i=0; i<3; i++) { + memcpy(key->contents+i*8, randombits->data+i*7, 7); + key->contents[i*8+7] = (((key->contents[i*8]&1)<<1) | + ((key->contents[i*8+1]&1)<<2) | + ((key->contents[i*8+2]&1)<<3) | + ((key->contents[i*8+3]&1)<<4) | + ((key->contents[i*8+4]&1)<<5) | + ((key->contents[i*8+5]&1)<<6) | + ((key->contents[i*8+6]&1)<<7)); + + mit_des_fixup_key_parity(key->contents+i*8); + } + + return(0); +} + +static krb5_error_code +k5_des3_encrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + mit_des3_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule_iov(key, ivec, data, num_data, &schedule); + if (err) + return err; + + /* this has a return value, but the code always returns zero */ + krb5int_des3_cbc_encrypt_iov(data, num_data, + schedule[0], schedule[1], schedule[2], + ivec != NULL ? (unsigned char *) ivec->data : NULL); + + zap(schedule, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des3_decrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + mit_des3_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule_iov(key, ivec, data, num_data, &schedule); + if (err) + return err; + + /* this has a return value, but the code always returns zero */ + krb5int_des3_cbc_decrypt_iov(data, num_data, + schedule[0], schedule[1], schedule[2], + ivec != NULL ? (unsigned char *) ivec->data : NULL); + + zap(schedule, sizeof(schedule)); + + return(0); +} + +const struct krb5_enc_provider krb5int_enc_des3 = { + 8, + 21, 24, + k5_des3_encrypt, + k5_des3_decrypt, + k5_des3_make_key, + krb5int_des_init_state, + krb5int_default_free_state, + k5_des3_encrypt_iov, + k5_des3_decrypt_iov +}; + diff --git a/src/lib/crypto/krb/enc_provider/enc_provider.h b/src/lib/crypto/krb/enc_provider/enc_provider.h new file mode 100644 index 000000000..92022b3c8 --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/enc_provider.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +extern const struct krb5_enc_provider krb5int_enc_des; +extern const struct krb5_enc_provider krb5int_enc_des3; +extern const struct krb5_enc_provider krb5int_enc_arcfour; +extern const struct krb5_enc_provider krb5int_enc_aes128; +extern const struct krb5_enc_provider krb5int_enc_aes256; +extern const struct krb5_enc_provider krb5int_enc_aes128_ctr; +extern const struct krb5_enc_provider krb5int_enc_aes256_ctr; + diff --git a/src/lib/crypto/krb/enc_provider/rc4.c b/src/lib/crypto/krb/enc_provider/rc4.c new file mode 100644 index 000000000..b950a605b --- /dev/null +++ b/src/lib/crypto/krb/enc_provider/rc4.c @@ -0,0 +1,271 @@ +/* arcfour.c + * + * Copyright (c) 2000 by Computer Science Laboratory, + * Rensselaer Polytechnic Institute + * + * #include STD_DISCLAIMER + */ + +#include "k5-int.h" +#include "arcfour-int.h" +#include "enc_provider.h" +#include "../aead.h" +/* gets the next byte from the PRNG */ +#if ((__GNUC__ >= 2) ) +static __inline__ unsigned int k5_arcfour_byte(ArcfourContext *); +#else +static unsigned int k5_arcfour_byte(ArcfourContext *); +#endif /* gcc inlines*/ + +/* Initializes the context and sets the key. */ +static krb5_error_code k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key, + unsigned int keylen); + +/* Encrypts/decrypts data. */ +static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest, + const unsigned char *src, unsigned int len); + +/* Interface layer to kerb5 crypto layer */ +static krb5_error_code +k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *, + const krb5_data *, krb5_data *); + +/* from a random bitstrem, construct a key */ +static krb5_error_code +k5_arcfour_make_key(const krb5_data *, krb5_keyblock *); + +static const unsigned char arcfour_weakkey1[] = {0x00, 0x00, 0xfd}; +static const unsigned char arcfour_weakkey2[] = {0x03, 0xfd, 0xfc}; +static const struct { + size_t length; + const unsigned char *data; +} arcfour_weakkeys[] = { + { sizeof (arcfour_weakkey1), arcfour_weakkey1}, + { sizeof (arcfour_weakkey2), arcfour_weakkey2}, +}; + +static inline unsigned int k5_arcfour_byte(ArcfourContext * ctx) +{ + unsigned int x; + unsigned int y; + unsigned int sx, sy; + unsigned char *state; + + state = ctx->state; + x = (ctx->x + 1) & 0xff; + sx = state[x]; + y = (sx + ctx->y) & 0xff; + sy = state[y]; + ctx->x = x; + ctx->y = y; + state[y] = sx; + state[x] = sy; + return state[(sx + sy) & 0xff]; +} + +static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest, + const unsigned char *src, unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) + dest[i] = src[i] ^ k5_arcfour_byte(ctx); +} + + +static krb5_error_code +k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key, + unsigned int key_len) +{ + unsigned int t, u; + unsigned int keyindex; + unsigned int stateindex; + unsigned char* state; + unsigned int counter; + + if (key_len != 16) + return KRB5_BAD_MSIZE; /*this is probably not the correct error code + to return */ + for (counter=0; + counter < sizeof(arcfour_weakkeys)/sizeof(arcfour_weakkeys[0]); + counter++) + if (!memcmp(key, arcfour_weakkeys[counter].data, + arcfour_weakkeys[counter].length)) + return KRB5DES_WEAK_KEY; /* most certainly not the correct error */ + + state = &ctx->state[0]; + ctx->x = 0; + ctx->y = 0; + for (counter = 0; counter < 256; counter++) + state[counter] = counter; + keyindex = 0; + stateindex = 0; + for (counter = 0; counter < 256; counter++) + { + t = state[counter]; + stateindex = (stateindex + key[keyindex] + t) & 0xff; + u = state[stateindex]; + state[stateindex] = t; + state[counter] = u; + if (++keyindex >= key_len) + keyindex = 0; + } + return 0; +} + + +/* The workhorse of the arcfour system, this impliments the cipher */ +static krb5_error_code +k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, + const krb5_data *input, krb5_data *output) +{ + ArcfourContext *arcfour_ctx; + ArcFourCipherState *cipher_state; + int ret; + + if (key->length != 16) + return(KRB5_BAD_KEYSIZE); + if (state && (state->length != sizeof (ArcFourCipherState))) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + if (state) { + cipher_state = (ArcFourCipherState *) state->data; + arcfour_ctx=&cipher_state->ctx; + if (cipher_state->initialized == 0) { + if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) { + return ret; + } + cipher_state->initialized = 1; + } + k5_arcfour_crypt(arcfour_ctx, (unsigned char *) output->data, (const unsigned char *) input->data, input->length); + } + else { + arcfour_ctx=malloc(sizeof (ArcfourContext)); + if (arcfour_ctx == NULL) + return ENOMEM; + if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) { + free(arcfour_ctx); + return (ret); + } + k5_arcfour_crypt(arcfour_ctx, (unsigned char * ) output->data, + (const unsigned char * ) input->data, input->length); + memset(arcfour_ctx, 0, sizeof (ArcfourContext)); + free(arcfour_ctx); + } + + return 0; +} + +/* In-place encryption */ +static krb5_error_code +k5_arcfour_docrypt_iov(const krb5_keyblock *key, + const krb5_data *state, + krb5_crypto_iov *data, + size_t num_data) +{ + ArcfourContext *arcfour_ctx = NULL; + ArcFourCipherState *cipher_state = NULL; + krb5_error_code ret; + size_t i; + + if (key->length != 16) + return KRB5_BAD_KEYSIZE; + if (state != NULL && (state->length != sizeof(ArcFourCipherState))) + return KRB5_BAD_MSIZE; + + if (state != NULL) { + cipher_state = (ArcFourCipherState *)state->data; + arcfour_ctx = &cipher_state->ctx; + if (cipher_state->initialized == 0) { + ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length); + if (ret != 0) + return ret; + + cipher_state->initialized = 1; + } + } else { + arcfour_ctx = (ArcfourContext *)malloc(sizeof(ArcfourContext)); + if (arcfour_ctx == NULL) + return ENOMEM; + + ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length); + if (ret != 0) { + free(arcfour_ctx); + return ret; + } + } + + for (i = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + k5_arcfour_crypt(arcfour_ctx, (unsigned char *)iov->data.data, + (const unsigned char *)iov->data.data, iov->data.length); + } + + if (state == NULL) { + memset(arcfour_ctx, 0, sizeof(ArcfourContext)); + free(arcfour_ctx); + } + + return 0; +} + +static krb5_error_code +k5_arcfour_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + if (key->length != 16) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != 16) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + key->length = 16; + + memcpy(key->contents, randombits->data, randombits->length); + + return(0); +} + +static krb5_error_code +k5_arcfour_init_state (const krb5_keyblock *key, + krb5_keyusage keyusage, krb5_data *new_state) +{ + /* Note that we can't actually set up the state here because the key + * will change between now and when encrypt is called + * because it is data dependent. Yeah, this has strange + * properties. --SDH + */ + new_state->length = sizeof (ArcFourCipherState); + new_state->data = malloc (new_state->length); + if (new_state->data) { + memset (new_state->data, 0 , new_state->length); + /* That will set initialized to zero*/ + }else { + return (ENOMEM); + } + return 0; +} + +/* Since the arcfour cipher is identical going forwards and backwards, + we just call "docrypt" directly +*/ +const struct krb5_enc_provider krb5int_enc_arcfour = { + /* This seems to work... although I am not sure what the + implications are in other places in the kerberos library */ + 1, + /* Keysize is arbitrary in arcfour, but the constraints of the + system, and to attempt to work with the MSFT system forces us + to 16byte/128bit. Since there is no parity in the key, the + byte and length are the same. */ + 16, 16, + k5_arcfour_docrypt, + k5_arcfour_docrypt, + k5_arcfour_make_key, + k5_arcfour_init_state, /*xxx not implemented yet*/ + krb5int_default_free_state, + k5_arcfour_docrypt_iov, + k5_arcfour_docrypt_iov +}; + diff --git a/src/lib/crypto/krb/encrypt.c b/src/lib/crypto/krb/encrypt.c new file mode 100644 index 000000000..a9a38aa77 --- /dev/null +++ b/src/lib/crypto/krb/encrypt.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_encrypt(krb5_context context, const krb5_keyblock *key, + krb5_keyusage usage, const krb5_data *ivec, + const krb5_data *input, krb5_enc_data *output) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + output->magic = KV5M_ENC_DATA; + output->kvno = 0; + output->enctype = key->enctype; + + if (krb5_enctypes_list[i].encrypt == NULL) { + assert(krb5_enctypes_list[i].aead != NULL); + + return krb5int_c_encrypt_aead_compat(krb5_enctypes_list[i].aead, + krb5_enctypes_list[i].enc, + krb5_enctypes_list[i].hash, + key, usage, ivec, + input, &output->ciphertext); + } + + return((*(krb5_enctypes_list[i].encrypt)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, usage, ivec, input, &output->ciphertext)); +} diff --git a/src/lib/crypto/krb/encrypt_iov.c b/src/lib/crypto/krb/encrypt_iov.c new file mode 100644 index 000000000..a35c5b577 --- /dev/null +++ b/src/lib/crypto/krb/encrypt_iov.c @@ -0,0 +1,55 @@ +/* + * lib/crypto/encrypt_iov.c + * + * Copyright 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_encrypt_iov(krb5_context context, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *cipher_state, + krb5_crypto_iov *data, + size_t num_data) +{ + int i; + const struct krb5_keytypes *ktp = NULL; + + for (i = 0; i < krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) { + ktp = &krb5_enctypes_list[i]; + break; + } + } + + if (ktp == NULL || ktp->aead == NULL) { + return KRB5_BAD_ENCTYPE; + } + + return ktp->aead->encrypt_iov(ktp->aead, ktp->enc, ktp->hash, + key, usage, cipher_state, data, num_data); +} + diff --git a/src/lib/crypto/krb/encrypt_length.c b/src/lib/crypto/krb/encrypt_length.c new file mode 100644 index 000000000..a934b2a21 --- /dev/null +++ b/src/lib/crypto/krb/encrypt_length.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype, + size_t inputlen, size_t *length) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + if (krb5_enctypes_list[i].encrypt_len == NULL) { + assert(krb5_enctypes_list[i].aead != NULL); + + krb5int_c_encrypt_length_aead_compat(krb5_enctypes_list[i].aead, + krb5_enctypes_list[i].enc, + krb5_enctypes_list[i].hash, + inputlen, length); + } else { + (*(krb5_enctypes_list[i].encrypt_len)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + inputlen, length); + } + + return(0); +} diff --git a/src/lib/crypto/krb/enctype_compare.c b/src/lib/crypto/krb/enctype_compare.c new file mode 100644 index 000000000..55e827764 --- /dev/null +++ b/src/lib/crypto/krb/enctype_compare.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2, + krb5_boolean *similar) +{ + int i, j; + + for (i=0; i<krb5_enctypes_length; i++) + if (krb5_enctypes_list[i].etype == e1) + break; + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + for (j=0; j<krb5_enctypes_length; j++) + if (krb5_enctypes_list[j].etype == e2) + break; + + if (j == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + *similar = + ((krb5_enctypes_list[i].enc == krb5_enctypes_list[j].enc) && + (krb5_enctypes_list[i].str2key == krb5_enctypes_list[j].str2key)); + + return(0); +} diff --git a/src/lib/crypto/krb/enctype_to_string.c b/src/lib/crypto/krb/enctype_to_string.c new file mode 100644 index 000000000..28fa63ee1 --- /dev/null +++ b/src/lib/crypto/krb/enctype_to_string.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_enctype_to_string(krb5_enctype enctype, char *buffer, size_t buflen) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) { + if (strlcpy(buffer, krb5_enctypes_list[i].out_string, + buflen) >= buflen) + return(ENOMEM); + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c new file mode 100644 index 000000000..c44ee413e --- /dev/null +++ b/src/lib/crypto/krb/etypes.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "hash_provider.h" +#include "etypes.h" +#include "old.h" +#include "raw.h" +#include "dk.h" +#include "arcfour.h" +#include "aes_s2k.h" +#include "des/des_int.h" + +/* these will be linear searched. if they ever get big, a binary + search or hash table would be better, which means these would need + to be sorted. An array would be more efficient, but that assumes + that the keytypes are all near each other. I'd rather not make + that assumption. */ + +const struct krb5_keytypes krb5_enctypes_list[] = { + { ENCTYPE_DES_CBC_CRC, + "des-cbc-crc", { 0 }, "DES cbc mode with CRC-32", + &krb5int_enc_des, &krb5int_hash_crc32, + 16, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5int_des_string_to_key, + krb5int_des_prf, + CKSUMTYPE_RSA_MD5, + NULL, /*AEAD*/ + ETYPE_WEAK }, + { ENCTYPE_DES_CBC_MD4, + "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4", + &krb5int_enc_des, &krb5int_hash_md4, + 16, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5int_des_string_to_key, + krb5int_des_prf, + CKSUMTYPE_RSA_MD4, + NULL, /*AEAD*/ + ETYPE_WEAK }, + { ENCTYPE_DES_CBC_MD5, + "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5", + &krb5int_enc_des, &krb5int_hash_md5, + 16, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5int_des_string_to_key, + krb5int_des_prf, + CKSUMTYPE_RSA_MD5, + NULL, /*AEAD*/ + ETYPE_WEAK }, + { ENCTYPE_DES_CBC_RAW, + "des-cbc-raw", { 0 }, "DES cbc mode raw", + &krb5int_enc_des, NULL, + 16, + krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, + krb5int_des_string_to_key, + krb5int_des_prf, + 0, + &krb5int_aead_raw, + ETYPE_WEAK }, + { ENCTYPE_DES3_CBC_RAW, + "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw", + &krb5int_enc_des3, NULL, + 16, + krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, + krb5int_dk_string_to_key, + NULL, /*PRF*/ + 0, + &krb5int_aead_raw, + ETYPE_WEAK }, + + { ENCTYPE_DES3_CBC_SHA1, + "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" }, + "Triple DES cbc mode with HMAC/sha1", + &krb5int_enc_des3, &krb5int_hash_sha1, + 16, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5int_dk_string_to_key, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_DES3, + &krb5int_aead_dk, + 0 /*flags*/ }, + + { ENCTYPE_DES_HMAC_SHA1, + "des-hmac-sha1", { 0 }, "DES with HMAC/sha1", + &krb5int_enc_des, &krb5int_hash_sha1, + 8, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5int_dk_string_to_key, + NULL, /*PRF*/ + 0, + NULL, + ETYPE_WEAK }, + { ENCTYPE_ARCFOUR_HMAC, + "arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" }, + "ArcFour with HMAC/md5", + &krb5int_enc_arcfour, + &krb5int_hash_md5, + 20, + krb5_arcfour_encrypt_length, krb5_arcfour_encrypt, + krb5_arcfour_decrypt, krb5int_arcfour_string_to_key, + krb5int_arcfour_prf, /*PRF*/ + CKSUMTYPE_HMAC_MD5_ARCFOUR, + &krb5int_aead_arcfour, + 0 /*flags*/ }, + { ENCTYPE_ARCFOUR_HMAC_EXP, + "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" }, + "Exportable ArcFour with HMAC/md5", + &krb5int_enc_arcfour, + &krb5int_hash_md5, + 20, + krb5_arcfour_encrypt_length, krb5_arcfour_encrypt, + krb5_arcfour_decrypt, krb5int_arcfour_string_to_key, + krb5int_arcfour_prf, /*PRF*/ + CKSUMTYPE_HMAC_MD5_ARCFOUR, + &krb5int_aead_arcfour, + ETYPE_WEAK + }, + + { ENCTYPE_AES128_CTS_HMAC_SHA1_96, + "aes128-cts-hmac-sha1-96", { "aes128-cts" }, + "AES-128 CTS mode with 96-bit SHA-1 HMAC", + &krb5int_enc_aes128, &krb5int_hash_sha1, + 16, + krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt, + krb5int_aes_string_to_key, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_96_AES128, + &krb5int_aead_aes, + 0 /*flags*/ }, + { ENCTYPE_AES256_CTS_HMAC_SHA1_96, + "aes256-cts-hmac-sha1-96", { "aes256-cts" }, + "AES-256 CTS mode with 96-bit SHA-1 HMAC", + &krb5int_enc_aes256, &krb5int_hash_sha1, + 16, + krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt, + krb5int_aes_string_to_key, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_96_AES256, + &krb5int_aead_aes, + 0 /*flags*/ }, +}; + +const int krb5_enctypes_length = +sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes); diff --git a/src/lib/crypto/krb/etypes.h b/src/lib/crypto/krb/etypes.h new file mode 100644 index 000000000..8441fcabc --- /dev/null +++ b/src/lib/crypto/krb/etypes.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +typedef void (*krb5_encrypt_length_func) (const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length); + +typedef krb5_error_code (*krb5_crypt_func) (const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage keyusage, + const krb5_data *ivec, + const krb5_data *input, krb5_data *output); + +typedef krb5_error_code (*krb5_str2key_func) (const struct krb5_enc_provider *enc, const krb5_data *string, + const krb5_data *salt, const krb5_data *parm, krb5_keyblock *key); + +typedef krb5_error_code (*krb5_prf_func)( + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + const krb5_data *in, krb5_data *out); + +struct krb5_keytypes { + krb5_enctype etype; + char *name; + char *aliases[2]; + char *out_string; + const struct krb5_enc_provider *enc; + const struct krb5_hash_provider *hash; + size_t prf_length; + krb5_encrypt_length_func encrypt_len; + krb5_crypt_func encrypt; + krb5_crypt_func decrypt; + krb5_str2key_func str2key; + krb5_prf_func prf; + krb5_cksumtype required_ctype; + const struct krb5_aead_provider *aead; + krb5_flags flags; +}; + +#define ETYPE_WEAK 1 + +extern const struct krb5_keytypes krb5_enctypes_list[]; +extern const int krb5_enctypes_length; + +static inline const struct krb5_keytypes* +find_enctype (krb5_enctype enctype) +{ + int i; + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return NULL; + return &krb5_enctypes_list[i]; +} diff --git a/src/lib/crypto/krb/hash_provider/Makefile.in b/src/lib/crypto/krb/hash_provider/Makefile.in new file mode 100644 index 000000000..ece3a99ba --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/Makefile.in @@ -0,0 +1,35 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/hash_provider +mydir=lib/crypto/krb/hash_provider +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../crc32 -I$(srcdir)/../../@CRYPTO_IMPL@/md4 \ + -I$(srcdir)/../../@CRYPTO_IMPL@/md5 -I$(srcdir)/../../@CRYPTO_IMPL@/sha1 +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=hash_provider +##DOS##OBJFILE=..\$(OUTPRE)hash_pro.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= hash_crc32.o hash_md4.o hash_md5.o hash_sha1.o + +OBJS= $(OUTPRE)hash_crc32.$(OBJEXT) $(OUTPRE)hash_md4.$(OBJEXT) \ + $(OUTPRE)hash_md5.$(OBJEXT) $(OUTPRE)hash_sha1.$(OBJEXT) + +SRCS= $(srcdir)/hash_crc32.c $(srcdir)/hash_md4.c \ + $(srcdir)/hash_md5.c $(srcdir)/hash_sha1.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/hash_provider/deps b/src/lib/crypto/krb/hash_provider/deps new file mode 100644 index 000000000..e59eade83 --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/deps @@ -0,0 +1,48 @@ +# +# Generated makefile dependencies follow. +# +hash_crc32.so hash_crc32.po $(OUTPRE)hash_crc32.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../crc32/crc-32.h hash_crc32.c hash_provider.h +hash_md4.so hash_md4.po $(OUTPRE)hash_md4.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/md4/rsa-md4.h hash_md4.c hash_provider.h +hash_md5.so hash_md5.po $(OUTPRE)hash_md5.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/md5/rsa-md5.h hash_md5.c hash_provider.h +hash_sha1.so hash_sha1.po $(OUTPRE)hash_sha1.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/sha1/shs.h hash_provider.h \ + hash_sha1.c diff --git a/src/lib/crypto/krb/hash_provider/hash_crc32.c b/src/lib/crypto/krb/hash_provider/hash_crc32.c new file mode 100644 index 000000000..ca2681067 --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/hash_crc32.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "crc-32.h" +#include "hash_provider.h" + +static krb5_error_code +k5_crc32_hash(unsigned int icount, const krb5_data *input, + krb5_data *output) +{ + unsigned long c, cn; + unsigned int i; + + if (output->length != CRC32_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + c = 0; + for (i=0; i<icount; i++) { + mit_crc32(input[i].data, input[i].length, &cn); + c ^= cn; + } + + store_32_le(c, output->data); + return(0); +} + +const struct krb5_hash_provider krb5int_hash_crc32 = { + CRC32_CKSUM_LENGTH, + 1, + k5_crc32_hash +}; diff --git a/src/lib/crypto/krb/hash_provider/hash_md4.c b/src/lib/crypto/krb/hash_provider/hash_md4.c new file mode 100644 index 000000000..1fa23c214 --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/hash_md4.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "rsa-md4.h" +#include "hash_provider.h" + +static krb5_error_code +k5_md4_hash(unsigned int icount, const krb5_data *input, + krb5_data *output) +{ + krb5_MD4_CTX ctx; + unsigned int i; + + if (output->length != RSA_MD4_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + krb5_MD4Init(&ctx); + for (i=0; i<icount; i++) + krb5_MD4Update(&ctx, (unsigned char *) input[i].data, input[i].length); + krb5_MD4Final(&ctx); + + memcpy(output->data, ctx.digest, RSA_MD4_CKSUM_LENGTH); + + return(0); +} + +const struct krb5_hash_provider krb5int_hash_md4 = { + RSA_MD4_CKSUM_LENGTH, + 64, + k5_md4_hash +}; diff --git a/src/lib/crypto/krb/hash_provider/hash_md5.c b/src/lib/crypto/krb/hash_provider/hash_md5.c new file mode 100644 index 000000000..174c432a4 --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/hash_md5.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "rsa-md5.h" +#include "hash_provider.h" + +static krb5_error_code +k5_md5_hash(unsigned int icount, const krb5_data *input, + krb5_data *output) +{ + krb5_MD5_CTX ctx; + unsigned int i; + + if (output->length != RSA_MD5_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + krb5_MD5Init(&ctx); + for (i=0; i<icount; i++) + krb5_MD5Update(&ctx, (unsigned char *) input[i].data, input[i].length); + krb5_MD5Final(&ctx); + + memcpy(output->data, ctx.digest, RSA_MD5_CKSUM_LENGTH); + + return(0); +} + +const struct krb5_hash_provider krb5int_hash_md5 = { + RSA_MD5_CKSUM_LENGTH, + 64, + k5_md5_hash +}; diff --git a/src/lib/crypto/krb/hash_provider/hash_provider.h b/src/lib/crypto/krb/hash_provider/hash_provider.h new file mode 100644 index 000000000..4fa46097d --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/hash_provider.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +extern const struct krb5_hash_provider krb5int_hash_crc32; +extern const struct krb5_hash_provider krb5int_hash_md4; +extern const struct krb5_hash_provider krb5int_hash_md5; +extern const struct krb5_hash_provider krb5int_hash_sha1; diff --git a/src/lib/crypto/krb/hash_provider/hash_sha1.c b/src/lib/crypto/krb/hash_provider/hash_sha1.c new file mode 100644 index 000000000..ffc073cf1 --- /dev/null +++ b/src/lib/crypto/krb/hash_provider/hash_sha1.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "shs.h" +#include "hash_provider.h" + +static krb5_error_code +k5_sha1_hash(unsigned int icount, const krb5_data *input, + krb5_data *output) +{ + SHS_INFO ctx; + unsigned int i; + + if (output->length != SHS_DIGESTSIZE) + return(KRB5_CRYPTO_INTERNAL); + + shsInit(&ctx); + for (i=0; i<icount; i++) + shsUpdate(&ctx, (unsigned char *) input[i].data, input[i].length); + shsFinal(&ctx); + + for (i=0; i<(sizeof(ctx.digest)/sizeof(ctx.digest[0])); i++) { + store_32_be(ctx.digest[i], &output->data[i*4]); + } + + return(0); +} + +const struct krb5_hash_provider krb5int_hash_sha1 = { + SHS_DIGESTSIZE, + SHS_DATASIZE, + k5_sha1_hash +}; diff --git a/src/lib/crypto/krb/keyblocks.c b/src/lib/crypto/krb/keyblocks.c new file mode 100644 index 000000000..5912c81b4 --- /dev/null +++ b/src/lib/crypto/krb/keyblocks.c @@ -0,0 +1,79 @@ +/* + * lib/crypto/keyblocks.c + * + * Copyright (C) 2002, 2005 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. + * + * + * + * krb5_init_keyblock- a function to set up + * an empty keyblock + */ + + +#include "k5-int.h" +#include <assert.h> + +krb5_error_code krb5int_c_init_keyblock + (krb5_context context, krb5_enctype enctype, + size_t length, krb5_keyblock **out) +{ + krb5_keyblock *kb; + kb = malloc (sizeof(krb5_keyblock)); + assert (out); + *out = NULL; + if (!kb) { + return ENOMEM; + } + kb->magic = KV5M_KEYBLOCK; + kb->enctype = enctype; + kb->length = length; + if(length) { + kb->contents = malloc (length); + if(!kb->contents) { + free (kb); + return ENOMEM; + } + } else { + kb->contents = NULL; + } + *out = kb; + return 0; +} + + +void +krb5int_c_free_keyblock(krb5_context context, register krb5_keyblock *val) +{ + krb5int_c_free_keyblock_contents(context, val); + free(val); +} + +void +krb5int_c_free_keyblock_contents(krb5_context context, krb5_keyblock *key) +{ + if (key && key->contents) { + krb5int_zap_data (key->contents, key->length); + free(key->contents); + key->contents = 0; + } +} diff --git a/src/lib/crypto/krb/keyed_checksum_types.c b/src/lib/crypto/krb/keyed_checksum_types.c new file mode 100644 index 000000000..04aa44757 --- /dev/null +++ b/src/lib/crypto/krb/keyed_checksum_types.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" +#include "cksumtypes.h" + +static int etype_match(krb5_enctype e1, krb5_enctype e2) +{ + int i1, i2; + + for (i1=0; i1<krb5_enctypes_length; i1++) + if (krb5_enctypes_list[i1].etype == e1) + break; + + for (i2=0; i2<krb5_enctypes_length; i2++) + if (krb5_enctypes_list[i2].etype == e2) + break; + + return((i1 < krb5_enctypes_length) && + (i2 < krb5_enctypes_length) && + (krb5_enctypes_list[i1].enc == krb5_enctypes_list[i2].enc)); +} + +krb5_error_code KRB5_CALLCONV +krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, + unsigned int *count, krb5_cksumtype **cksumtypes) +{ + unsigned int i, c; + + c = 0; + for (i=0; i<krb5_cksumtypes_length; i++) { + if ((krb5_cksumtypes_list[i].keyhash && + etype_match(krb5_cksumtypes_list[i].keyed_etype, enctype)) || + (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE)) { + c++; + } + } + + *count = c; + + if ((*cksumtypes = (krb5_cksumtype *) malloc(c*sizeof(krb5_cksumtype))) + == NULL) + return(ENOMEM); + + c = 0; + for (i=0; i<krb5_cksumtypes_length; i++) { + if ((krb5_cksumtypes_list[i].keyhash && + etype_match(krb5_cksumtypes_list[i].keyed_etype, enctype)) || + (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE)) { + (*cksumtypes)[c] = krb5_cksumtypes_list[i].ctype; + c++; + } + } + + return(0); +} + +void KRB5_CALLCONV +krb5_free_cksumtypes(krb5_context context, krb5_cksumtype *val) +{ + if (val) + free(val); + return; +} + diff --git a/src/lib/crypto/krb/keyed_cksum.c b/src/lib/crypto/krb/keyed_cksum.c new file mode 100644 index 000000000..023d8c6a5 --- /dev/null +++ b/src/lib/crypto/krb/keyed_cksum.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_boolean KRB5_CALLCONV +krb5_c_is_keyed_cksum(krb5_cksumtype ctype) +{ + unsigned int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == ctype) { + if (krb5_cksumtypes_list[i].keyhash || + (krb5_cksumtypes_list[i].flags & + KRB5_CKSUMFLAG_DERIVE)) + return(1); + else + return(0); + } + } + + /* ick, but it's better than coredumping, which is what the + old code would have done */ + return 0; /* error case */ +} + +krb5_boolean KRB5_CALLCONV +is_keyed_cksum(krb5_cksumtype ctype) +{ + return krb5_c_is_keyed_cksum (ctype); +} diff --git a/src/lib/crypto/krb/keyhash_provider/Makefile.in b/src/lib/crypto/krb/keyhash_provider/Makefile.in new file mode 100644 index 000000000..d84ce7967 --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/Makefile.in @@ -0,0 +1,34 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/keyhash_provider +mydir=lib/crypto/krb/keyhash_provider +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../../@CRYPTO_IMPL@/des -I$(srcdir)/../../@CRYPTO_IMPL@/md4 \ + -I$(srcdir)/../../@CRYPTO_IMPL@/md5 -I$(srcdir)/../../@CRYPTO_IMPL@/arcfour \ + -I$(srcdir)/../hash_provider +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=keyhash_provider +##DOS##OBJFILE=..\$(OUTPRE)kh_pro.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= descbc.o k5_md4des.o k5_md5des.o hmac_md5.o md5_hmac.o + +OBJS= $(OUTPRE)descbc.$(OBJEXT) $(OUTPRE)k5_md4des.$(OBJEXT) $(OUTPRE)k5_md5des.$(OBJEXT) $(OUTPRE)hmac_md5.$(OBJEXT) $(OUTPRE)md5_hmac.$(OBJEXT) + +SRCS= $(srcdir)/descbc.c $(srcdir)/k5_md4des.c $(srcdir)/k5_md5des.c $(srcdir)/hmac_md5.c $(srcdir)/md5_hmac.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/keyhash_provider/deps b/src/lib/crypto/krb/keyhash_provider/deps new file mode 100644 index 000000000..553676e67 --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/deps @@ -0,0 +1,65 @@ +# +# Generated makefile dependencies follow. +# +descbc.so descbc.po $(OUTPRE)descbc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/des/des_int.h \ + descbc.c keyhash_provider.h +k5_md4des.so k5_md4des.po $(OUTPRE)k5_md4des.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/des/des_int.h $(srcdir)/../../builtin/md4/rsa-md4.h \ + k5_md4des.c keyhash_provider.h +k5_md5des.so k5_md5des.po $(OUTPRE)k5_md5des.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/des/des_int.h $(srcdir)/../../builtin/md5/rsa-md5.h \ + k5_md5des.c keyhash_provider.h +hmac_md5.so hmac_md5.po $(OUTPRE)hmac_md5.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/arcfour/arcfour-int.h $(srcdir)/../../builtin/arcfour/arcfour.h \ + $(srcdir)/../../builtin/md5/rsa-md5.h $(srcdir)/../aead.h \ + $(srcdir)/../cksumtypes.h $(srcdir)/../hash_provider/hash_provider.h \ + hmac_md5.c keyhash_provider.h +md5_hmac.so md5_hmac.po $(OUTPRE)md5_hmac.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/arcfour/arcfour-int.h $(srcdir)/../../builtin/arcfour/arcfour.h \ + $(srcdir)/../../builtin/md5/rsa-md5.h $(srcdir)/../hash_provider/hash_provider.h \ + keyhash_provider.h md5_hmac.c diff --git a/src/lib/crypto/krb/keyhash_provider/descbc.c b/src/lib/crypto/krb/keyhash_provider/descbc.c new file mode 100644 index 000000000..bf68e324c --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/descbc.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "des_int.h" +#include "keyhash_provider.h" + +static krb5_error_code +k5_descbc_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + mit_des_key_schedule schedule; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_CRYPTO_INTERNAL); + if (output->length != 8) + return(KRB5_CRYPTO_INTERNAL); + + switch (mit_des_key_sched(key->contents, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* this has a return value, but it's useless to us */ + + mit_des_cbc_cksum((unsigned char *) input->data, + (unsigned char *) output->data, input->length, + schedule, + ivec? (const unsigned char *)ivec->data: + (const unsigned char *)mit_des_zeroblock); + + memset(schedule, 0, sizeof(schedule)); + + return(0); +} + +const struct krb5_keyhash_provider krb5int_keyhash_descbc = { + 8, + k5_descbc_hash, + NULL, + NULL, + NULL +}; diff --git a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c new file mode 100644 index 000000000..34ce67169 --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c @@ -0,0 +1,144 @@ +/* + * lib/crypto/keyhash_provider/hmac_md5.c + * + * Copyright 2001, 2009 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. + * + * + * Implementation of the Microsoft hmac-md5 checksum type. + * Implemented based on draft-brezak-win2k-krb-rc4-hmac-03 + */ + +#include "k5-int.h" +#include "keyhash_provider.h" +#include "arcfour-int.h" +#include "rsa-md5.h" +#include "hash_provider.h" +#include "../aead.h" + +static krb5_error_code +k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *iv, + const krb5_data *input, krb5_data *output) +{ + krb5_keyusage ms_usage; + krb5_error_code ret; + krb5_keyblock ks; + krb5_data ds, ks_constant, md5tmp; + krb5_MD5_CTX ctx; + char t[4]; + + + ds.length = key->length; + ks.length = key->length; + ds.data = malloc(ds.length); + if (ds.data == NULL) + return ENOMEM; + ks.contents = (void *) ds.data; + + ks_constant.data = "signaturekey"; + ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/ + + ret = krb5_hmac( &krb5int_hash_md5, key, 1, + &ks_constant, &ds); + if (ret) + goto cleanup; + + krb5_MD5Init (&ctx); + ms_usage = krb5int_arcfour_translate_usage (usage); + store_32_le(ms_usage, t); + krb5_MD5Update (&ctx, (unsigned char * ) &t, 4); + krb5_MD5Update (&ctx, (unsigned char *) input-> data, + (unsigned int) input->length ); + krb5_MD5Final(&ctx); + md5tmp.data = (void *) ctx.digest; + md5tmp.length = 16; + ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp, + output); + + cleanup: + memset(&ctx, 0, sizeof(ctx)); + memset (ks.contents, 0, ks.length); + free (ks.contents); + return ret; +} + +static krb5_error_code +k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *iv, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + krb5_keyusage ms_usage; + krb5_error_code ret; + krb5_keyblock ks; + krb5_data ds, ks_constant, md5tmp; + krb5_MD5_CTX ctx; + char t[4]; + size_t i; + + ds.length = key->length; + ks.length = key->length; + ds.data = malloc(ds.length); + if (ds.data == NULL) + return ENOMEM; + ks.contents = (void *) ds.data; + + ks_constant.data = "signaturekey"; + ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/ + + ret = krb5_hmac( &krb5int_hash_md5, key, 1, + &ks_constant, &ds); + if (ret) + goto cleanup; + + krb5_MD5Init (&ctx); + ms_usage = krb5int_arcfour_translate_usage (usage); + store_32_le(ms_usage, t); + krb5_MD5Update (&ctx, (unsigned char * ) &t, 4); + for (i = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + krb5_MD5Update (&ctx, (unsigned char *)iov->data.data, + (unsigned int)iov->data.length); + } + krb5_MD5Final(&ctx); + md5tmp.data = (void *) ctx.digest; + md5tmp.length = 16; + ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp, + output); + + cleanup: + memset(&ctx, 0, sizeof(ctx)); + memset (ks.contents, 0, ks.length); + free (ks.contents); + return ret; +} + +const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5 = { + 16, + k5_hmac_md5_hash, + NULL, /*checksum again*/ + k5_hmac_md5_hash_iov, + NULL /*checksum again */ +}; diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c new file mode 100644 index 000000000..fceb58ebd --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "des_int.h" +#include "rsa-md4.h" +#include "keyhash_provider.h" + +#define CONFLENGTH 8 + +/* Force acceptance of krb5-beta5 md4des checksum for now. */ +#define KRB5_MD4DES_BETA5_COMPAT + +/* des-cbc(xorkey, conf | rsa-md4(conf | data)) */ + +/* this could be done in terms of the md4 and des providers, but + that's less efficient, and there's no need for this to be generic */ + +static krb5_error_code +k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + krb5_error_code ret; + krb5_data data; + krb5_MD4_CTX ctx; + unsigned char conf[CONFLENGTH]; + unsigned char xorkey[8]; + unsigned int i; + mit_des_key_schedule schedule; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (output->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) + return(KRB5_CRYPTO_INTERNAL); + + /* create the confouder */ + + data.length = CONFLENGTH; + data.data = (char *) conf; + if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &data))) + return(ret); + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + for (i=0; i<sizeof(xorkey); i++) + xorkey[i] ^= 0xf0; + + switch (ret = mit_des_key_sched(xorkey, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* hash the confounder, then the input data */ + + krb5_MD4Init(&ctx); + krb5_MD4Update(&ctx, conf, CONFLENGTH); + krb5_MD4Update(&ctx, (unsigned char *) input->data, + (unsigned int) input->length); + krb5_MD4Final(&ctx); + + /* construct the buffer to be encrypted */ + + memcpy(output->data, conf, CONFLENGTH); + memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH); + + /* encrypt it, in place. this has a return value, but it's + always zero. */ + + mit_des_cbc_encrypt((krb5_pointer) output->data, + (krb5_pointer) output->data, output->length, + schedule, (const unsigned char *) mit_des_zeroblock, + 1); + + return(0); +} + +static krb5_error_code +k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, const krb5_data *hash, + krb5_boolean *valid) +{ + krb5_MD4_CTX ctx; + unsigned char plaintext[CONFLENGTH+RSA_MD4_CKSUM_LENGTH]; + unsigned char xorkey[8]; + unsigned int i; + mit_des_key_schedule schedule; + int compathash = 0; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) { +#ifdef KRB5_MD4DES_BETA5_COMPAT + if (hash->length != RSA_MD4_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + else + compathash = 1; +#else + return(KRB5_CRYPTO_INTERNAL); +#endif + return(KRB5_CRYPTO_INTERNAL); + } + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + if (!compathash) { + for (i=0; i<sizeof(xorkey); i++) + xorkey[i] ^= 0xf0; + } + + switch (mit_des_key_sched(xorkey, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* decrypt it. this has a return value, but it's always zero. */ + + if (!compathash) { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, + (const unsigned char *) mit_des_zeroblock, 0); + } else { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, xorkey, 0); + } + + /* hash the confounder, then the input data */ + + krb5_MD4Init(&ctx); + if (!compathash) { + krb5_MD4Update(&ctx, plaintext, CONFLENGTH); + } + krb5_MD4Update(&ctx, (unsigned char *) input->data, + (unsigned int) input->length); + krb5_MD4Final(&ctx); + + /* compare the decrypted hash to the computed one */ + + if (!compathash) { + *valid = + (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH) + == 0); + } else { + *valid = + (memcmp(plaintext, ctx.digest, RSA_MD4_CKSUM_LENGTH) == 0); + } + + memset(plaintext, 0, sizeof(plaintext)); + + return(0); +} + +const struct krb5_keyhash_provider krb5int_keyhash_md4des = { + CONFLENGTH+RSA_MD4_CKSUM_LENGTH, + k5_md4des_hash, + k5_md4des_verify, + NULL, + NULL +}; diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c new file mode 100644 index 000000000..0175c68ab --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "des_int.h" +#include "rsa-md5.h" +#include "keyhash_provider.h" + +#define CONFLENGTH 8 + +/* Force acceptance of krb5-beta5 md5des checksum for now. */ +#define KRB5_MD5DES_BETA5_COMPAT + +/* des-cbc(xorkey, conf | rsa-md5(conf | data)) */ + +/* this could be done in terms of the md5 and des providers, but + that's less efficient, and there's no need for this to be generic */ + +static krb5_error_code +k5_md5des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + krb5_error_code ret; + krb5_data data; + krb5_MD5_CTX ctx; + unsigned char conf[CONFLENGTH]; + unsigned char xorkey[8]; + unsigned int i; + mit_des_key_schedule schedule; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (output->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) + return(KRB5_CRYPTO_INTERNAL); + + /* create the confouder */ + + data.length = CONFLENGTH; + data.data = (char *) conf; + if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &data))) + return(ret); + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + for (i=0; i<sizeof(xorkey); i++) + xorkey[i] ^= 0xf0; + + switch (ret = mit_des_key_sched(xorkey, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* hash the confounder, then the input data */ + + krb5_MD5Init(&ctx); + krb5_MD5Update(&ctx, conf, CONFLENGTH); + krb5_MD5Update(&ctx, (unsigned char *) input->data, + (unsigned int) input->length); + krb5_MD5Final(&ctx); + + /* construct the buffer to be encrypted */ + + memcpy(output->data, conf, CONFLENGTH); + memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH); + + /* encrypt it, in place. this has a return value, but it's + always zero. */ + + mit_des_cbc_encrypt((krb5_pointer) output->data, + (krb5_pointer) output->data, output->length, + schedule, (const unsigned char *) mit_des_zeroblock, + 1); + + return(0); +} + +static krb5_error_code +k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, + const krb5_data *input, const krb5_data *hash, + krb5_boolean *valid) +{ + krb5_MD5_CTX ctx; + unsigned char plaintext[CONFLENGTH+RSA_MD5_CKSUM_LENGTH]; + unsigned char xorkey[8]; + unsigned int i; + mit_des_key_schedule schedule; + int compathash = 0; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) { +#ifdef KRB5_MD5DES_BETA5_COMPAT + if (hash->length != RSA_MD5_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + else + compathash = 1; +#else + return(KRB5_CRYPTO_INTERNAL); +#endif + } + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + if (!compathash) { + for (i=0; i<sizeof(xorkey); i++) + xorkey[i] ^= 0xf0; + } + + switch (mit_des_key_sched(xorkey, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* decrypt it. this has a return value, but it's always zero. */ + + if (!compathash) { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, + (const unsigned char *) mit_des_zeroblock, 0); + } else { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, xorkey, 0); + } + + /* hash the confounder, then the input data */ + + krb5_MD5Init(&ctx); + if (!compathash) { + krb5_MD5Update(&ctx, plaintext, CONFLENGTH); + } + krb5_MD5Update(&ctx, (unsigned char *) input->data, + (unsigned) input->length); + krb5_MD5Final(&ctx); + + /* compare the decrypted hash to the computed one */ + + if (!compathash) { + *valid = + (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH) + == 0); + } else { + *valid = + (memcmp(plaintext, ctx.digest, RSA_MD5_CKSUM_LENGTH) == 0); + } + memset(plaintext, 0, sizeof(plaintext)); + + return(0); +} + +const struct krb5_keyhash_provider krb5int_keyhash_md5des = { + CONFLENGTH+RSA_MD5_CKSUM_LENGTH, + k5_md5des_hash, + k5_md5des_verify, + NULL, + NULL +}; diff --git a/src/lib/crypto/krb/keyhash_provider/keyhash_provider.h b/src/lib/crypto/krb/keyhash_provider/keyhash_provider.h new file mode 100644 index 000000000..8ac91e19d --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/keyhash_provider.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +extern const struct krb5_keyhash_provider krb5int_keyhash_descbc; +extern const struct krb5_keyhash_provider krb5int_keyhash_md4des; +extern const struct krb5_keyhash_provider krb5int_keyhash_md5des; +extern const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5; +extern const struct krb5_keyhash_provider krb5int_keyhash_md5_hmac; +extern const struct krb5_keyhash_provider krb5int_keyhash_aescbc_128; +extern const struct krb5_keyhash_provider krb5int_keyhash_aescbc_256; diff --git a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c new file mode 100644 index 000000000..d05b97f00 --- /dev/null +++ b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c @@ -0,0 +1,65 @@ +/* + * lib/crypto/keyhash_provider/md5_hmac.c + * + * Copyright 2001, 2009 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. + * + * Implementation of Microsoft KERB_CHECKSUM_MD5_HMAC + */ + +#include "k5-int.h" +#include "keyhash_provider.h" +#include "arcfour-int.h" +#include "rsa-md5.h" +#include "hash_provider.h" + +static krb5_error_code +k5_md5_hmac_hash (const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *iv, + const krb5_data *input, krb5_data *output) +{ + krb5_keyusage ms_usage; + krb5_MD5_CTX ctx; + unsigned char t[4]; + krb5_data ds; + + krb5_MD5Init(&ctx); + + ms_usage = krb5int_arcfour_translate_usage (usage); + store_32_le(ms_usage, t); + krb5_MD5Update(&ctx, t, sizeof(t)); + krb5_MD5Update(&ctx, (unsigned char *)input->data, input->length); + krb5_MD5Final(&ctx); + + ds.magic = KV5M_DATA; + ds.length = 16; + ds.data = (char *)ctx.digest; + + return krb5_hmac ( &krb5int_hash_md5, key, 1, &ds, output); +} + +const struct krb5_keyhash_provider krb5int_keyhash_md5_hmac = { + 16, + k5_md5_hmac_hash, + NULL /*checksum again*/ +}; + diff --git a/src/lib/crypto/krb/keylengths.c b/src/lib/crypto/krb/keylengths.c new file mode 100644 index 000000000..acd1da81b --- /dev/null +++ b/src/lib/crypto/krb/keylengths.c @@ -0,0 +1,61 @@ +/* + * COPYRIGHT (c) 2006 + * The Regents of the University of Michigan + * ALL RIGHTS RESERVED + * + * Permission is granted to use, copy, create derivative works + * and redistribute this software and such derivative works + * for any purpose, so long as the name of The University of + * Michigan is not used in any advertising or publicity + * pertaining to the use of distribution of this software + * without specific, written prior authorization. If the + * above copyright notice or any other identification of the + * University of Michigan is included in any copy of any + * portion of this software, then the disclaimer below must + * also be included. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +#include "k5-int.h" +#include "etypes.h" + +/* + * keybytes is the number of bytes required as input to make a key, + * keylength is the length of the final key in bytes + */ +krb5_error_code KRB5_CALLCONV +krb5_c_keylengths(krb5_context context, krb5_enctype enctype, + size_t *keybytes, size_t *keylength) +{ + int i; + + if (keybytes == NULL && keylength == NULL) + return(EINVAL); + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + if (keybytes) + *keybytes = krb5_enctypes_list[i].enc->keybytes; + if (keylength) + *keylength = krb5_enctypes_list[i].enc->keylength; + + return(0); +} diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c new file mode 100644 index 000000000..ad532b27d --- /dev/null +++ b/src/lib/crypto/krb/make_checksum.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" +#include "etypes.h" +#include "dk.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *input, krb5_checksum *cksum) +{ + unsigned int i; + int e1, e2; + krb5_data data; + krb5_error_code ret; + size_t cksumlen; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + if (krb5_cksumtypes_list[i].keyhash) + cksumlen = krb5_cksumtypes_list[i].keyhash->hashsize; + else + cksumlen = krb5_cksumtypes_list[i].hash->hashsize; + + cksum->length = cksumlen; + + if ((cksum->contents = (krb5_octet *) malloc(cksum->length)) == NULL) + return(ENOMEM); + + data.length = cksum->length; + data.data = (char *) cksum->contents; + + if (krb5_cksumtypes_list[i].keyhash) { + /* check if key is compatible */ + const struct krb5_keyhash_provider *keyhash; + + keyhash = krb5_cksumtypes_list[i].keyhash; + + if (krb5_cksumtypes_list[i].keyed_etype) { + for (e1=0; e1<krb5_enctypes_length; e1++) + if (krb5_enctypes_list[e1].etype == + krb5_cksumtypes_list[i].keyed_etype) + break; + + for (e2=0; e2<krb5_enctypes_length; e2++) + if (krb5_enctypes_list[e2].etype == key->enctype) + break; + + if ((e1 == krb5_enctypes_length) || + (e2 == krb5_enctypes_length) || + (krb5_enctypes_list[e1].enc != krb5_enctypes_list[e2].enc)) { + ret = KRB5_BAD_ENCTYPE; + goto cleanup; + } + } + + if (keyhash->hash == NULL) { + krb5_crypto_iov iov[1]; + + iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + iov[0].data = *input; + + assert(keyhash->hash_iov != NULL); + + ret = (*keyhash->hash_iov)(key, usage, 0, iov, 1, &data); + } else { + ret = (*keyhash->hash)(key, usage, 0, input, &data); + } + } else if (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE) { + ret = krb5_dk_make_checksum(krb5_cksumtypes_list[i].hash, + key, usage, input, &data); + } else { + /* no key is used */ + + ret = (*(krb5_cksumtypes_list[i].hash->hash))(1, input, &data); + } + + if (!ret) { + cksum->magic = KV5M_CHECKSUM; + cksum->checksum_type = cksumtype; + if (krb5_cksumtypes_list[i].trunc_size) { + krb5_octet *trunc; + cksum->length = krb5_cksumtypes_list[i].trunc_size; + trunc = (krb5_octet *) realloc(cksum->contents, cksum->length); + if (trunc) + cksum->contents = trunc; + } + } + +cleanup: + if (ret) { + memset(cksum->contents, 0, cksum->length); + free(cksum->contents); + cksum->contents = NULL; + } + + return(ret); +} diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c new file mode 100644 index 000000000..3cf4af605 --- /dev/null +++ b/src/lib/crypto/krb/make_checksum_iov.c @@ -0,0 +1,82 @@ +/* + * lib/crypto/make_checksum_iov.c + * + * Copyright 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 "cksumtypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_make_checksum_iov(krb5_context context, + krb5_cksumtype cksumtype, + const krb5_keyblock *key, + krb5_keyusage usage, + krb5_crypto_iov *data, + size_t num_data) +{ + unsigned int i; + size_t cksumlen; + krb5_error_code ret; + krb5_data cksum_data; + krb5_crypto_iov *checksum; + + for (i = 0; i < krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + if (krb5_cksumtypes_list[i].keyhash != NULL) + cksum_data.length = krb5_cksumtypes_list[i].keyhash->hashsize; + else + cksum_data.length = krb5_cksumtypes_list[i].hash->hashsize; + + if (krb5_cksumtypes_list[i].trunc_size != 0) + cksumlen = krb5_cksumtypes_list[i].trunc_size; + else + cksumlen = cksum_data.length; + + checksum = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); + if (checksum == NULL || checksum->data.length < cksumlen) + return(KRB5_BAD_MSIZE); + + cksum_data.data = malloc(cksum_data.length); + if (cksum_data.data == NULL) + return(ENOMEM); + + ret = krb5int_c_make_checksum_iov(&krb5_cksumtypes_list[i], + key, usage, data, num_data, + &cksum_data); + if (ret == 0) { + memcpy(checksum->data.data, cksum_data.data, cksumlen); + checksum->data.length = cksumlen; + } + + free(cksum_data.data); + + return(ret); +} diff --git a/src/lib/crypto/krb/make_random_key.c b/src/lib/crypto/krb/make_random_key.c new file mode 100644 index 000000000..0ae321dca --- /dev/null +++ b/src/lib/crypto/krb/make_random_key.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_make_random_key(krb5_context context, krb5_enctype enctype, + krb5_keyblock *random_key) +{ + int i; + krb5_error_code ret; + const struct krb5_enc_provider *enc; + size_t keybytes, keylength; + krb5_data random_data; + unsigned char *bytes; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + keybytes = enc->keybytes; + keylength = enc->keylength; + + if ((bytes = (unsigned char *) malloc(keybytes)) == NULL) + return(ENOMEM); + if ((random_key->contents = (krb5_octet *) malloc(keylength)) == NULL) { + free(bytes); + return(ENOMEM); + } + + random_data.data = (char *) bytes; + random_data.length = keybytes; + + if ((ret = krb5_c_random_make_octets(context, &random_data))) + goto cleanup; + + random_key->magic = KV5M_KEYBLOCK; + random_key->enctype = enctype; + random_key->length = keylength; + + ret = ((*(enc->make_key))(&random_data, random_key)); + +cleanup: + memset(bytes, 0, keybytes); + free(bytes); + + if (ret) { + memset(random_key->contents, 0, keylength); + free(random_key->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/krb/mandatory_sumtype.c b/src/lib/crypto/krb/mandatory_sumtype.c new file mode 100644 index 000000000..f9322ff3f --- /dev/null +++ b/src/lib/crypto/krb/mandatory_sumtype.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2003 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 "etypes.h" + +krb5_error_code +krb5int_c_mandatory_cksumtype (krb5_context ctx, krb5_enctype etype, + krb5_cksumtype *cksumtype) +{ + int i; + + for (i = 0; i < krb5_enctypes_length; i++) + if (krb5_enctypes_list[i].etype == etype) { + *cksumtype = krb5_enctypes_list[i].required_ctype; + return 0; + } + + return KRB5_BAD_ENCTYPE; +} diff --git a/src/lib/crypto/krb/nfold.c b/src/lib/crypto/krb/nfold.c new file mode 100644 index 000000000..1f1902d1c --- /dev/null +++ b/src/lib/crypto/krb/nfold.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif + +/* +n-fold(k-bits): + l = lcm(n,k) + r = l/k + s = k-bits | k-bits rot 13 | k-bits rot 13*2 | ... | k-bits rot 13*(r-1) + compute the 1's complement sum: + n-fold = s[0..n-1]+s[n..2n-1]+s[2n..3n-1]+..+s[(k-1)*n..k*n-1] +*/ + +/* representation: msb first, assume n and k are multiples of 8, and + that k>=16. this is the case of all the cryptosystems which are + likely to be used. this function can be replaced if that + assumption ever fails. */ + +/* input length is in bits */ + +void +krb5_nfold(unsigned int inbits, const unsigned char *in, unsigned int outbits, + unsigned char *out) +{ + int a,b,c,lcm; + int byte, i, msbit; + + /* the code below is more readable if I make these bytes + instead of bits */ + + inbits >>= 3; + outbits >>= 3; + + /* first compute lcm(n,k) */ + + a = outbits; + b = inbits; + + while(b != 0) { + c = b; + b = a%b; + a = c; + } + + lcm = outbits*inbits/a; + + /* now do the real work */ + + memset(out, 0, outbits); + byte = 0; + + /* this will end up cycling through k lcm(k,n)/k times, which + is correct */ + for (i=lcm-1; i>=0; i--) { + /* compute the msbit in k which gets added into this byte */ + msbit = (/* first, start with the msbit in the first, unrotated + byte */ + ((inbits<<3)-1) + /* then, for each byte, shift to the right for each + repetition */ + +(((inbits<<3)+13)*(i/inbits)) + /* last, pick out the correct byte within that + shifted repetition */ + +((inbits-(i%inbits))<<3) + )%(inbits<<3); + + /* pull out the byte value itself */ + byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| + (in[((inbits)-(msbit>>3))%inbits])) + >>((msbit&7)+1))&0xff; + + /* do the addition */ + byte += out[i%outbits]; + out[i%outbits] = byte&0xff; + +#if 0 + printf("msbit[%d] = %d\tbyte = %02x\tsum = %03x\n", i, msbit, + (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| + (in[((inbits)-(msbit>>3))%inbits])) + >>((msbit&7)+1))&0xff, byte); +#endif + + /* keep around the carry bit, if any */ + byte >>= 8; + +#if 0 + printf("carry=%d\n", byte); +#endif + } + + /* if there's a carry bit left over, add it back in */ + if (byte) { + for (i=outbits-1; i>=0; i--) { + /* do the addition */ + byte += out[i]; + out[i] = byte&0xff; + + /* keep around the carry bit, if any */ + byte >>= 8; + } + } +} + diff --git a/src/lib/crypto/krb/old/Makefile.in b/src/lib/crypto/krb/old/Makefile.in new file mode 100644 index 000000000..4370f1ffb --- /dev/null +++ b/src/lib/crypto/krb/old/Makefile.in @@ -0,0 +1,35 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/old +mydir=lib/crypto/krb/old +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../../@CRYPTO_IMPL@/des -I$(srcdir) +DEFS= + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=old +##DOS##OBJFILE=..\$(OUTPRE)old.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= old_decrypt.o old_encrypt.o des_stringtokey.o + +OBJS= $(OUTPRE)des_stringtokey.$(OBJEXT) $(OUTPRE)old_decrypt.$(OBJEXT) $(OUTPRE)old_encrypt.$(OBJEXT) + +SRCS= $(srcdir)/des_stringtokey.c $(srcdir)/old_decrypt.c \ + $(srcdir)/old_encrypt.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/old/deps b/src/lib/crypto/krb/old/deps new file mode 100644 index 000000000..e2e71c213 --- /dev/null +++ b/src/lib/crypto/krb/old/deps @@ -0,0 +1,37 @@ +# +# Generated makefile dependencies follow. +# +des_stringtokey.so des_stringtokey.po $(OUTPRE)des_stringtokey.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../../builtin/des/des_int.h des_stringtokey.c \ + old.h +old_decrypt.so old_decrypt.po $(OUTPRE)old_decrypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + old.h old_decrypt.c +old_encrypt.so old_encrypt.po $(OUTPRE)old_encrypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + old.h old_encrypt.c diff --git a/src/lib/crypto/krb/old/des_stringtokey.c b/src/lib/crypto/krb/old/des_stringtokey.c new file mode 100644 index 000000000..2bacb4ef9 --- /dev/null +++ b/src/lib/crypto/krb/old/des_stringtokey.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "old.h" +#include <des_int.h> + +/* XXX */ +extern krb5_error_code mit_des_string_to_key_int +(krb5_keyblock * keyblock, + const krb5_data * data, + const krb5_data * salt); + +krb5_error_code +krb5int_des_string_to_key(const struct krb5_enc_provider *enc, + const krb5_data *string, + const krb5_data *salt, const krb5_data *parm, + krb5_keyblock *key) +{ + int type; + if (parm ) { + if (parm->length != 1) + return KRB5_ERR_BAD_S2K_PARAMS; + type = parm->data[0]; + } + else type = 0; + switch(type) { + case 0: + return(mit_des_string_to_key_int(key, string, salt)); + case 1: + return mit_afs_string_to_key(key, string, salt); + default: + return KRB5_ERR_BAD_S2K_PARAMS; + } +} diff --git a/src/lib/crypto/krb/old/old.h b/src/lib/crypto/krb/old/old.h new file mode 100644 index 000000000..94ee6421e --- /dev/null +++ b/src/lib/crypto/krb/old/old.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +void krb5_old_encrypt_length +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t input, size_t *length); + +krb5_error_code krb5_old_encrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output); + +krb5_error_code krb5_old_decrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); + +krb5_error_code krb5int_des_string_to_key +(const struct krb5_enc_provider *enc, + const krb5_data *string, const krb5_data *salt, + const krb5_data *params, + krb5_keyblock *key); diff --git a/src/lib/crypto/krb/old/old_decrypt.c b/src/lib/crypto/krb/old/old_decrypt.c new file mode 100644 index 000000000..cfbbd7272 --- /dev/null +++ b/src/lib/crypto/krb/old/old_decrypt.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "old.h" + +krb5_error_code +krb5_old_decrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, + krb5_data *arg_output) +{ + krb5_error_code ret; + size_t blocksize, hashsize, plainsize; + unsigned char *cksumdata, *cn; + krb5_data output, cksum, crcivec; + int alloced; + + blocksize = enc->block_size; + hashsize = hash->hashsize; + + plainsize = input->length - blocksize - hashsize; + + if (arg_output->length < plainsize) + return(KRB5_BAD_MSIZE); + + /* if there's enough space to work in the app buffer, use it, + otherwise allocate our own */ + + if ((cksumdata = (unsigned char *) malloc(hashsize)) == NULL) + return(ENOMEM); + + if (arg_output->length < input->length) { + output.length = input->length; + + if ((output.data = (char *) malloc(output.length)) == NULL) { + free(cksumdata); + return(ENOMEM); + } + + alloced = 1; + } else { + output.length = input->length; + + output.data = arg_output->data; + + alloced = 0; + } + + /* decrypt it */ + + /* save last ciphertext block in case we decrypt in place */ + if (ivec != NULL && ivec->length == blocksize) { + cn = malloc(blocksize); + if (cn == NULL) { + ret = ENOMEM; + goto cleanup; + } + memcpy(cn, input->data + input->length - blocksize, blocksize); + } else + cn = NULL; + + /* XXX this is gross, but I don't have much choice */ + if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { + crcivec.length = key->length; + crcivec.data = (char *) key->contents; + ivec = &crcivec; + } + + if ((ret = ((*(enc->decrypt))(key, ivec, input, &output)))) + goto cleanup; + + /* verify the checksum */ + + memcpy(cksumdata, output.data+blocksize, hashsize); + memset(output.data+blocksize, 0, hashsize); + + cksum.length = hashsize; + cksum.data = output.data+blocksize; + + if ((ret = ((*(hash->hash))(1, &output, &cksum)))) + goto cleanup; + + if (memcmp(cksum.data, cksumdata, cksum.length) != 0) { + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto cleanup; + } + + /* copy the plaintext around */ + + if (alloced) { + memcpy(arg_output->data, output.data+blocksize+hashsize, + plainsize); + } else { + memmove(arg_output->data, arg_output->data+blocksize+hashsize, + plainsize); + } + arg_output->length = plainsize; + + /* update ivec */ + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); + + ret = 0; + +cleanup: + if (alloced) { + memset(output.data, 0, output.length); + free(output.data); + } + + if (cn != NULL) + free(cn); + memset(cksumdata, 0, hashsize); + free(cksumdata); + return(ret); +} diff --git a/src/lib/crypto/krb/old/old_encrypt.c b/src/lib/crypto/krb/old/old_encrypt.c new file mode 100644 index 000000000..98bd109e0 --- /dev/null +++ b/src/lib/crypto/krb/old/old_encrypt.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "old.h" + +void +krb5_old_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, + size_t *length) +{ + size_t blocksize, hashsize; + + blocksize = enc->block_size; + hashsize = hash->hashsize; + + *length = krb5_roundup(blocksize+hashsize+inputlen, blocksize); +} + +krb5_error_code +krb5_old_encrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, + krb5_data *output) +{ + krb5_error_code ret; + size_t blocksize, hashsize, enclen; + krb5_data datain, crcivec; + int real_ivec; + + blocksize = enc->block_size; + hashsize = hash->hashsize; + + krb5_old_encrypt_length(enc, hash, input->length, &enclen); + + if (output->length < enclen) + return(KRB5_BAD_MSIZE); + + output->length = enclen; + + /* fill in confounded, padded, plaintext buffer with zero checksum */ + + memset(output->data, 0, output->length); + + datain.length = blocksize; + datain.data = output->data; + + if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &datain))) + return(ret); + memcpy(output->data+blocksize+hashsize, input->data, input->length); + + /* compute the checksum */ + + datain.length = hashsize; + datain.data = output->data+blocksize; + + if ((ret = ((*(hash->hash))(1, output, &datain)))) + goto cleanup; + + /* encrypt it */ + + /* XXX this is gross, but I don't have much choice */ + if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { + crcivec.length = key->length; + crcivec.data = (char *) key->contents; + ivec = &crcivec; + real_ivec = 0; + } else + real_ivec = 1; + + if ((ret = ((*(enc->encrypt))(key, ivec, output, output)))) + goto cleanup; + + /* update ivec */ + if (real_ivec && ivec != NULL && ivec->length == blocksize) + memcpy(ivec->data, output->data + output->length - blocksize, + blocksize); +cleanup: + if (ret) + memset(output->data, 0, output->length); + + return(ret); +} diff --git a/src/lib/crypto/krb/old_api_glue.c b/src/lib/crypto/krb/old_api_glue.c new file mode 100644 index 000000000..4db0c3359 --- /dev/null +++ b/src/lib/crypto/krb/old_api_glue.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +krb5_error_code KRB5_CALLCONV +krb5_encrypt(krb5_context context, krb5_const_pointer inptr, + krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock, + krb5_pointer ivec) +{ + krb5_data inputd, ivecd; + krb5_enc_data outputd; + size_t blocksize, outlen; + krb5_error_code ret; + + if (ivec) { + if ((ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize))) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + /* size is the length of the input cleartext data */ + inputd.length = size; + inputd.data = inptr; + + /* The size of the output buffer isn't part of the old api. Not too + safe. So, we assume here that it's big enough. */ + if ((ret = krb5_c_encrypt_length(context, eblock->key->enctype, size, + &outlen))) + return(ret); + + outputd.ciphertext.length = outlen; + outputd.ciphertext.data = outptr; + + return(krb5_c_encrypt(context, eblock->key, 0, ivec?&ivecd:0, + &inputd, &outputd)); +} + +krb5_error_code KRB5_CALLCONV +krb5_decrypt(krb5_context context, krb5_const_pointer inptr, + krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock, + krb5_pointer ivec) +{ + krb5_enc_data inputd; + krb5_data outputd, ivecd; + size_t blocksize; + krb5_error_code ret; + + if (ivec) { + if ((ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize))) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + /* size is the length of the input ciphertext data */ + inputd.enctype = eblock->key->enctype; + inputd.ciphertext.length = size; + inputd.ciphertext.data = inptr; + + /* we don't really know how big this is, but the code tends to assume + that the output buffer size should be the same as the input + buffer size */ + outputd.length = size; + outputd.data = outptr; + + return(krb5_c_decrypt(context, eblock->key, 0, ivec?&ivecd:0, + &inputd, &outputd)); +} + +krb5_error_code KRB5_CALLCONV +krb5_process_key(krb5_context context, krb5_encrypt_block *eblock, + const krb5_keyblock *key) +{ + eblock->key = (krb5_keyblock *) key; + + return(0); +} + +krb5_error_code KRB5_CALLCONV +krb5_finish_key(krb5_context context, krb5_encrypt_block *eblock) +{ + return(0); +} + +krb5_error_code KRB5_CALLCONV +krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock, + krb5_keyblock *keyblock, const krb5_data *data, + const krb5_data *salt) +{ + return(krb5_c_string_to_key(context, eblock->crypto_entry, data, salt, + keyblock)); +} + +krb5_error_code KRB5_CALLCONV +krb5_init_random_key(krb5_context context, const krb5_encrypt_block *eblock, + const krb5_keyblock *keyblock, krb5_pointer *ptr) +{ + krb5_data data; + + data.length = keyblock->length; + data.data = (char *) keyblock->contents; + + return(krb5_c_random_seed(context, &data)); +} + +krb5_error_code KRB5_CALLCONV +krb5_finish_random_key(krb5_context context, const krb5_encrypt_block *eblock, + krb5_pointer *ptr) +{ + return(0); +} + +krb5_error_code KRB5_CALLCONV +krb5_random_key(krb5_context context, const krb5_encrypt_block *eblock, + krb5_pointer ptr, krb5_keyblock **keyblock) +{ + krb5_keyblock *key; + krb5_error_code ret; + + if ((key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL) + return(ENOMEM); + + if ((ret = krb5_c_make_random_key(context, eblock->crypto_entry, key))) { + free(key); + key = NULL; + } + + *keyblock = key; + + return(ret); +} + +krb5_enctype KRB5_CALLCONV +krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block *eblock) +{ + return(eblock->crypto_entry); +} + +krb5_error_code KRB5_CALLCONV +krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock, + krb5_enctype enctype) +{ + eblock->crypto_entry = enctype; + + return(0); +} + +size_t KRB5_CALLCONV +krb5_encrypt_size(size_t length, krb5_enctype crypto) +{ + size_t ret; + + if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret)) + return(-1); /* XXX */ + + return(ret); +} + +size_t KRB5_CALLCONV +krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) +{ + size_t ret; + + if (krb5_c_checksum_length(context, ctype, &ret)) + return(-1); /* XXX */ + + return(ret); +} + +krb5_error_code KRB5_CALLCONV +krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype, + krb5_const_pointer in, size_t in_length, + krb5_const_pointer seed, size_t seed_length, + krb5_checksum *outcksum) +{ + krb5_data input; + krb5_keyblock key; + krb5_error_code ret; + krb5_checksum cksum; + + input.data = in; + input.length = in_length; + + key.length = seed_length; + key.contents = seed; + + if ((ret = krb5_c_make_checksum(context, ctype, &key, 0, &input, &cksum))) + return(ret); + + if (outcksum->length < cksum.length) { + memset(cksum.contents, 0, cksum.length); + free(cksum.contents); + return(KRB5_BAD_MSIZE); + } + + outcksum->magic = cksum.magic; + outcksum->checksum_type = cksum.checksum_type; + memcpy(outcksum->contents, cksum.contents, cksum.length); + outcksum->length = cksum.length; + + free(cksum.contents); + + return(0); +} + +krb5_error_code KRB5_CALLCONV +krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype, + const krb5_checksum *cksum, krb5_const_pointer in, + size_t in_length, krb5_const_pointer seed, + size_t seed_length) +{ + krb5_data input; + krb5_keyblock key; + krb5_error_code ret; + krb5_boolean valid; + + input.data = in; + input.length = in_length; + + key.length = seed_length; + key.contents = seed; + + if ((ret = krb5_c_verify_checksum(context, &key, 0, &input, cksum, + &valid))) + return(ret); + + if (!valid) + return(KRB5KRB_AP_ERR_BAD_INTEGRITY); + + return(0); +} + +krb5_error_code KRB5_CALLCONV +krb5_random_confounder(size_t size, krb5_pointer ptr) +{ + krb5_data random_data; + + random_data.length = size; + random_data.data = ptr; + + return(krb5_c_random_make_octets(/* XXX */ 0, &random_data)); +} + +krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key, + krb5_pointer ivec, krb5_data *data, + krb5_enc_data *enc_data) +{ + krb5_error_code ret; + size_t enclen, blocksize; + krb5_data ivecd; + + if ((ret = krb5_c_encrypt_length(context, key->enctype, data->length, + &enclen))) + return(ret); + + if (ivec) { + if ((ret = krb5_c_block_size(context, key->enctype, &blocksize))) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + enc_data->magic = KV5M_ENC_DATA; + enc_data->kvno = 0; + enc_data->enctype = key->enctype; + enc_data->ciphertext.length = enclen; + if ((enc_data->ciphertext.data = malloc(enclen)) == NULL) + return(ENOMEM); + + if ((ret = krb5_c_encrypt(context, key, 0, ivec?&ivecd:0, data, enc_data))) + free(enc_data->ciphertext.data); + + return(ret); +} + +krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key, + krb5_pointer ivec, krb5_enc_data *enc_data, + krb5_data *data) +{ + krb5_error_code ret; + krb5_data ivecd; + size_t blocksize; + + if (ivec) { + if ((ret = krb5_c_block_size(context, key->enctype, &blocksize))) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + data->length = enc_data->ciphertext.length; + if ((data->data = (char *) malloc(data->length)) == NULL) + return(ENOMEM); + + if ((ret = krb5_c_decrypt(context, key, 0, ivec?&ivecd:0, enc_data, data))) + free(data->data); + + return(0); +} diff --git a/src/lib/crypto/krb/prf.c b/src/lib/crypto/krb/prf.c new file mode 100644 index 000000000..67e1bc8a3 --- /dev/null +++ b/src/lib/crypto/krb/prf.c @@ -0,0 +1,87 @@ +/* + * lib/crypto/prf.c + * + * Copyright (C) 2004 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 contains the implementation of krb5_c_prf, which will find + *the enctype-specific PRF and then generate pseudo-random data. This + *function yields krb5_c_prf_length bytes of output. + */ + + +#include "k5-int.h" +#include "etypes.h" + +#include <assert.h> + +krb5_error_code KRB5_CALLCONV +krb5_c_prf_length(krb5_context context, krb5_enctype enctype, + size_t *len) +{ + int i; + assert (len); + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + *len = krb5_enctypes_list[i].prf_length; + return 0; + +} + +krb5_error_code KRB5_CALLCONV +krb5_c_prf(krb5_context context, const krb5_keyblock *key, + krb5_data *input, krb5_data *output) +{ + int i; + size_t len; + assert(input && output); + assert (output->data); + + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + output->magic = KV5M_DATA; + if (!krb5_enctypes_list[i].prf) + return (KRB5_CRYPTO_INTERNAL); + krb5_c_prf_length (context, key->enctype, &len); + if (len != output->length) + return (KRB5_CRYPTO_INTERNAL); + return((*(krb5_enctypes_list[i].prf)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, input, output)); +} + diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c new file mode 100644 index 000000000..f9647eae2 --- /dev/null +++ b/src/lib/crypto/krb/prng.c @@ -0,0 +1,215 @@ +/* + * 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 <assert.h> +#include "k5-thread.h" + +#include "yarrow.h" +static Yarrow_CTX y_ctx; +#define yarrow_lock krb5int_yarrow_lock +k5_mutex_t yarrow_lock = K5_MUTEX_PARTIAL_INITIALIZER; + +/* Helper function to estimate entropy based on sample length + * and where it comes from. + */ + +static size_t +entropy_estimate (unsigned int randsource, size_t length) +{ + switch (randsource) { + case KRB5_C_RANDSOURCE_OLDAPI: + return (4*length); + case KRB5_C_RANDSOURCE_OSRAND: + return (8*length); + case KRB5_C_RANDSOURCE_TRUSTEDPARTY: + return (4*length); + case KRB5_C_RANDSOURCE_TIMING:return (2); + case KRB5_C_RANDSOURCE_EXTERNAL_PROTOCOL: + return (0); + default: + abort(); + } +return (0); +} + +int krb5int_prng_init(void) +{ + unsigned i; + 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++ ) { + unsigned source_id; + 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_seed (krb5_context context, krb5_data *data) +{ + return krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_OLDAPI, data); +} + +krb5_error_code KRB5_CALLCONV +krb5_c_random_make_octets(krb5_context context, krb5_data *data) +{ + int yerr; + 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); +} + + +/* + * 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 <unistd.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#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[YARROW_SLOW_THRESH/8], *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; + if ( krb5_c_random_add_entropy (context, KRB5_C_RANDSOURCE_OSRAND, + &data) != 0) { + return 0; + } + return 1; +} + +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/random_to_key.c b/src/lib/crypto/krb/random_to_key.c new file mode 100644 index 000000000..20f0abc0d --- /dev/null +++ b/src/lib/crypto/krb/random_to_key.c @@ -0,0 +1,73 @@ +/* + * COPYRIGHT (c) 2006 + * The Regents of the University of Michigan + * ALL RIGHTS RESERVED + * + * Permission is granted to use, copy, create derivative works + * and redistribute this software and such derivative works + * for any purpose, so long as the name of The University of + * Michigan is not used in any advertising or publicity + * pertaining to the use of distribution of this software + * without specific, written prior authorization. If the + * above copyright notice or any other identification of the + * University of Michigan is included in any copy of any + * portion of this software, then the disclaimer below must + * also be included. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* + * Create a key given random data. It is assumed that random_key has + * already been initialized and random_key->contents have been allocated + * with the correct length. + */ +#include "k5-int.h" +#include "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_random_to_key(krb5_context context, krb5_enctype enctype, + krb5_data *random_data, krb5_keyblock *random_key) +{ + int i; + krb5_error_code ret; + const struct krb5_enc_provider *enc; + + if (random_data == NULL || random_key == NULL) + return(EINVAL); + + if (random_key->contents == NULL) + return(EINVAL); + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + if (random_key->length != enc->keylength) + return(KRB5_BAD_KEYSIZE); + + ret = ((*(enc->make_key))(random_data, random_key)); + + if (ret) { + memset(random_key->contents, 0, random_key->length); + } + + return(ret); +} diff --git a/src/lib/crypto/krb/raw/Makefile.in b/src/lib/crypto/krb/raw/Makefile.in new file mode 100644 index 000000000..f52cb24ea --- /dev/null +++ b/src/lib/crypto/krb/raw/Makefile.in @@ -0,0 +1,34 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/raw +mydir=lib/crypto/krb/raw +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../@CRYPTO_IMPL@ +DEFS= + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=raw +##DOS##OBJFILE=..\$(OUTPRE)raw.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= raw_decrypt.o raw_encrypt.o raw_aead.o + +OBJS= $(OUTPRE)raw_decrypt.$(OBJEXT) $(OUTPRE)raw_encrypt.$(OBJEXT) $(OUTPRE)raw_aead.$(OBJEXT) + +SRCS= $(srcdir)/raw_decrypt.c $(srcdir)/raw_encrypt.c $(srcdir)/raw_aead.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/raw/deps b/src/lib/crypto/krb/raw/deps new file mode 100644 index 000000000..7ab0382e4 --- /dev/null +++ b/src/lib/crypto/krb/raw/deps @@ -0,0 +1,37 @@ +# +# Generated makefile dependencies follow. +# +raw_decrypt.so raw_decrypt.po $(OUTPRE)raw_decrypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + raw.h raw_decrypt.c +raw_encrypt.so raw_encrypt.po $(OUTPRE)raw_encrypt.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + raw.h raw_encrypt.c +raw_aead.so raw_aead.po $(OUTPRE)raw_aead.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h $(SRCTOP)/include/k5-buf.h \ + $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \ + $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \ + $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \ + $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + $(srcdir)/../aead.h $(srcdir)/../cksumtypes.h raw.h \ + raw_aead.c diff --git a/src/lib/crypto/krb/raw/raw.h b/src/lib/crypto/krb/raw/raw.h new file mode 100644 index 000000000..f4b7d5f0b --- /dev/null +++ b/src/lib/crypto/krb/raw/raw.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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" + +void krb5_raw_encrypt_length +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t input, size_t *length); + +krb5_error_code krb5_raw_encrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output); + +krb5_error_code krb5_raw_decrypt +(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); + +extern const struct krb5_aead_provider krb5int_aead_raw; + diff --git a/src/lib/crypto/krb/raw/raw_aead.c b/src/lib/crypto/krb/raw/raw_aead.c new file mode 100644 index 000000000..f52fe000d --- /dev/null +++ b/src/lib/crypto/krb/raw/raw_aead.c @@ -0,0 +1,163 @@ +/* + * lib/crypto/raw/raw_aead.c + * + * Copyright 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 "raw.h" +#include "aead.h" + +/* AEAD */ + +static krb5_error_code +krb5int_raw_crypto_length(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + krb5_cryptotype type, + unsigned int *length) +{ + switch (type) { + case KRB5_CRYPTO_TYPE_PADDING: + *length = enc->block_size; + break; + default: + *length = 0; + break; + } + + return 0; +} + +static krb5_error_code +krb5int_raw_encrypt_iov(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_error_code ret; + krb5_crypto_iov *padding; + size_t i; + unsigned int blocksize = 0; + unsigned int plainlen = 0; + unsigned int padsize = 0; + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &blocksize); + if (ret != 0) + return ret; + + for (i = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + if (iov->flags == KRB5_CRYPTO_TYPE_DATA) + plainlen += iov->data.length; + } + + if (blocksize != 0) { + /* Check that the input data is correctly padded */ + if (plainlen % blocksize) + padsize = blocksize - (plainlen % blocksize); + } + + padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING); + if (padsize && (padding == NULL || padding->data.length < padsize)) + return KRB5_BAD_MSIZE; + + if (padding != NULL) { + memset(padding->data.data, 0, padsize); + padding->data.length = padsize; + } + + assert(enc->encrypt_iov != NULL); + + ret = enc->encrypt_iov(key, ivec, data, num_data); /* will update ivec */ + + return ret; +} + +static krb5_error_code +krb5int_raw_decrypt_iov(const struct krb5_aead_provider *aead, + const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_error_code ret; + size_t i; + unsigned int blocksize = 0; /* careful, this is enc block size not confounder len */ + unsigned int cipherlen = 0; + + if (krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM) != NULL) { + return krb5int_c_iov_decrypt_stream(aead, enc, hash, key, + usage, ivec, data, num_data); + } + + + /* E(Confounder | Plaintext | Pad) | Checksum */ + + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &blocksize); + if (ret != 0) + return ret; + + for (i = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_DATA_IOV(iov)) + cipherlen += iov->data.length; + } + + if (blocksize == 0) { + /* Check for correct input length in CTS mode */ + if (enc->block_size != 0 && cipherlen < enc->block_size) + return KRB5_BAD_MSIZE; + } else { + /* Check that the input data is correctly padded */ + if ((cipherlen % blocksize) != 0) + return KRB5_BAD_MSIZE; + } + + /* Validate header and trailer lengths */ + + /* derive the keys */ + + /* decrypt the plaintext (header | data | padding) */ + assert(enc->decrypt_iov != NULL); + + ret = enc->decrypt_iov(key, ivec, data, num_data); /* will update ivec */ + + return ret; +} + +const struct krb5_aead_provider krb5int_aead_raw = { + krb5int_raw_crypto_length, + krb5int_raw_encrypt_iov, + krb5int_raw_decrypt_iov +}; diff --git a/src/lib/crypto/krb/raw/raw_decrypt.c b/src/lib/crypto/krb/raw/raw_decrypt.c new file mode 100644 index 000000000..767da1f9f --- /dev/null +++ b/src/lib/crypto/krb/raw/raw_decrypt.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "raw.h" + +krb5_error_code +krb5_raw_decrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + return((*(enc->decrypt))(key, ivec, input, output)); +} diff --git a/src/lib/crypto/krb/raw/raw_encrypt.c b/src/lib/crypto/krb/raw/raw_encrypt.c new file mode 100644 index 000000000..68b819c01 --- /dev/null +++ b/src/lib/crypto/krb/raw/raw_encrypt.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "raw.h" + +void +krb5_raw_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t inputlen, size_t *length) +{ + size_t blocksize; + + blocksize = enc->block_size; + + *length = krb5_roundup(inputlen, blocksize); +} + +krb5_error_code +krb5_raw_encrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *output) +{ + return((*(enc->encrypt))(key, ivec, input, output)); +} diff --git a/src/lib/crypto/krb/state.c b/src/lib/crypto/krb/state.c new file mode 100644 index 000000000..f69746c81 --- /dev/null +++ b/src/lib/crypto/krb/state.c @@ -0,0 +1,72 @@ +/* + * lib/crypto/state.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 + + * + * + * + * * Section 6 (Encryption) of the Kerberos revisions document defines + * cipher states to be used to chain encryptions and decryptions + * together. Examples of cipher states include initialization vectors + * for CBC encription. This file contains implementations of + * krb5_c_init_state and krb5_c_free_state used by clients of the + * Kerberos crypto library. + */ +#include "k5-int.h" +#include "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_init_state (krb5_context context, const krb5_keyblock *key, + krb5_keyusage keyusage, krb5_data *new_state) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + return (*(krb5_enctypes_list[i].enc->init_state)) + (key, keyusage, new_state); +} + +krb5_error_code KRB5_CALLCONV +krb5_c_free_state (krb5_context context, const krb5_keyblock *key, + krb5_data *state) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + return (*(krb5_enctypes_list[i].enc->free_state)) + (state); +} diff --git a/src/lib/crypto/krb/string_to_cksumtype.c b/src/lib/crypto/krb/string_to_cksumtype.c new file mode 100644 index 000000000..5a3c70d73 --- /dev/null +++ b/src/lib/crypto/krb/string_to_cksumtype.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_string_to_cksumtype(char *string, krb5_cksumtype *cksumtypep) +{ + unsigned int i, j; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (strcasecmp(krb5_cksumtypes_list[i].name, string) == 0) { + *cksumtypep = krb5_cksumtypes_list[i].ctype; + return(0); + } +#define MAX_ALIASES (sizeof(krb5_cksumtypes_list[i].aliases) / sizeof(krb5_cksumtypes_list[i].aliases[0])) + for (j = 0; j < MAX_ALIASES; j++) { + const char *alias = krb5_cksumtypes_list[i].aliases[j]; + if (alias == NULL) + break; + if (strcasecmp(alias, string) == 0) { + *cksumtypep = krb5_cksumtypes_list[i].ctype; + return 0; + } + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/krb/string_to_enctype.c b/src/lib/crypto/krb/string_to_enctype.c new file mode 100644 index 000000000..5c6ae1cad --- /dev/null +++ b/src/lib/crypto/krb/string_to_enctype.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_string_to_enctype(char *string, krb5_enctype *enctypep) +{ + unsigned int i, j; + + for (i=0; i<krb5_enctypes_length; i++) { + if (strcasecmp(krb5_enctypes_list[i].name, string) == 0) { + *enctypep = krb5_enctypes_list[i].etype; + return 0; + } +#define MAX_ALIASES (sizeof(krb5_enctypes_list[i].aliases) / sizeof(krb5_enctypes_list[i].aliases[0])) + for (j = 0; j < MAX_ALIASES; j++) { + const char *alias = krb5_enctypes_list[i].aliases[j]; + if (alias == NULL) + break; + if (strcasecmp(alias, string) == 0) { + *enctypep = krb5_enctypes_list[i].etype; + return 0; + } + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/krb/string_to_key.c b/src/lib/crypto/krb/string_to_key.c new file mode 100644 index 000000000..71d9db650 --- /dev/null +++ b/src/lib/crypto/krb/string_to_key.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_string_to_key_with_params(krb5_context context, + krb5_enctype enctype, + const krb5_data *string, + const krb5_data *salt, + const krb5_data *params, + krb5_keyblock *key); + + +krb5_error_code KRB5_CALLCONV +krb5_c_string_to_key(krb5_context context, krb5_enctype enctype, + const krb5_data *string, const krb5_data *salt, + krb5_keyblock *key) +{ + return krb5_c_string_to_key_with_params(context, enctype, string, salt, + NULL, key); +} + +krb5_error_code KRB5_CALLCONV +krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype, + const krb5_data *string, + const krb5_data *salt, + const krb5_data *params, krb5_keyblock *key) +{ + int i; + krb5_error_code ret; + const struct krb5_enc_provider *enc; + size_t keybytes, keylength; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; +/* xxx AFS string2key function is indicated by a special length in + * the salt in much of the code. However only the DES enctypes can + * deal with this. Using s2kparams would be a much better solution.*/ + if (salt && salt->length == SALT_TYPE_AFS_LENGTH) { + switch (enctype) { + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + break; + default: + return (KRB5_CRYPTO_INTERNAL); + } + } + + keybytes = enc->keybytes; + keylength = enc->keylength; + + if ((key->contents = (krb5_octet *) malloc(keylength)) == NULL) + return(ENOMEM); + + key->magic = KV5M_KEYBLOCK; + key->enctype = enctype; + key->length = keylength; + + ret = (*krb5_enctypes_list[i].str2key)(enc, string, salt, params, key); + if (ret) { + memset(key->contents, 0, keylength); + free(key->contents); + key->length = 0; + key->contents = NULL; + } + + return(ret); +} diff --git a/src/lib/crypto/krb/valid_cksumtype.c b/src/lib/crypto/krb/valid_cksumtype.c new file mode 100644 index 000000000..8fd9effc9 --- /dev/null +++ b/src/lib/crypto/krb/valid_cksumtype.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_boolean KRB5_CALLCONV +krb5_c_valid_cksumtype(krb5_cksumtype ctype) +{ + unsigned int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == ctype) + return(1); + } + + return(0); +} + +krb5_boolean KRB5_CALLCONV +valid_cksumtype(krb5_cksumtype ctype) +{ + return krb5_c_valid_cksumtype (ctype); +} diff --git a/src/lib/crypto/krb/valid_enctype.c b/src/lib/crypto/krb/valid_enctype.c new file mode 100644 index 000000000..7b9a92a89 --- /dev/null +++ b/src/lib/crypto/krb/valid_enctype.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "etypes.h" + +krb5_boolean KRB5_CALLCONV +krb5_c_valid_enctype(krb5_enctype etype) +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == etype) + return(1); + } + + return(0); +} + +krb5_boolean KRB5_CALLCONV +valid_enctype(krb5_enctype etype) +{ + return krb5_c_valid_enctype (etype); +} + +krb5_boolean KRB5_CALLCONV +krb5_c_weak_enctype(krb5_enctype etype) +{ + int i; + const struct krb5_keytypes *k; + + for (i = 0; i < krb5_enctypes_length; i++) { +#if 0 + if (krb5_enctypes_list[i].etype == etype && + krb5_enctypes_list[i].flags | ETYPE_WEAK) + return(1); +#endif + k = &krb5_enctypes_list[i]; + if (k->etype == etype && (k->flags & ETYPE_WEAK)) { + return(1); + } + } + + return(0); +} diff --git a/src/lib/crypto/krb/verify_checksum.c b/src/lib/crypto/krb/verify_checksum.c new file mode 100644 index 000000000..72b5595de --- /dev/null +++ b/src/lib/crypto/krb/verify_checksum.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. 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 + * 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 "cksumtypes.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key, + krb5_keyusage usage, const krb5_data *data, + const krb5_checksum *cksum, krb5_boolean *valid) +{ + unsigned int i; + size_t hashsize; + krb5_error_code ret; + krb5_data indata; + krb5_checksum computed; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksum->checksum_type) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + /* if there's actually a verify function, call it */ + + indata.length = cksum->length; + indata.data = (char *) cksum->contents; + + if (krb5_cksumtypes_list[i].keyhash) { + const struct krb5_keyhash_provider *keyhash; + + keyhash = krb5_cksumtypes_list[i].keyhash; + + if (keyhash->verify == NULL && keyhash->verify_iov != NULL) { + krb5_crypto_iov iov[1]; + + iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + iov[0].data = *data; + + return (*keyhash->verify_iov)(key, usage, 0, iov, 1, &indata, valid); + } else if (keyhash->verify != NULL) { + return (*keyhash->verify)(key, usage, 0, data, &indata, valid); + } + } + + /* otherwise, make the checksum again, and compare */ + + if ((ret = krb5_c_checksum_length(context, cksum->checksum_type, &hashsize))) + return(ret); + + if (cksum->length != hashsize) + return(KRB5_BAD_MSIZE); + + computed.length = hashsize; + + if ((ret = krb5_c_make_checksum(context, cksum->checksum_type, key, usage, + data, &computed))) { + free(computed.contents); + return(ret); + } + + *valid = (memcmp(computed.contents, cksum->contents, hashsize) == 0); + + free(computed.contents); + + return(0); +} diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c new file mode 100644 index 000000000..08c0a5c7b --- /dev/null +++ b/src/lib/crypto/krb/verify_checksum_iov.c @@ -0,0 +1,98 @@ +/* + * lib/crypto/verify_checksum_iov.c + * + * Copyright 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 "cksumtypes.h" +#include "aead.h" + +krb5_error_code KRB5_CALLCONV +krb5_c_verify_checksum_iov(krb5_context context, + krb5_cksumtype checksum_type, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_boolean *valid) +{ + unsigned int i; + size_t cksumlen; + krb5_error_code ret; + krb5_data computed; + krb5_crypto_iov *checksum; + + for (i = 0; i < krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == checksum_type) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + checksum = krb5int_c_locate_iov((krb5_crypto_iov *)data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); + if (checksum == NULL) + return(KRB5_BAD_MSIZE); + + /* if there's actually a verify function, call it */ + + if (krb5_cksumtypes_list[i].keyhash && + krb5_cksumtypes_list[i].keyhash->verify_iov) + return((*(krb5_cksumtypes_list[i].keyhash->verify_iov))(key, usage, 0, + data, num_data, + &checksum->data, + valid)); + + /* otherwise, make the checksum again, and compare */ + + if (krb5_cksumtypes_list[i].keyhash != NULL) + computed.length = krb5_cksumtypes_list[i].keyhash->hashsize; + else + computed.length = krb5_cksumtypes_list[i].hash->hashsize; + + if (krb5_cksumtypes_list[i].trunc_size != 0) + cksumlen = krb5_cksumtypes_list[i].trunc_size; + else + cksumlen = computed.length; + + if (checksum->data.length != cksumlen) + return(KRB5_BAD_MSIZE); + + computed.data = malloc(computed.length); + if (computed.data == NULL) + return(ENOMEM); + + if ((ret = krb5int_c_make_checksum_iov(&krb5_cksumtypes_list[i], key, usage, + data, num_data, &computed))) { + free(computed.data); + return(ret); + } + + *valid = (computed.length == cksumlen) && + (memcmp(computed.data, checksum->data.data, cksumlen) == 0); + + free(computed.data); + + return(0); +} diff --git a/src/lib/crypto/krb/yarrow/ASSUMPTIONS b/src/lib/crypto/krb/yarrow/ASSUMPTIONS new file mode 100644 index 000000000..3e3c99c49 --- /dev/null +++ b/src/lib/crypto/krb/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/yarrow/LICENSE b/src/lib/crypto/krb/yarrow/LICENSE new file mode 100644 index 000000000..c85475d7e --- /dev/null +++ b/src/lib/crypto/krb/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/yarrow/Makefile.in b/src/lib/crypto/krb/yarrow/Makefile.in new file mode 100644 index 000000000..d7f01e469 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/Makefile.in @@ -0,0 +1,37 @@ +thisconfigdir=../../../.. +myfulldir=lib/crypto/krb/yarrow +mydir=lib/crypto/krb/yarrow +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../@CRYPTO_IMPL@ -I$(srcdir)/../../@CRYPTO_IMPL@/sha1 -I$(srcdir)/../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 new file mode 100644 index 000000000..3dd4b801a --- /dev/null +++ b/src/lib/crypto/krb/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/yarrow/TODO b/src/lib/crypto/krb/yarrow/TODO new file mode 100644 index 000000000..bd133ecfd --- /dev/null +++ b/src/lib/crypto/krb/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/yarrow/deps b/src/lib/crypto/krb/yarrow/deps new file mode 100644 index 000000000..e61199e4d --- /dev/null +++ b/src/lib/crypto/krb/yarrow/deps @@ -0,0 +1,27 @@ +# +# 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) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/sha1/shs.h \ + yarrow.c yarrow.h ycipher.h yexcep.h yhash.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) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/sha1/shs.h \ + $(srcdir)/../enc_provider/enc_provider.h yarrow.h ycipher.c \ + ycipher.h yhash.h ytypes.h diff --git a/src/lib/crypto/krb/yarrow/yarrow.c b/src/lib/crypto/krb/yarrow/yarrow.c new file mode 100644 index 000000000..ff25fa9c5 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/yarrow.c @@ -0,0 +1,958 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +/* + * 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 <string.h> +#include <limits.h> +#ifdef _WIN32 +#include "port-sockets.h" +#else +# include <unistd.h> +# include <netinet/in.h> +#endif +#if !defined(YARROW_NO_MATHLIB) +#include <math.h> +#endif + +#define YARROW_IMPL +#include "yarrow.h" +#include "yhash.h" +#include "ycipher.h" +#include "ylock.h" +#include "ystate.h" +#include "yexcep.h" + +#if defined( YARROW_DEBUG ) || defined( YARROW_TRACE ) +# include <stdio.h> +#endif + +#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; + int 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 || 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 new file mode 100644 index 000000000..7e1fe1442 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/yarrow.h @@ -0,0 +1,186 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#ifndef YARROW_H +#define YARROW_H + +#ifdef HAVE_UNISTD_H +#define YARROW_DETECT_FORK +#include <unistd.h> +#endif +#define YARROW_NO_MATHLIB + +#include "ytypes.h" +#include "yhash.h" +#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 */ + int slow_thresh; + int 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 new file mode 100644 index 000000000..a65b4e05c --- /dev/null +++ b/src/lib/crypto/krb/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/yarrow/yarrow.pod b/src/lib/crypto/krb/yarrow/yarrow.pod new file mode 100644 index 000000000..7892ebbe6 --- /dev/null +++ b/src/lib/crypto/krb/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<Yarrow_CTX> structure. B<filename> 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<YARROW_OK> if the +PRNG is seeded on exit, or B<YARROW_NOT_SEEDED> 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<Yarrow_CTX>. The function assigns a unique number to the new source, +and places it in B<source_id>. + +Yarrow_Poll() gathers entropy from the state of the machine and adds +it to the source B<source_id>. The source has to be allocated by the +user with Yarrow_New_Source. Returns B<YARROW_OK> if the PRNG is +seeded on exit, or B<YARROW_NOT_SEEDED> if the PRNG is not yet seeded. + +Yarrow_Input() is used to add randomness from the source B<source_id> +to the PRNG. It reads B<size> bytes at the address B<sample>. An +estimate of the entropy in bits contained in the sample must be +specified as B<entropy_bits>. + +Yarrow_Status() returns B<YARROW_OK> if the PRNG has enough entropy to +produce output, and B<YARROW_NOT_SEEDED> 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<size> bytes of cryptographically strong +pseudo-random output and places them at B<out>. 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<source_id>. 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<YARROW_OK> 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 new file mode 100644 index 000000000..2af410440 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/ycipher.c @@ -0,0 +1,96 @@ +/* + * 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; + keybytes = enc->keybytes; + keylength = enc->keylength; + assert (keybytes == CIPHER_KEY_SIZE); + 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) + return (YARROW_NOMEM); + randombits.data = (char *) key; + randombits.length = keybytes; + ret = enc->make_key (&randombits, &ctx->key); + if (ret) { + memset (ctx->key.contents, 0, ctx->key.length); + free(ctx->key.contents); + ctx->key.contents = NULL; + 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_data ind, outd; + const struct krb5_enc_provider *enc = &yarrow_enc_provider; + ind.data = (char *) in; + ind.length = CIPHER_BLOCK_SIZE; + outd.data = (char *) out; + outd.length = CIPHER_BLOCK_SIZE; + ret = enc->encrypt (&ctx->key, 0, &ind, &outd); + if (ret) + return YARROW_FAIL; + return YARROW_OK; +} + +void +krb5int_yarrow_cipher_final +(CIPHER_CTX *ctx) + +{ + if (ctx->key.contents) { + memset (ctx->key.contents, 0, ctx->key.length); + free (ctx->key.contents); + } + ctx->key.contents = 0; + ctx->key.length = 0; +} diff --git a/src/lib/crypto/krb/yarrow/ycipher.h b/src/lib/crypto/krb/yarrow/ycipher.h new file mode 100644 index 000000000..96999c0db --- /dev/null +++ b/src/lib/crypto/krb/yarrow/ycipher.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#ifndef YCIPHER_H +#define YCIPHER_H + +/* block cipher interface */ + +typedef struct +{ + krb5_keyblock 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 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 new file mode 100644 index 000000000..d27de2d5e --- /dev/null +++ b/src/lib/crypto/krb/yarrow/yexcep.h @@ -0,0 +1,107 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#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/yhash.h b/src/lib/crypto/krb/yarrow/yhash.h new file mode 100644 index 000000000..ee4f03eb2 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/yhash.h @@ -0,0 +1,29 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#ifndef YHASH_H +#define YHASH_H + +/* hash function interface */ + +/* default to SHA1 for yarrow 160 */ + +#include "shs.h" + + + +#define HASH_CTX SHS_INFO +#define HASH_Init(x) shsInit(x) +#define HASH_Update(x, buf, sz) shsUpdate(x, (const void*)buf, sz) +#define HASH_Final(x, tdigest) do { \ + int loopvar; \ + unsigned char *out2 = (void *)(tdigest); \ + HASH_CTX *ctx = (x); \ + shsFinal(ctx); \ + for (loopvar=0; loopvar<(sizeof(ctx->digest)/sizeof(ctx->digest[0])); loopvar++) \ + store_32_be(ctx->digest[loopvar], &out2[loopvar*4]); \ + } while(0) + + +#define HASH_DIGEST_SIZE SHS_DIGESTSIZE + +#endif /* YHASH_H */ diff --git a/src/lib/crypto/krb/yarrow/ylock.h b/src/lib/crypto/krb/yarrow/ylock.h new file mode 100644 index 000000000..9c032dc61 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/ylock.h @@ -0,0 +1,24 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#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 new file mode 100644 index 000000000..2886ca338 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/ystate.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#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 new file mode 100644 index 000000000..9265e5a84 --- /dev/null +++ b/src/lib/crypto/krb/yarrow/ytypes.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; c-file-style: "bsd" -*- */ + +#ifndef YTYPES_H +#define YTYPES_H + +#include <limits.h> +#include <stddef.h> +#include "autoconf.h" +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#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 */ |
