* Tie in Microsoft rc4 cipher and make it build
authorSam Hartman <hartmans@mit.edu>
Tue, 23 Oct 2001 21:15:04 +0000 (21:15 +0000)
committerSam Hartman <hartmans@mit.edu>
Tue, 23 Oct 2001 21:15:04 +0000 (21:15 +0000)
* 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

23 files changed:
src/include/ChangeLog
src/include/k5-int.h
src/include/krb5.hin
src/lib/crypto/ChangeLog
src/lib/crypto/Makefile.in
src/lib/crypto/arcfour/ChangeLog
src/lib/crypto/arcfour/arcfour-int.h
src/lib/crypto/arcfour/arcfour.c
src/lib/crypto/cksumtypes.c
src/lib/crypto/configure.in
src/lib/crypto/enc_provider/ChangeLog
src/lib/crypto/enc_provider/Makefile.in
src/lib/crypto/enc_provider/arcfour.c [new file with mode: 0644]
src/lib/crypto/enc_provider/enc_provider.h
src/lib/crypto/etypes.c
src/lib/crypto/keyhash_provider/ChangeLog
src/lib/crypto/keyhash_provider/Makefile.in
src/lib/crypto/keyhash_provider/hmac_md5.c [new file with mode: 0644]
src/lib/crypto/keyhash_provider/k5_md4des.c
src/lib/crypto/keyhash_provider/k5_md5des.c
src/lib/crypto/keyhash_provider/keyhash_provider.h
src/lib/crypto/t_encrypt.c [new file with mode: 0644]
src/lib/crypto/verify_checksum.c

index 6aef81d0b960db4c2978e85243b1f358fbbfd3d1..f50cb595cb62e8f65b278a747c48ddb72ffe41a5 100644 (file)
@@ -1,3 +1,8 @@
+2001-10-23  Sam Hartman  <hartmans@mit.edu>
+
+       * krb5.hin: Add rc4-hmac, rc4-hmac-exp enctypes,  hmac-md5-rc4
+       cksumtype 
+
 2001-10-22  Sam Hartman  <hartmans@mit.edu>
 
        * k5-int.h: keyhash_provider gains usage argument to hash function
index d180e00f31a300c4991cba2962bc904cc6ee94cb..9f7a78ebae59e007caabf951900984ea24910d12 100644 (file)
@@ -556,6 +556,7 @@ struct krb5_keyhash_provider {
                             krb5_data *output);
 
     krb5_error_code (*verify) (krb5_const krb5_keyblock *key,
+                              krb5_keyusage usage,
                               krb5_const krb5_data *ivec,
                               krb5_const krb5_data *input,
                               krb5_const krb5_data *hash,
index 710e6d6a4a0dcb328dee51ebacebf644a7bf723e..4119085a3d23abb1a1f90ee4d59ac0575e31723c 100644 (file)
@@ -334,6 +334,8 @@ typedef struct _krb5_enc_data {
 #define        ENCTYPE_DES3_CBC_RAW    0x0006  /* DES-3 cbc mode raw */
 #define ENCTYPE_DES_HMAC_SHA1  0x0008
 #define ENCTYPE_DES3_CBC_SHA1  0x0010
+#define ENCTYPE_ARCFOUR_HMAC   0x0017
+#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
 #define ENCTYPE_UNKNOWN                0x01ff
 /* local crud */
 /* marc's DES-3 with 32-bit length */
@@ -349,6 +351,7 @@ typedef struct _krb5_enc_data {
 #define        CKSUMTYPE_RSA_MD5_DES   0x0008
 #define CKSUMTYPE_NIST_SHA     0x0009
 #define CKSUMTYPE_HMAC_SHA1_DES3       0x000c
+#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /*Microsoft md5 hmac cksumtype*/
 
 #ifndef krb5_roundup
 /* round x up to nearest multiple of y */
index d8fbcfc502e432fef53373a71944f2dba5a046b5..8df6f5028bf3c8bee33ee3f96beb101cbb1af68c 100644 (file)
@@ -1,3 +1,13 @@
+2001-10-23  Sam Hartman  <hartmans@mit.edu>
+
+       * 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  <hartmans@mit.edu>
 
        * make_checksum.c (krb5_c_make_checksum):  Include key usage
index f41d19cdc24b061f4ef850d8d11da7c59bc4d13a..0710d6f8085baf3f2db89722279b4f7bb12c582f 100644 (file)
@@ -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
index 91782a055de80b30cf59eac7db36a4f9d7de7ab6..f82226281b17f0f0df3f3d4d7954945337d3032b 100644 (file)
@@ -1,3 +1,8 @@
+2001-10-22  Sam Hartman  <hartmans@mit.edu>
+
+       * arcfour-int.h: Make krb5int_arcfour_translate_usage non-static so the hash can use it
+       
+
 2001-10-19  Sam Hartman  <hartmans@mit.edu>
 
        * string_to_key.c (krb5_arcfour_string_to_key): Ignore salt
index 2b2557634783392588095e22d2535bbacd9678b8..b54fce1e2ab469f89fb0eb458ae98c264951ff84 100644 (file)
@@ -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 */
index b26a3f330fd9f5322da3c4ebdc042cf439527371..cc1857770bc58e034798701d6e6e1612e5171df6 100644 (file)
@@ -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);
 }
+
index 5b36657a742544adba8429b1dc4cdc55530332d4..76882f87d128522c62e71de095702fa12ccc8244 100644 (file)
@@ -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 =
index 18ac537532aad624873bfaff314dae7dc7f94cf6..acfef8d7f639bd097a91cc4b47de0b88108f0827 100644 (file)
@@ -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
index 6a63ec8a73094438ab507b507a3975c91dfa7d5b..035d41b9dbe920d97c7d7daf4986eb526f0cbf3b 100644 (file)
@@ -1,3 +1,11 @@
+2001-10-23  Sam Hartman  <hartmans@mit.edu>
+
+       * enc_provider.h: New encryption provider: rc4
+
+2001-10-19  Sam Hartman  <hartmans@mit.edu>
+
+       * arcfour.c: Move prototype for static functions here  rather than in a header file.
+
 2001-05-31  Ezra Peisach  <epeisach@mit.edu>
 
        * des.c (k5_des_docrypt): Do not use a variable named "encrypt"
index 64922d47ce4cace4c292d7e8aeeaf2dec8245afb..64e7ac58807850ce959b25e481fb597724bf4696 100644 (file)
@@ -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 (file)
index 0000000..956b75e
--- /dev/null
@@ -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
+};
index ac95b58ae390aeb22fb11256e0166902e7a45d1c..9a3dafb8d6464f7458d56cfece0f4734e11dc15c 100644 (file)
@@ -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;
+
+
index 7aa316186b5e260e2e40f01d7c65fe520e4cf8fa..f1d2c9d6d271c2f64f456dc5c1eabb1c10f17a85 100644 (file)
@@ -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
index 5ca3844da1ae65cdf1fa8f6db1cad0350f8bc345..c52095a6a1dd56b0f5c20aa133af8f808fc9dbba 100644 (file)
@@ -1,5 +1,13 @@
+2001-10-23  Sam Hartman  <hartmans@mit.edu>
+
+       * k5_md5des.c (k5_md5des_verify): Add usage
+
+       * k5_md4des.c (k5_md4des_verify): Add usage
+
 2001-10-22  Sam Hartman  <hartmans@mit.edu>
 
+       * 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
index 58792ec8b51baeea470fa054f12ac68466aaf7ca..7b758531123acbf4513568547496185c4f7e3b20 100644 (file)
@@ -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 (file)
index 0000000..2f406c5
--- /dev/null
@@ -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*/
+};
+
index 8e03357d1541e80fb908250a047997b8d85c1523..5ff50bfdfac8ad6741139c6b2778e879d6b57ed5 100644 (file)
@@ -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)
 {
index 012bc850ca540683c7b86b92bbbdb36e845fd4f5..2a2bef38d4038730bbf3d7594abd363c0d39ecd4 100644 (file)
@@ -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)
 {
index 1393500883caab3e3a2c91743f12ea2870549374..6a96faf8ffce2b181d48a337f83355ac109d83fa 100644 (file)
@@ -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 (file)
index 0000000..bf7cfca
--- /dev/null
@@ -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 <stdio.h>
+
+/* 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;
+}
+
+       
index 841b6df8cb5d89886dadf8c9ce924ff84283f23f..0c97cb598f9c26f0236acb5ba90ab41db5ae429c 100644 (file)
@@ -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 */