From c4b08a05ed58dea774885a9ac4c241e63f056a46 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Tue, 23 Oct 2001 21:15:04 +0000 Subject: * Tie in Microsoft rc4 cipher and make it build * Add hmac-md5-rc4 keyed hash and appropriate glue * Give keyed hash verify function access to usage argument * Add simplistic crypto system test to make check git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13832 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/crypto/ChangeLog | 10 ++ src/lib/crypto/Makefile.in | 15 +- src/lib/crypto/arcfour/ChangeLog | 5 + src/lib/crypto/arcfour/arcfour-int.h | 26 +-- src/lib/crypto/arcfour/arcfour.c | 7 +- src/lib/crypto/cksumtypes.c | 13 ++ src/lib/crypto/configure.in | 1 + src/lib/crypto/enc_provider/ChangeLog | 8 + src/lib/crypto/enc_provider/Makefile.in | 8 +- src/lib/crypto/enc_provider/arcfour.c | 193 +++++++++++++++++++++ src/lib/crypto/enc_provider/enc_provider.h | 3 + src/lib/crypto/etypes.c | 20 +++ src/lib/crypto/keyhash_provider/ChangeLog | 8 + src/lib/crypto/keyhash_provider/Makefile.in | 9 +- src/lib/crypto/keyhash_provider/hmac_md5.c | 102 +++++++++++ src/lib/crypto/keyhash_provider/k5_md4des.c | 3 +- src/lib/crypto/keyhash_provider/k5_md5des.c | 2 +- src/lib/crypto/keyhash_provider/keyhash_provider.h | 1 + src/lib/crypto/t_encrypt.c | 87 ++++++++++ src/lib/crypto/verify_checksum.c | 2 +- 20 files changed, 479 insertions(+), 44 deletions(-) create mode 100644 src/lib/crypto/enc_provider/arcfour.c create mode 100644 src/lib/crypto/keyhash_provider/hmac_md5.c create mode 100644 src/lib/crypto/t_encrypt.c (limited to 'src/lib') diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index d8fbcfc..8df6f50 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,3 +1,13 @@ +2001-10-23 Sam Hartman + + * cksumtypes.c: hmac-md5-rc4 keyed checksum added + + * etypes.c: arcfour-hmac enctype added + + * configure.in Makefile.in : New subdir: arcfour + + * verify_checksum.c (krb5_c_verify_checksum): Add usage argument to verify call + 2001-10-22 Sam Hartman * make_checksum.c (krb5_c_make_checksum): Include key usage diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index f41d19c..0710d6f 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -3,10 +3,10 @@ myfulldir=lib/crypto mydir=. BUILDTOP=$(REL)$(U)$(S)$(U) LOCAL_SUBDIRS=crc32 des dk enc_provider hash_provider keyhash_provider \ - md4 md5 old raw sha1 + md4 md5 old raw sha1 arcfour LOCALINCLUDES = -I$(srcdir)/enc_provider \ -I$(srcdir)/hash_provider -I$(srcdir)/keyhash_provider \ - -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/dk + -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/dk -I$(srcdir)/arcfour ##DOSBUILDTOP = ..\.. ##DOSLIBNAME=$(OUTPRE)crypto.lib @@ -112,7 +112,8 @@ RELDIR=crypto STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ hash_provider/OBJS.ST keyhash_provider/OBJS.ST md4/OBJS.ST \ - md5/OBJS.ST old/OBJS.ST raw/OBJS.ST sha1/OBJS.ST OBJS.ST + md5/OBJS.ST old/OBJS.ST raw/OBJS.ST sha1/OBJS.ST arcfour/OBJS.ST \ + OBJS.ST # No dependencies. Record places to find this shared object if the target # link editor and loader support it. @@ -131,14 +132,18 @@ libcrypto.lib: clean-unix:: clean-liblinks clean-libs clean-libobjs -check-unix:: t_nfold +check-unix:: t_nfold t_encrypt $(RUN_SETUP) ./t_nfold + $(RUN_SETUP) ./t_encrypt t_nfold$(EXEEXT): t_nfold.$(OBJEXT) nfold.$(OBJEXT) $(CC_LINK) -o $@ t_nfold.$(OBJEXT) nfold.$(OBJEXT) +t_encrypt$(EXEEXT): t_encrypt.$(OBJEXT) nfold.$(OBJEXT) + $(CC_LINK) -o $@ t_encrypt.$(OBJEXT) -lk5crypto -lcom_err + clean:: - $(RM) t_nfold.o t_nfold + $(RM) t_nfold.o t_nfold t_encrypt t_encrypt.o all-windows:: cd crc32 diff --git a/src/lib/crypto/arcfour/ChangeLog b/src/lib/crypto/arcfour/ChangeLog index 91782a0..f822262 100644 --- a/src/lib/crypto/arcfour/ChangeLog +++ b/src/lib/crypto/arcfour/ChangeLog @@ -1,3 +1,8 @@ +2001-10-22 Sam Hartman + + * arcfour-int.h: Make krb5int_arcfour_translate_usage non-static so the hash can use it + + 2001-10-19 Sam Hartman * string_to_key.c (krb5_arcfour_string_to_key): Ignore salt diff --git a/src/lib/crypto/arcfour/arcfour-int.h b/src/lib/crypto/arcfour/arcfour-int.h index 2b25576..b54fce1 100644 --- a/src/lib/crypto/arcfour/arcfour-int.h +++ b/src/lib/crypto/arcfour/arcfour-int.h @@ -20,31 +20,7 @@ typedef struct unsigned char state[256]; } ArcfourContext; -/* gets the next byte from the PRNG */ -static inline unsigned int k5_arcfour_byte(ArcfourContext *); +krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage); -/* 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(krb5_const krb5_keyblock *, krb5_const krb5_data *, - krb5_const krb5_data *, krb5_data *); - - -/* The blocksize for the enctype */ -static void k5_arcfour_blocksize(size_t *); - -/* keysize for the enctype (number of bytes, and length of key (parity/etc) */ -static void k5_arcfour_keysize(size_t *, size_t *); - -/* from a random bitstrem, construct a key */ -static krb5_error_code -k5_arcfour_make_key(krb5_const krb5_data *, krb5_keyblock *); #endif /* ARCFOUR_INT_H */ diff --git a/src/lib/crypto/arcfour/arcfour.c b/src/lib/crypto/arcfour/arcfour.c index b26a3f3..cc18577 100644 --- a/src/lib/crypto/arcfour/arcfour.c +++ b/src/lib/crypto/arcfour/arcfour.c @@ -27,7 +27,7 @@ krb5_arcfour_encrypt_length(enc, hash, inputlen, length) *length = hashsize + krb5_roundup(8 + inputlen, blocksize); } -static krb5_keyusage arcfour_translate_usage(krb5_keyusage usage) + krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage) { switch (usage) { case 1: /* AS-REQ PA-ENC-TIMESTAMP padata timestamp, */ @@ -139,7 +139,7 @@ krb5_arcfour_encrypt(enc, hash, key, usage, ivec, input, output) confounder.data=plaintext.data; /* begin the encryption, computer K1 */ - ms_usage=arcfour_translate_usage(usage); + ms_usage=krb5int_arcfour_translate_usage(usage); if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, l40, salt.length); salt.data[10]=ms_usage & 0xff; @@ -261,7 +261,7 @@ krb5_arcfour_decrypt(enc, hash, key, usage, ivec, input, output) checksum.data=input->data; /* compute the salt */ - ms_usage=arcfour_translate_usage(usage); + ms_usage=krb5int_arcfour_translate_usage(usage); if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, l40, salt.length); salt.data[10]=ms_usage & 0xff; @@ -319,3 +319,4 @@ krb5_arcfour_decrypt(enc, hash, key, usage, ivec, input, output) free(plaintext.data); return (ret); } + diff --git a/src/lib/crypto/cksumtypes.c b/src/lib/crypto/cksumtypes.c index 5b36657..76882f8 100644 --- a/src/lib/crypto/cksumtypes.c +++ b/src/lib/crypto/cksumtypes.c @@ -71,6 +71,19 @@ const struct krb5_cksumtypes krb5_cksumtypes_list[] = { "hmac-sha1-des3-kd", "HMAC-SHA1 DES3 key", /* alias */ 0, NULL, &krb5int_hash_sha1 }, + { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0, + "hmac-md5-rc4", "Microsoft HMAC MD5 (RC4 key)", + ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, + NULL }, + { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0, + "hmac-md5-enc", "Microsoft HMAC MD5 (RC4 key)", /*Heimdal alias*/ + ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, + NULL }, + { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0, + "hmac-md5-earcfour", "Microsoft HMAC MD5 (RC4 key)", /* alias*/ + ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, + NULL }, + }; const int krb5_cksumtypes_length = diff --git a/src/lib/crypto/configure.in b/src/lib/crypto/configure.in index 18ac537..acfef8d 100644 --- a/src/lib/crypto/configure.in +++ b/src/lib/crypto/configure.in @@ -30,4 +30,5 @@ K5_GEN_MAKEFILE(md5, libobj) K5_GEN_MAKEFILE(old, libobj) K5_GEN_MAKEFILE(raw, libobj) K5_GEN_MAKEFILE(sha1, libobj) +K5_GEN_MAKEFILE(arcfour, libobj) K5_AC_OUTPUT diff --git a/src/lib/crypto/enc_provider/ChangeLog b/src/lib/crypto/enc_provider/ChangeLog index 6a63ec8..035d41b 100644 --- a/src/lib/crypto/enc_provider/ChangeLog +++ b/src/lib/crypto/enc_provider/ChangeLog @@ -1,3 +1,11 @@ +2001-10-23 Sam Hartman + + * enc_provider.h: New encryption provider: rc4 + +2001-10-19 Sam Hartman + + * arcfour.c: Move prototype for static functions here rather than in a header file. + 2001-05-31 Ezra Peisach * des.c (k5_des_docrypt): Do not use a variable named "encrypt" diff --git a/src/lib/crypto/enc_provider/Makefile.in b/src/lib/crypto/enc_provider/Makefile.in index 64922d4..64e7ac5 100644 --- a/src/lib/crypto/enc_provider/Makefile.in +++ b/src/lib/crypto/enc_provider/Makefile.in @@ -2,7 +2,7 @@ thisconfigdir=./.. myfulldir=lib/crypto/enc_provider mydir=enc_provider BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -LOCALINCLUDES = -I$(srcdir)/../des +LOCALINCLUDES = -I$(srcdir)/../des -I$(srcdir)/../arcfour ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=enc_provider @@ -14,11 +14,11 @@ PROG_RPATH=$(KRB5_LIBDIR) RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -STLIBOBJS= des.o des3.o +STLIBOBJS= des.o des3.o arcfour.o -OBJS= $(OUTPRE)des.$(OBJEXT) $(OUTPRE)des3.$(OBJEXT) +OBJS= $(OUTPRE)des.$(OBJEXT) $(OUTPRE)des3.$(OBJEXT) $(OUTPRE)arcfour.$(OBJEXT) -SRCS= $(srcdir)/des.c $(srcdir)/des3.c +SRCS= $(srcdir)/des.c $(srcdir)/des3.c $(srcdir)/arcfour.c ##DOS##LIBOBJS = $(OBJS) diff --git a/src/lib/crypto/enc_provider/arcfour.c b/src/lib/crypto/enc_provider/arcfour.c new file mode 100644 index 0000000..956b75e --- /dev/null +++ b/src/lib/crypto/enc_provider/arcfour.c @@ -0,0 +1,193 @@ +/* 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" +/* gets the next byte from the PRNG */ +static inline unsigned int k5_arcfour_byte(ArcfourContext *); + +/* 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(krb5_const krb5_keyblock *, krb5_const krb5_data *, + krb5_const krb5_data *, krb5_data *); + + +/* The blocksize for the enctype */ +static void k5_arcfour_blocksize(size_t *); + +/* keysize for the enctype (number of bytes, and length of key (parity/etc) */ +static void k5_arcfour_keysize(size_t *, size_t *); + +/* from a random bitstrem, construct a key */ +static krb5_error_code +k5_arcfour_make_key(krb5_const krb5_data *, krb5_keyblock *); + +static char arcfour_weakkey1[] = {0x00, 0x00, 0xfd}; +static char arcfour_weakkey2[] = {0x03, 0xfd, 0xfc}; +static krb5_data arcfour_weakkeys[] = { {KV5M_DATA, sizeof (arcfour_weakkey1), + arcfour_weakkey1}, + {KV5M_DATA, sizeof (arcfour_weakkey2), + arcfour_weakkey2}, + {KV5M_DATA, 0, 0} +}; + +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;arcfour_weakkeys[counter].length >0; counter++) + if (memcmp(key, arcfour_weakkeys[counter].data, + arcfour_weakkeys[counter].length) == 0) + 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; +} + +/* This seems to work... although I am not sure what the implications are + in other places in the kerberos library */ +static void +k5_arcfour_blocksize(size_t *blocksize) +{ + *blocksize = 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. +*/ +static void +k5_arcfour_keysize(size_t *keybytes, size_t *keylength) +{ + *keybytes = 16; + *keylength = 16; +} + +/* The workhorse of the arcfour system, this impliments the cipher */ +static krb5_error_code +k5_arcfour_docrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *state, + krb5_const krb5_data *input, krb5_data *output) +{ + ArcfourContext *arcfour_ctx; + int ret; + + if (key->length != 16) + return(KRB5_BAD_KEYSIZE); + if (state && (state->length != sizeof (ArcfourContext))) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + if (state) { + arcfour_ctx=(ArcfourContext *)state->data; + k5_arcfour_crypt(arcfour_ctx, output->data, 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, output->data, input->data, input->length); + memset(arcfour_ctx, 0, sizeof (ArcfourContext)); + free(arcfour_ctx); + } + + return 0; +} + +static krb5_error_code +k5_arcfour_make_key(krb5_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); +} + +/* Since the arcfour cipher is identical going forwards and backwards, + we just call "docrypt" directly +*/ +const struct krb5_enc_provider krb5int_enc_arcfour = { + k5_arcfour_blocksize, + k5_arcfour_keysize, + k5_arcfour_docrypt, + k5_arcfour_docrypt, + k5_arcfour_make_key +}; diff --git a/src/lib/crypto/enc_provider/enc_provider.h b/src/lib/crypto/enc_provider/enc_provider.h index ac95b58..9a3dafb 100644 --- a/src/lib/crypto/enc_provider/enc_provider.h +++ b/src/lib/crypto/enc_provider/enc_provider.h @@ -28,3 +28,6 @@ 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; + + diff --git a/src/lib/crypto/etypes.c b/src/lib/crypto/etypes.c index 7aa3161..f1d2c9d 100644 --- a/src/lib/crypto/etypes.c +++ b/src/lib/crypto/etypes.c @@ -31,6 +31,7 @@ #include "old.h" #include "raw.h" #include "dk.h" +#include "arcfour.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 @@ -92,6 +93,25 @@ const struct krb5_keytypes krb5_enctypes_list[] = { &krb5int_enc_des, &krb5int_hash_sha1, krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, krb5_dk_string_to_key }, + { ENCTYPE_ARCFOUR_HMAC, + "arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour, + &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt, + krb5_arcfour_decrypt, krb5_arcfour_string_to_key }, + { ENCTYPE_ARCFOUR_HMAC, /* alias */ + "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour, + &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt, + krb5_arcfour_decrypt, krb5_arcfour_string_to_key }, + { ENCTYPE_ARCFOUR_HMAC_EXP, + "arcfour-hmac-exp", "Exportable ArcFour with HMAC/md5", + &krb5int_enc_arcfour, + &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt, + krb5_arcfour_decrypt, krb5_arcfour_string_to_key }, + { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */ + "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5", + &krb5int_enc_arcfour, + &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt, + krb5_arcfour_decrypt, krb5_arcfour_string_to_key }, + #ifdef ATHENA_DES3_KLUDGE /* * If you are using this, you're almost certainly doing the diff --git a/src/lib/crypto/keyhash_provider/ChangeLog b/src/lib/crypto/keyhash_provider/ChangeLog index 5ca3844..c52095a 100644 --- a/src/lib/crypto/keyhash_provider/ChangeLog +++ b/src/lib/crypto/keyhash_provider/ChangeLog @@ -1,5 +1,13 @@ +2001-10-23 Sam Hartman + + * k5_md5des.c (k5_md5des_verify): Add usage + + * k5_md4des.c (k5_md4des_verify): Add usage + 2001-10-22 Sam Hartman + * keyhash_provider.h hmac_md5.c: Implement Microsoft hmac-md5 keyhash provider + * t_cksum.c (main): Include key usage in hash call. * k5_md5des.c (k5_md5des_hash): add usage diff --git a/src/lib/crypto/keyhash_provider/Makefile.in b/src/lib/crypto/keyhash_provider/Makefile.in index 58792ec..7b75853 100644 --- a/src/lib/crypto/keyhash_provider/Makefile.in +++ b/src/lib/crypto/keyhash_provider/Makefile.in @@ -3,7 +3,8 @@ myfulldir=lib/crypto/keyhash_provider mydir=keyhash_provider BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) LOCALINCLUDES = -I$(srcdir)/../des -I$(srcdir)/../md4 \ - -I$(srcdir)/../md5 + -I$(srcdir)/../md5 -I$(srcdir)/../arcfour \ + -I$(srcdir)/../hash_provider ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=keyhash_provider @@ -15,11 +16,11 @@ PROG_RPATH=$(KRB5_LIBDIR) RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -STLIBOBJS= descbc.o k5_md4des.o k5_md5des.o +STLIBOBJS= descbc.o k5_md4des.o k5_md5des.o hmac_md5.o -OBJS= $(OUTPRE)descbc.$(OBJEXT) $(OUTPRE)k5_md4des.$(OBJEXT) $(OUTPRE)k5_md5des.$(OBJEXT) +OBJS= $(OUTPRE)descbc.$(OBJEXT) $(OUTPRE)k5_md4des.$(OBJEXT) $(OUTPRE)k5_md5des.$(OBJEXT) $(OUTP)hmac_md5.$(OBJEXT) -SRCS= $(srcdir)/descbc.c $(srcdir)/k5_md4des.c $(srcdir)/k5_md5des.c +SRCS= $(srcdir)/descbc.c $(srcdir)/k5_md4des.c $(srcdir)/k5_md5des.c $(srcdir)/hmac_md5.c ##DOS##LIBOBJS = $(OBJS) diff --git a/src/lib/crypto/keyhash_provider/hmac_md5.c b/src/lib/crypto/keyhash_provider/hmac_md5.c new file mode 100644 index 0000000..2f406c5 --- /dev/null +++ b/src/lib/crypto/keyhash_provider/hmac_md5.c @@ -0,0 +1,102 @@ +/* + * lib/crypto/keyhash_provider/hmac_md5.c + * +(I don't know) +. + * Copyright2001 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" + +static void +k5_hmac_md5_hash_size (size_t *output) +{ + *output = 16; +} + +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.length == 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); + t[0] = (ms_usage) & 0xff; + t[1] = (ms_usage>>8) & 0xff; + t[2] = (ms_usage >>16) & 0xff; + t[3] = (ms_usage>>24) & 0XFF; + 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; +} + + + +const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5 = { + k5_hmac_md5_hash_size, + k5_hmac_md5_hash, + NULL /*checksum again*/ +}; + diff --git a/src/lib/crypto/keyhash_provider/k5_md4des.c b/src/lib/crypto/keyhash_provider/k5_md4des.c index 8e03357..5ff50bf 100644 --- a/src/lib/crypto/keyhash_provider/k5_md4des.c +++ b/src/lib/crypto/keyhash_provider/k5_md4des.c @@ -110,7 +110,8 @@ k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i } static krb5_error_code -k5_md4des_verify(const krb5_keyblock *key, const krb5_data *ivec, +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) { diff --git a/src/lib/crypto/keyhash_provider/k5_md5des.c b/src/lib/crypto/keyhash_provider/k5_md5des.c index 012bc85..2a2bef3 100644 --- a/src/lib/crypto/keyhash_provider/k5_md5des.c +++ b/src/lib/crypto/keyhash_provider/k5_md5des.c @@ -110,7 +110,7 @@ k5_md5des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i } static krb5_error_code -k5_md5des_verify(const krb5_keyblock *key, const krb5_data *ivec, +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) { diff --git a/src/lib/crypto/keyhash_provider/keyhash_provider.h b/src/lib/crypto/keyhash_provider/keyhash_provider.h index 1393500..6a96faf 100644 --- a/src/lib/crypto/keyhash_provider/keyhash_provider.h +++ b/src/lib/crypto/keyhash_provider/keyhash_provider.h @@ -29,3 +29,4 @@ 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; diff --git a/src/lib/crypto/t_encrypt.c b/src/lib/crypto/t_encrypt.c new file mode 100644 index 0000000..bf7cfca --- /dev/null +++ b/src/lib/crypto/t_encrypt.c @@ -0,0 +1,87 @@ +/* + * lib/crypto/t_encrypt.c + * + * Copyright2001 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. + * + * + * <<< Description >>> + */ +/* + * Some black-box tests of crypto systems. Make sure that we can decrypt things we encrypt, etc. + */ + +#include "k5-int.h" +#include "etypes.h" +#include + +/* What enctypes should we test?*/ +krb5_enctype interesting_enctypes[] = { + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD4, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES3_CBC_SHA1, + ENCTYPE_ARCFOUR_HMAC, + ENCTYPE_ARCFOUR_HMAC_EXP, + 0 +}; + +#define test(msg, exp) \ +printf ("%s: . . . ", msg); \ +retval = (exp);\ +if( retval) { \ + printf( "Failed: %s\n", error_message(retval)); \ + abort(); \ +} else printf ("OK\n"); + +int main () { + krb5_context context ; + krb5_data in, out, check; + int i; + krb5_enc_data enc_out; + krb5_error_code retval; + krb5_keyblock key; + in.data = "This is a test.\n"; + in.length = strlen (in.data); + + test ("Seeding random number generator", + krb5_c_random_seed (context, &in)); + out.data = malloc(2048); + check.data = malloc(2048); + out.length = 2048; + check.length = 2048; + for (i = 0; interesting_enctypes[i]; i++) { + krb5_enctype enctype = interesting_enctypes [i]; + printf ("Testing enctype %d\n", enctype); + test ("Generating random key", + krb5_c_make_random_key (context, enctype, &key)); + enc_out.ciphertext = out; + krb5_c_encrypt_length (context, key.enctype, in.length, &enc_out.ciphertext.length); + test ("Encrypting", + krb5_c_encrypt (context, &key, 7, 0, &in, &enc_out)); + test ("Decrypting", + krb5_c_decrypt (context, &key, 7, 0, &enc_out, &check)); + } + return 0; +} + + diff --git a/src/lib/crypto/verify_checksum.c b/src/lib/crypto/verify_checksum.c index 841b6df..0c97cb5 100644 --- a/src/lib/crypto/verify_checksum.c +++ b/src/lib/crypto/verify_checksum.c @@ -57,7 +57,7 @@ krb5_c_verify_checksum(context, key, usage, data, cksum, valid) if (krb5_cksumtypes_list[i].keyhash && krb5_cksumtypes_list[i].keyhash->verify) - return((*(krb5_cksumtypes_list[i].keyhash->verify))(key, 0, data, + return((*(krb5_cksumtypes_list[i].keyhash->verify))(key, usage, 0, data, &indata, valid)); /* otherwise, make the checksum again, and compare */ -- cgit v1.1