aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto/krb
diff options
context:
space:
mode:
authorZhanna Tsitkov <tsitkova@mit.edu>2009-08-03 14:19:16 +0000
committerZhanna Tsitkov <tsitkova@mit.edu>2009-08-03 14:19:16 +0000
commit3c40c7f134b4e87baa43b0cacb435b6f96245e2f (patch)
tree2b1014db60c1d3941f17a4d00221e07cc5cece62 /src/lib/crypto/krb
parentab7ffb919b4ee5ee5bc07f987d9163202a632e6a (diff)
downloadkrb5-3c40c7f134b4e87baa43b0cacb435b6f96245e2f.zip
krb5-3c40c7f134b4e87baa43b0cacb435b6f96245e2f.tar.gz
krb5-3c40c7f134b4e87baa43b0cacb435b6f96245e2f.tar.bz2
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')
-rw-r--r--src/lib/crypto/krb/Makefile.in253
-rw-r--r--src/lib/crypto/krb/aead.c573
-rw-r--r--src/lib/crypto/krb/aead.h123
-rw-r--r--src/lib/crypto/krb/block_size.c47
-rw-r--r--src/lib/crypto/krb/cf2.c154
-rw-r--r--src/lib/crypto/krb/checksum_length.c53
-rw-r--r--src/lib/crypto/krb/cksumtype_to_string.c45
-rw-r--r--src/lib/crypto/krb/cksumtypes.c91
-rw-r--r--src/lib/crypto/krb/cksumtypes.h62
-rw-r--r--src/lib/crypto/krb/coll_proof_cksum.c50
-rw-r--r--src/lib/crypto/krb/combine_keys.c349
-rw-r--r--src/lib/crypto/krb/crc32/CRC.pm156
-rw-r--r--src/lib/crypto/krb/crc32/Makefile.in34
-rw-r--r--src/lib/crypto/krb/crc32/Poly.pm182
-rw-r--r--src/lib/crypto/krb/crc32/crc-32.h71
-rw-r--r--src/lib/crypto/krb/crc32/crc.pl111
-rw-r--r--src/lib/crypto/krb/crc32/crc32.c192
-rw-r--r--src/lib/crypto/krb/crc32/deps13
-rw-r--r--src/lib/crypto/krb/crypto_length.c170
-rw-r--r--src/lib/crypto/krb/crypto_libinit.c33
-rw-r--r--src/lib/crypto/krb/decrypt.c67
-rw-r--r--src/lib/crypto/krb/decrypt_iov.c61
-rw-r--r--src/lib/crypto/krb/default_state.c63
-rw-r--r--src/lib/crypto/krb/deps445
-rw-r--r--src/lib/crypto/krb/dk/Makefile.in53
-rw-r--r--src/lib/crypto/krb/dk/checksum.c168
-rw-r--r--src/lib/crypto/krb/dk/deps79
-rw-r--r--src/lib/crypto/krb/dk/derive.c217
-rw-r--r--src/lib/crypto/krb/dk/dk.h124
-rw-r--r--src/lib/crypto/krb/dk/dk_aead.c386
-rw-r--r--src/lib/crypto/krb/dk/dk_decrypt.c200
-rw-r--r--src/lib/crypto/krb/dk/dk_encrypt.c358
-rw-r--r--src/lib/crypto/krb/dk/dk_prf.c64
-rw-r--r--src/lib/crypto/krb/dk/stringtokey.c96
-rw-r--r--src/lib/crypto/krb/enc_provider/Makefile.in41
-rw-r--r--src/lib/crypto/krb/enc_provider/aes.c415
-rw-r--r--src/lib/crypto/krb/enc_provider/deps50
-rw-r--r--src/lib/crypto/krb/enc_provider/des.c181
-rw-r--r--src/lib/crypto/krb/enc_provider/des3.c221
-rw-r--r--src/lib/crypto/krb/enc_provider/enc_provider.h36
-rw-r--r--src/lib/crypto/krb/enc_provider/rc4.c271
-rw-r--r--src/lib/crypto/krb/encrypt.c63
-rw-r--r--src/lib/crypto/krb/encrypt_iov.c55
-rw-r--r--src/lib/crypto/krb/encrypt_length.c59
-rw-r--r--src/lib/crypto/krb/enctype_compare.c55
-rw-r--r--src/lib/crypto/krb/enctype_to_string.c45
-rw-r--r--src/lib/crypto/krb/etypes.c169
-rw-r--r--src/lib/crypto/krb/etypes.h83
-rw-r--r--src/lib/crypto/krb/hash_provider/Makefile.in35
-rw-r--r--src/lib/crypto/krb/hash_provider/deps48
-rw-r--r--src/lib/crypto/krb/hash_provider/hash_crc32.c55
-rw-r--r--src/lib/crypto/krb/hash_provider/hash_md4.c55
-rw-r--r--src/lib/crypto/krb/hash_provider/hash_md5.c55
-rw-r--r--src/lib/crypto/krb/hash_provider/hash_provider.h32
-rw-r--r--src/lib/crypto/krb/hash_provider/hash_sha1.c57
-rw-r--r--src/lib/crypto/krb/keyblocks.c79
-rw-r--r--src/lib/crypto/krb/keyed_checksum_types.c89
-rw-r--r--src/lib/crypto/krb/keyed_cksum.c55
-rw-r--r--src/lib/crypto/krb/keyhash_provider/Makefile.in34
-rw-r--r--src/lib/crypto/krb/keyhash_provider/deps65
-rw-r--r--src/lib/crypto/krb/keyhash_provider/descbc.c72
-rw-r--r--src/lib/crypto/krb/keyhash_provider/hmac_md5.c144
-rw-r--r--src/lib/crypto/krb/keyhash_provider/k5_md4des.c194
-rw-r--r--src/lib/crypto/krb/keyhash_provider/k5_md5des.c191
-rw-r--r--src/lib/crypto/krb/keyhash_provider/keyhash_provider.h35
-rw-r--r--src/lib/crypto/krb/keyhash_provider/md5_hmac.c65
-rw-r--r--src/lib/crypto/krb/keylengths.c61
-rw-r--r--src/lib/crypto/krb/make_checksum.c129
-rw-r--r--src/lib/crypto/krb/make_checksum_iov.c82
-rw-r--r--src/lib/crypto/krb/make_random_key.c83
-rw-r--r--src/lib/crypto/krb/mandatory_sumtype.c41
-rw-r--r--src/lib/crypto/krb/nfold.c130
-rw-r--r--src/lib/crypto/krb/old/Makefile.in35
-rw-r--r--src/lib/crypto/krb/old/deps37
-rw-r--r--src/lib/crypto/krb/old/des_stringtokey.c58
-rw-r--r--src/lib/crypto/krb/old/old.h52
-rw-r--r--src/lib/crypto/krb/old/old_decrypt.c143
-rw-r--r--src/lib/crypto/krb/old/old_encrypt.c110
-rw-r--r--src/lib/crypto/krb/old_api_glue.c328
-rw-r--r--src/lib/crypto/krb/prf.c87
-rw-r--r--src/lib/crypto/krb/prng.c215
-rw-r--r--src/lib/crypto/krb/random_to_key.c73
-rw-r--r--src/lib/crypto/krb/raw/Makefile.in34
-rw-r--r--src/lib/crypto/krb/raw/deps37
-rw-r--r--src/lib/crypto/krb/raw/raw.h49
-rw-r--r--src/lib/crypto/krb/raw/raw_aead.c163
-rw-r--r--src/lib/crypto/krb/raw/raw_decrypt.c38
-rw-r--r--src/lib/crypto/krb/raw/raw_encrypt.c50
-rw-r--r--src/lib/crypto/krb/state.c72
-rw-r--r--src/lib/crypto/krb/string_to_cksumtype.c53
-rw-r--r--src/lib/crypto/krb/string_to_enctype.c53
-rw-r--r--src/lib/crypto/krb/string_to_key.c101
-rw-r--r--src/lib/crypto/krb/valid_cksumtype.c47
-rw-r--r--src/lib/crypto/krb/valid_enctype.c68
-rw-r--r--src/lib/crypto/krb/verify_checksum.c92
-rw-r--r--src/lib/crypto/krb/verify_checksum_iov.c98
-rw-r--r--src/lib/crypto/krb/yarrow/ASSUMPTIONS101
-rw-r--r--src/lib/crypto/krb/yarrow/LICENSE21
-rw-r--r--src/lib/crypto/krb/yarrow/Makefile.in37
-rw-r--r--src/lib/crypto/krb/yarrow/README94
-rw-r--r--src/lib/crypto/krb/yarrow/TODO9
-rw-r--r--src/lib/crypto/krb/yarrow/deps27
-rw-r--r--src/lib/crypto/krb/yarrow/yarrow.c958
-rw-r--r--src/lib/crypto/krb/yarrow/yarrow.h186
-rw-r--r--src/lib/crypto/krb/yarrow/yarrow.man315
-rw-r--r--src/lib/crypto/krb/yarrow/yarrow.pod112
-rw-r--r--src/lib/crypto/krb/yarrow/ycipher.c96
-rw-r--r--src/lib/crypto/krb/yarrow/ycipher.h42
-rw-r--r--src/lib/crypto/krb/yarrow/yexcep.h107
-rw-r--r--src/lib/crypto/krb/yarrow/yhash.h29
-rw-r--r--src/lib/crypto/krb/yarrow/ylock.h24
-rw-r--r--src/lib/crypto/krb/yarrow/ystate.h28
-rw-r--r--src/lib/crypto/krb/yarrow/ytypes.h27
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 0000000..887fa16
--- /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 0000000..2d9a835
--- /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 0000000..2c99eb8
--- /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 0000000..e4c11e8
--- /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 0000000..4e25641
--- /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 0000000..28846a6
--- /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 0000000..ee1d50b
--- /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 0000000..037e53f
--- /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 0000000..c667e8a
--- /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 0000000..85fb57b
--- /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 0000000..3d97651
--- /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 0000000..ee2ab2a
--- /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 0000000..d62b6ed
--- /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 0000000..cad0f77
--- /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 0000000..0efc006
--- /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 0000000..b21b6b1
--- /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 0000000..ef65476
--- /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 0000000..2558fe2
--- /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 0000000..d99d18b
--- /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 0000000..91bf8ac
--- /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 0000000..74c38f6
--- /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 0000000..1a98b06
--- /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 0000000..33a189f
--- /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 0000000..d7041bf
--- /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 0000000..b254523
--- /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 0000000..f4b18bf
--- /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 0000000..28e8a08
--- /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 0000000..77b05fa
--- /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 0000000..bc40134
--- /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 0000000..e995f9a
--- /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 0000000..c38c4d5
--- /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 0000000..6596e53
--- /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 0000000..ec64caf
--- /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 0000000..0e54b84
--- /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 0000000..2eedf1d
--- /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 0000000..060d119
--- /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 0000000..fa797cd
--- /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 0000000..547f6b9
--- /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 0000000..412c994
--- /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 0000000..92022b3
--- /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 0000000..b950a60
--- /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 0000000..a9a38aa
--- /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 0000000..a35c5b5
--- /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 0000000..a934b2a
--- /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 0000000..55e8277
--- /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 0000000..28fa63e
--- /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 0000000..c44ee41
--- /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 0000000..8441fca
--- /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 0000000..ece3a99
--- /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 0000000..e59eade
--- /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 0000000..ca26810
--- /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 0000000..1fa23c2
--- /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 0000000..174c432
--- /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 0000000..4fa4609
--- /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 0000000..ffc073c
--- /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 0000000..5912c81
--- /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 0000000..04aa447
--- /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 0000000..023d8c6
--- /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 0000000..d84ce79
--- /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 0000000..553676e
--- /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 0000000..bf68e32
--- /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 0000000..34ce671
--- /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 0000000..fceb58e
--- /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 0000000..0175c68
--- /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 0000000..8ac91e1
--- /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 0000000..d05b97f
--- /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 0000000..acd1da8
--- /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 0000000..ad532b2
--- /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 0000000..3cf4af6
--- /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 0000000..0ae321d
--- /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 0000000..f9322ff
--- /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 0000000..1f1902d
--- /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 0000000..4370f1f
--- /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 0000000..e2e71c2
--- /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 0000000..2bacb4e
--- /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 0000000..94ee642
--- /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 0000000..cfbbd72
--- /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 0000000..98bd109
--- /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 0000000..4db0c33
--- /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 0000000..67e1bc8
--- /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 0000000..f9647ea
--- /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 0000000..20f0abc
--- /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 0000000..f52cb24
--- /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 0000000..7ab0382
--- /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 0000000..f4b7d5f
--- /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 0000000..f52fe00
--- /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 0000000..767da1f
--- /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 0000000..68b819c
--- /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 0000000..f69746c
--- /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 0000000..5a3c70d
--- /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 0000000..5c6ae1c
--- /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 0000000..71d9db6
--- /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 0000000..8fd9eff
--- /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 0000000..7b9a92a
--- /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 0000000..72b5595
--- /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 0000000..08c0a5c
--- /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 0000000..3e3c99c
--- /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 0000000..c85475d
--- /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 0000000..d7f01e4
--- /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 0000000..3dd4b80
--- /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 0000000..bd133ec
--- /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 0000000..e61199e
--- /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 0000000..ff25fa9
--- /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 0000000..7e1fe14
--- /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 0000000..a65b4e0
--- /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 0000000..7892ebb
--- /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 0000000..2af4104
--- /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 0000000..96999c0
--- /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 0000000..d27de2d
--- /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 0000000..ee4f03e
--- /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 0000000..9c032dc
--- /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 0000000..2886ca3
--- /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 0000000..9265e5a
--- /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 */