* Add krb5_c_init_state and krb5_c_free_state functions
authorSam Hartman <hartmans@mit.edu>
Tue, 6 Nov 2001 15:25:49 +0000 (15:25 +0000)
committerSam Hartman <hartmans@mit.edu>
Tue, 6 Nov 2001 15:25:49 +0000 (15:25 +0000)
* Add init_state and free_state to enc_providers as operations that need to be filled in
* Implement generic free_state and des-specific init_state
* Implement arcfour-specific init_state
* Add functions to find enctype state functions and call them
* Add tests for above

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13948 dc483132-0cff-0310-8789-dd5450dbe970

14 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/default_state.c [new file with mode: 0644]
src/lib/crypto/enc_provider/ChangeLog
src/lib/crypto/enc_provider/arcfour.c
src/lib/crypto/enc_provider/des.c
src/lib/crypto/enc_provider/des3.c
src/lib/crypto/state.c [new file with mode: 0644]
src/lib/crypto/t_encrypt.c

index b7be662418f4df10cf83881a5bc20c665fa4eec1..e1818dde59d093da5dea69703ea96a9df0972d84 100644 (file)
@@ -1,3 +1,15 @@
+2001-11-06  Sam Hartman  <hartmans@tir-na-nogth.mit.edu>
+
+       * k5-int.h: Add krb5int_des_init_state and krb5int_default_free_state
+
+2001-11-06  Sam Hartman  <hartmans@mit.edu>
+
+       * k5-int.h: Add init_state and free_state to enc_provider struct
+
+2001-11-05  Sam Hartman  <hartmans@mit.edu>
+
+       * krb5.hin:  Add krb5_c_init_state and krb5_c_free_state
+
 2001-10-30  Ezra Peisach  <epeisach@mit.edu>
 
        * fake-addrinfo.c (freeaddrinfo): Do not free NULL pointers.
index fa8c9c28ae541b70beab96078927782eb746a724..4d04738cab7c5656cc31bff45ede19052dd45ad8 100644 (file)
@@ -521,9 +521,9 @@ struct krb5_enc_provider {
        keylength is the output size */
     void (*keysize) (size_t *keybytes, size_t *keylength);
 
-    /* ivec == 0 is an all-zeros ivec */
+    /* cipher-state == 0 fresh state thrown away at end */
     krb5_error_code (*encrypt) (krb5_const krb5_keyblock *key,
-                               krb5_const krb5_data *ivec,
+                               krb5_const krb5_data *cipher_state,
                                krb5_const krb5_data *input,
                                krb5_data *output);
 
@@ -534,6 +534,11 @@ struct krb5_enc_provider {
 
     krb5_error_code (*make_key) (krb5_const krb5_data *randombits,
                                 krb5_keyblock *key);
+
+  krb5_error_code (*init_state) (krb5_const krb5_keyblock *key,
+                                krb5_keyusage keyusage, krb5_data *out_state);
+  krb5_error_code (*free_state) (krb5_data *state);
+  
 };
 
 struct krb5_hash_provider {
@@ -623,6 +628,21 @@ krb5_error_code krb5_hmac
                krb5_const krb5_keyblock *key, unsigned int icount,
                krb5_const krb5_data *input, krb5_data *output);
 
+/* A definition of init_state for DES based encryption systems.
+ * sets up an 8-byte IV of all zeros
+ */
+
+krb5_error_code krb5int_des_init_state
+(krb5_const krb5_keyblock *key, krb5_keyusage usage, krb5_data *new_state);
+
+/* 
+ * normally to free a cipher_state you can just memset the length to zero and
+ * free it.
+ */
+krb5_error_code krb5int_default_free_state
+(krb5_data *state);
+
+
 /* 
  * These declarations are here, so both krb5 and k5crypto
  * can get to them.
index 4119085a3d23abb1a1f90ee4d59ac0575e31723c..88185c2e9a9d8bbd0f5ce387bfe88c1bce09ce03 100644 (file)
@@ -371,13 +371,13 @@ typedef struct _krb5_enc_data {
 krb5_error_code KRB5_CALLCONV
     krb5_c_encrypt
     (krb5_context context, krb5_const krb5_keyblock *key,
-                   krb5_keyusage usage, krb5_const krb5_data *ivec,
+                   krb5_keyusage usage, krb5_const krb5_data *cipher_state,
                    krb5_const krb5_data *input, krb5_enc_data *output);
 
 krb5_error_code KRB5_CALLCONV
     krb5_c_decrypt
     (krb5_context context, krb5_const krb5_keyblock *key,
-                   krb5_keyusage usage, krb5_const krb5_data *ivec,
+                   krb5_keyusage usage, krb5_const krb5_data *cipher_state,
                    krb5_const krb5_enc_data *input, krb5_data *output);
 
 krb5_error_code KRB5_CALLCONV
@@ -390,6 +390,16 @@ krb5_error_code KRB5_CALLCONV
     (krb5_context context, krb5_enctype enctype,
                    size_t *blocksize);
 
+krb5_error_code KRB5_CALLCONV
+       krb5_c_init_state
+(krb5_context context,
+krb5_const krb5_keyblock *key, krb5_keyusage usage,
+krb5_data *new_state);
+
+krb5_error_code KRB5_CALLCONV
+       krb5_c_free_state
+(krb5_context context, krb5_const krb5_keyblock *key, krb5_data *state);
+
 krb5_error_code KRB5_CALLCONV
     krb5_c_make_random_key
     (krb5_context context, krb5_enctype enctype,
index c5b7371485daab000b67a638de38fdf6bac0eeda..f91e7bee1e4cf9ecc8b96b024feaac2b47f49c30 100644 (file)
@@ -1,3 +1,9 @@
+2001-11-06  Sam Hartman  <hartmans@tir-na-nogth.mit.edu>
+
+       * state.c: New file
+
+       * default_state.c: New file.
+
 2001-10-29  Jeff Altman   <jaltman@columbia.edu>
 
         * Makefile.in - Windows configuration for src/lib/crypto/arcfour
index 672af7a26cbd4f57e3eecc416f6c6ab1f1e70109..39f70d8fd3cbe6dba513cb812b70d46d5ef6af52 100644 (file)
@@ -30,6 +30,7 @@ STLIBOBJS=\
        cksumtypes.o            \
        coll_proof_cksum.o      \
        crypto_libinit.o        \
+       default_state.o \
        decrypt.o               \
        encrypt.o               \
        encrypt_length.o        \
@@ -44,6 +45,7 @@ STLIBOBJS=\
        nfold.o                 \
        old_api_glue.o          \
        prng.o                  \
+       state.o \
        string_to_cksumtype.o   \
        string_to_enctype.o     \
        string_to_key.o         \
@@ -58,6 +60,7 @@ OBJS=\
        $(OUTPRE)cksumtypes.$(OBJEXT)           \
        $(OUTPRE)coll_proof_cksum.$(OBJEXT)     \
        $(OUTPRE)crypto_libinit.$(OBJEXT)       \
+       $(OUTPRE)default_state.$(OBJEXT) \
        $(OUTPRE)decrypt.$(OBJEXT)              \
        $(OUTPRE)encrypt.$(OBJEXT)              \
        $(OUTPRE)encrypt_length.$(OBJEXT)       \
@@ -72,6 +75,7 @@ OBJS=\
        $(OUTPRE)nfold.$(OBJEXT)                \
        $(OUTPRE)old_api_glue.$(OBJEXT)         \
        $(OUTPRE)prng.$(OBJEXT)                 \
+       $(OUTPRE)state.$(OBJEXT) \
        $(OUTPRE)string_to_cksumtype.$(OBJEXT)  \
        $(OUTPRE)string_to_enctype.$(OBJEXT)    \
        $(OUTPRE)string_to_key.$(OBJEXT)        \
@@ -86,6 +90,7 @@ SRCS=\
        $(srcdir)/cksumtypes.c          \
        $(srcdir)/coll_proof_cksum.c    \
        $(srcdir)/crypto_libinit.c      \
+       $(srcdir)/default_state.c \
        $(srcdir)/decrypt.c             \
        $(srcdir)/encrypt.c             \
        $(srcdir)/encrypt_length.c      \
@@ -100,6 +105,7 @@ SRCS=\
        $(srcdir)/nfold.c               \
        $(srcdir)/old_api_glue.c        \
        $(srcdir)/prng.c                \
+       $(srcdir)/state.c \
        $(srcdir)/string_to_cksumtype.c \
        $(srcdir)/string_to_enctype.c   \
        $(srcdir)/string_to_key.c       \
index f3b4a5040f00db0bfc519457372dafac4a50652b..d511f8f007a0edf4418e7e97a56730fb91903b7a 100644 (file)
@@ -1,3 +1,7 @@
+2001-11-06  Sam Hartman  <hartmans@mit.edu>
+
+       * arcfour-int.h: Structure for arcfour cipher state
+       
 2001-10-26  Ezra Peisach  <epeisach@mit.edu>
 
        * string_to_key.c (krb5_arcfour_string_to_key): Cleanup variables
index b54fce1e2ab469f89fb0eb458ae98c264951ff84..398fe57a1d8068ed84ee06ccdb4abcf511539b01 100644 (file)
@@ -20,6 +20,11 @@ typedef struct
    unsigned char state[256];
 } ArcfourContext;
 
+typedef struct {
+  int initialized;
+  ArcfourContext ctx;
+} ArcFourCipherState;
+
 krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage);
 
 
diff --git a/src/lib/crypto/default_state.c b/src/lib/crypto/default_state.c
new file mode 100644 (file)
index 0000000..33a189f
--- /dev/null
@@ -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;
+}
+
+    
+  
index 4fe632c8667c7ff32b976663c69bc37f4c299d86..4b06974c2f83e04108801bec470e8f8fceed4920 100644 (file)
@@ -1,3 +1,11 @@
+2001-11-06  Sam Hartman  <hartmans@mit.edu>
+
+       * arcfour.c (k5_arcfour_docrypt): Treat state as an
+       ArcFourCipherState structure; manipulate and initialize as appropriate.
+       (k5_arcfour_init_state): new function
+
+       * arcfour.c des.c des3.c:  Add state functions
+
 2001-10-23  Sam Hartman  <hartmans@mit.edu>
 
        * arcfour.c (endif /* gcc inlines*/): handle inlines in an ansi-compatible manner
index 43c71f17957edad3ac28efb9373e97abdcb7cc09..28627b7844fa8bd7e1aab6370949e4ee691554d0 100644 (file)
@@ -146,17 +146,25 @@ k5_arcfour_docrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *state,
               krb5_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 (ArcfourContext)))
+  if (state && (state->length != sizeof (ArcFourCipherState)))
     return(KRB5_BAD_MSIZE);
   if (input->length != output->length)
     return(KRB5_BAD_MSIZE);
 
   if (state) {
-    arcfour_ctx=(ArcfourContext *)state->data;
+    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 {
@@ -192,6 +200,26 @@ k5_arcfour_make_key(krb5_const krb5_data *randombits, krb5_keyblock *key)
     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
 */
@@ -200,5 +228,7 @@ const struct krb5_enc_provider krb5int_enc_arcfour = {
     k5_arcfour_keysize,
     k5_arcfour_docrypt,
     k5_arcfour_docrypt,
-    k5_arcfour_make_key
+    k5_arcfour_make_key,
+    k5_arcfour_init_state, /*xxx not implemented yet*/
+    krb5int_default_free_state
 };
index e12ddcdc9aa0467663cfc4dbae342763867340d9..e9ecb72e1e9f5d88f0b2f06f7562dccdde63c4ba 100644 (file)
@@ -126,5 +126,7 @@ const struct krb5_enc_provider krb5int_enc_des = {
     k5_des_keysize,
     k5_des_encrypt,
     k5_des_decrypt,
-    k5_des_make_key
+    k5_des_make_key,
+    krb5int_des_init_state,
+    krb5int_default_free_state
 };
index 5f638fdbae357cae67a148ba666f437a2b23f203..91579c6ab7d3705be4515fbd8aba42072fc26d6c 100644 (file)
@@ -131,5 +131,7 @@ const struct krb5_enc_provider krb5int_enc_des3 = {
     k5_des3_keysize,
     k5_des3_encrypt,
     k5_des3_decrypt,
-    k5_des3_make_key
+    k5_des3_make_key,
+    krb5int_des_init_state,
+    krb5int_default_free_state
 };
diff --git a/src/lib/crypto/state.c b/src/lib/crypto/state.c
new file mode 100644 (file)
index 0000000..30e52ef
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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_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_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);
+}
index 6cdfc21c62284964eb8183f3c046f1e12f9bd448..db20210c38c99420ce0a89d7364914f3add1f11a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * lib/crypto/t_encrypt.c
+main * lib/crypto/t_encrypt.c
  *
  * Copyright2001 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
@@ -53,9 +53,11 @@ if( retval) { \
   abort(); \
 } else printf ("OK\n");
   
-int main () {
+int
+main ()
+{
   krb5_context context ;
-  krb5_data  in, out, check;
+  krb5_data  in, out, check, state;
   int i;
   size_t len;
   krb5_enc_data enc_out;
@@ -85,6 +87,14 @@ int main () {
          krb5_c_encrypt (context, &key, 7, 0, &in, &enc_out));
     test ("Decrypting",
          krb5_c_decrypt (context, &key, 7, 0, &enc_out, &check));
+    test ("init_state",
+         krb5_c_init_state (context, &key, 7, &state));
+        test ("Encrypting with state",
+         krb5_c_encrypt (context, &key, 7, &state, &in, &enc_out));
+    test ("Decrypting",
+         krb5_c_decrypt (context, &key, 7, 0, &enc_out, &check));
+    test ("free_state",
+         krb5_c_free_state (context, &key, &state));
   }
   return 0;
 }