svn rev #23378: trunk/src/ include/ lib/crypto/ lib/crypto/krb/arcfour/ lib/crypto/krb/prf/ ...

ghudson@MIT.EDU ghudson at MIT.EDU
Sat Nov 28 18:10:31 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=23378
Commit By: ghudson
Log Message:
Create functional internal interfaces to allow GSSAPI to perform
arcfour encryption of GSS tokens.  This factors out derivation of
the usage and encryption keys, and removes the need for the provider
structures to be visible to all of krb5 via k5-int.h.



Changed Files:
U   trunk/src/include/k5-int.h
U   trunk/src/lib/crypto/krb/arcfour/arcfour.c
U   trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c
U   trunk/src/lib/crypto/krb/prf/des_prf.c
U   trunk/src/lib/crypto/libk5crypto.exports
U   trunk/src/lib/gssapi/krb5/gssapiP_krb5.h
U   trunk/src/lib/gssapi/krb5/util_crypt.c
U   trunk/src/lib/krb5/os/accessor.c
Modified: trunk/src/include/k5-int.h
===================================================================
--- trunk/src/include/k5-int.h	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/include/k5-int.h	2009-11-28 23:10:31 UTC (rev 23378)
@@ -752,6 +752,18 @@
 krb5_error_code krb5int_pbkdf2_hmac_sha1(const krb5_data *, unsigned long,
                                          const krb5_data *, const krb5_data *);
 
+/* These crypto functions are used by GSSAPI via the accessor. */
+
+krb5_error_code
+krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
+                         const krb5_data *kd_data, const krb5_data *input,
+                         krb5_data *output);
+
+krb5_error_code
+krb5int_arcfour_gsscrypt_iov(const krb5_keyblock *keyblock,
+                             krb5_keyusage usage, const krb5_data *kd_data,
+                             krb5_crypto_iov *data, size_t num_data);
+
 /*
  * Attempt to zero memory in a way that compilers won't optimize out.
  *
@@ -843,15 +855,6 @@
 extern void krb5int_prng_cleanup(void);
 
 
-/*
- * These declarations are here, so both krb5 and k5crypto
- * can get to them.
- * krb5 needs to get to them so it can  make them available to libgssapi.
- */
-extern const struct krb5_enc_provider krb5int_enc_arcfour;
-extern const struct krb5_hash_provider krb5int_hash_md5;
-
-
 #ifdef KRB5_OLD_CRYPTO
 /* old provider api */
 
@@ -2192,19 +2195,24 @@
 /* To keep happy libraries which are (for now) accessing internal stuff */
 
 /* Make sure to increment by one when changing the struct */
-#define KRB5INT_ACCESS_STRUCT_VERSION 15
+#define KRB5INT_ACCESS_STRUCT_VERSION 16
 
 #ifndef ANAME_SZ
 struct ktext;                   /* from krb.h, for krb524 support */
 #endif
 typedef struct _krb5int_access {
     /* crypto stuff */
-    const struct krb5_hash_provider *md5_hash_provider;
-    const struct krb5_enc_provider *arcfour_enc_provider;
-    krb5_error_code (*hmac)(const struct krb5_hash_provider *hash,
-                            const krb5_keyblock *key,
-                            unsigned int icount, const krb5_data *input,
-                            krb5_data *output);
+    krb5_error_code (*arcfour_gsscrypt)(const krb5_keyblock *keyblock,
+                                        krb5_keyusage usage,
+                                        const krb5_data *kd_data,
+                                        const krb5_data *input,
+                                        krb5_data *output);
+    krb5_error_code (*arcfour_gsscrypt_iov)(const krb5_keyblock *keyblock,
+                                            krb5_keyusage usage,
+                                            const krb5_data *kd_data,
+                                            krb5_crypto_iov *data,
+                                            size_t num_data);
+
     krb5_error_code (*auth_con_get_subkey_enctype)(krb5_context,
                                                    krb5_auth_context,
                                                    krb5_enctype *);

Modified: trunk/src/lib/crypto/krb/arcfour/arcfour.c
===================================================================
--- trunk/src/lib/crypto/krb/arcfour/arcfour.c	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/crypto/krb/arcfour/arcfour.c	2009-11-28 23:10:31 UTC (rev 23378)
@@ -70,7 +70,7 @@
     return krb5int_hmac_keyblock(hash, session_keyblock, 1, &salt, &out_data);
 }
 
-/* Derive an encryption key from a usage key and checksum. */
+/* Derive an encryption key from a usage key and (typically) checksum. */
 krb5_error_code
 krb5int_arcfour_enc_key(const struct krb5_enc_provider *enc,
                         const struct krb5_hash_provider *hash,
@@ -264,3 +264,49 @@
     zapfree(comp_checksum.data, comp_checksum.length);
     return ret;
 }
+
+/* Encrypt or decrypt data for a GSSAPI token. */
+krb5_error_code
+krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
+                         const krb5_data *kd_data, const krb5_data *input,
+                         krb5_data *output)
+{
+    const struct krb5_enc_provider *enc = &krb5int_enc_arcfour;
+    const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+    krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+    krb5_key enc_key;
+    krb5_error_code ret;
+
+    ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+                                  &usage_keyblock);
+    if (ret != 0)
+        goto cleanup;
+    ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+                                  &enc_keyblock);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Derive a usage key from the session key and usage. */
+    ret = krb5int_arcfour_usage_key(enc, hash, keyblock, usage,
+                                    usage_keyblock);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Derive the encryption key from the usage key and kd_data. */
+    ret = krb5int_arcfour_enc_key(enc, hash, usage_keyblock, kd_data,
+                                  enc_keyblock);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Encrypt or decrypt (encrypt works for both) the input. */
+    ret = krb5_k_create_key(NULL, enc_keyblock, &enc_key);
+    if (ret != 0)
+        goto cleanup;
+    ret = (*enc->encrypt)(enc_key, 0, input, output);
+    krb5_k_free_key(NULL, enc_key);
+
+cleanup:
+    krb5int_c_free_keyblock(NULL, usage_keyblock);
+    krb5int_c_free_keyblock(NULL, enc_keyblock);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c
===================================================================
--- trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c	2009-11-28 23:10:31 UTC (rev 23378)
@@ -29,6 +29,7 @@
 #include "k5-int.h"
 #include "arcfour.h"
 #include "arcfour-int.h"
+#include "hash_provider/hash_provider.h"
 #include "aead.h"
 
 /* AEAD */
@@ -265,3 +266,48 @@
     krb5int_arcfour_encrypt_iov,
     krb5int_arcfour_decrypt_iov
 };
+
+krb5_error_code
+krb5int_arcfour_gsscrypt_iov(const krb5_keyblock *keyblock,
+                             krb5_keyusage usage, const krb5_data *kd_data,
+                             krb5_crypto_iov *data, size_t num_data)
+{
+    const struct krb5_enc_provider *enc = &krb5int_enc_arcfour;
+    const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+    krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+    krb5_key enc_key;
+    krb5_error_code ret;
+
+    ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+                                  &usage_keyblock);
+    if (ret != 0)
+        goto cleanup;
+    ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+                                  &enc_keyblock);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Derive a usage key from the session key and usage. */
+    ret = krb5int_arcfour_usage_key(enc, hash, keyblock, usage,
+                                    usage_keyblock);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Derive the encryption key from the usage key and kd_data. */
+    ret = krb5int_arcfour_enc_key(enc, hash, usage_keyblock, kd_data,
+                                  enc_keyblock);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Encrypt or decrypt (encrypt_iov works for both) the input. */
+    ret = krb5_k_create_key(NULL, enc_keyblock, &enc_key);
+    if (ret != 0)
+        goto cleanup;
+    ret = (*enc->encrypt_iov)(enc_key, 0, data, num_data);
+    krb5_k_free_key(NULL, enc_key);
+
+cleanup:
+    krb5int_c_free_keyblock(NULL, usage_keyblock);
+    krb5int_c_free_keyblock(NULL, enc_keyblock);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/prf/des_prf.c
===================================================================
--- trunk/src/lib/crypto/krb/prf/des_prf.c	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/crypto/krb/prf/des_prf.c	2009-11-28 23:10:31 UTC (rev 23378)
@@ -31,7 +31,7 @@
  */
 
 #include "prf_int.h"
-//#include <hash_provider/hash_provider.h>              /* XXX is this ok? */
+#include "hash_provider/hash_provider.h"
 
 krb5_error_code
 krb5int_des_prf (const struct krb5_enc_provider *enc,

Modified: trunk/src/lib/crypto/libk5crypto.exports
===================================================================
--- trunk/src/lib/crypto/libk5crypto.exports	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/crypto/libk5crypto.exports	2009-11-28 23:10:31 UTC (rev 23378)
@@ -65,7 +65,6 @@
 krb5int_c_free_keyblock
 krb5int_c_init_keyblock
 krb5int_hash_md5
-krb5int_hmac_keyblock
 krb5int_enc_arcfour
 krb5int_hmac
 mit_des_fixup_key_parity
@@ -96,3 +95,5 @@
 krb5int_MD5Final
 krb5int_aes_decrypt
 krb5int_enc_des3
+krb5int_arcfour_gsscrypt
+krb5int_arcfour_gsscrypt_iov

Modified: trunk/src/lib/gssapi/krb5/gssapiP_krb5.h
===================================================================
--- trunk/src/lib/gssapi/krb5/gssapiP_krb5.h	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/gssapi/krb5/gssapiP_krb5.h	2009-11-28 23:10:31 UTC (rev 23378)
@@ -299,14 +299,14 @@
                                 int iov_count);
 
 krb5_error_code
-kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage,
+kg_arcfour_docrypt (const krb5_keyblock *keyblock, int usage,
                     const unsigned char *kd_data, size_t kd_data_len,
                     const unsigned char *input_buf, size_t input_len,
                     unsigned char *output_buf);
 
 krb5_error_code
 kg_arcfour_docrypt_iov (krb5_context context,
-                        const krb5_keyblock *longterm_key , int ms_usage,
+                        const krb5_keyblock *keyblock, int usage,
                         const unsigned char *kd_data, size_t kd_data_len,
                         gss_iov_buffer_desc *iov,
                         int iov_count);

Modified: trunk/src/lib/gssapi/krb5/util_crypt.c
===================================================================
--- trunk/src/lib/gssapi/krb5/util_crypt.c	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/gssapi/krb5/util_crypt.c	2009-11-28 23:10:31 UTC (rev 23378)
@@ -282,73 +282,21 @@
 }
 
 krb5_error_code
-kg_arcfour_docrypt(const krb5_keyblock *longterm_key , int ms_usage,
+kg_arcfour_docrypt(const krb5_keyblock *keyblock, int usage,
                    const unsigned char *kd_data, size_t kd_data_len,
                    const unsigned char *input_buf, size_t input_len,
                    unsigned char *output_buf)
 {
     krb5_error_code code;
-    krb5_data input, output;
+    krb5_data kd = make_data((char *) kd_data, kd_data_len);
+    krb5_data input = make_data((char *) input_buf, input_len);
+    krb5_data output = make_data(output_buf, input_len);
     krb5int_access kaccess;
-    krb5_key key;
-    krb5_keyblock seq_enc_key, usage_key;
-    unsigned char t[14];
-    size_t i = 0;
-    int exportable = (longterm_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP);
 
-    usage_key.length = longterm_key->length;
-    usage_key.contents = malloc(usage_key.length);
-    if (usage_key.contents == NULL)
-        return (ENOMEM);
-    seq_enc_key.length = longterm_key->length;
-    seq_enc_key.contents = malloc(seq_enc_key.length);
-    if (seq_enc_key.contents == NULL) {
-        free ((void *) usage_key.contents);
-        return (ENOMEM);
-    }
-    code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+    code = krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION);
     if (code)
-        goto cleanup_arcfour;
-
-    if (exportable) {
-        memcpy(t, kg_arcfour_l40, sizeof(kg_arcfour_l40));
-        i += sizeof(kg_arcfour_l40);
-    }
-    store_32_le(ms_usage, &t[i]);
-    i += 4;
-    input.data = (void *) &t;
-    input.length = i;
-    output.data = (void *) usage_key.contents;
-    output.length = usage_key.length;
-    code = (*kaccess.hmac)(kaccess.md5_hash_provider, longterm_key, 1,
-                           &input, &output);
-    if (code)
-        goto cleanup_arcfour;
-    if (exportable)
-        memset(usage_key.contents + 7, 0xab, 9);
-
-    input.data = ( void *) kd_data;
-    input.length = kd_data_len;
-    output.data = (void *) seq_enc_key.contents;
-    code = (*kaccess.hmac)(kaccess.md5_hash_provider, &usage_key, 1,
-                           &input, &output);
-    if (code)
-        goto cleanup_arcfour;
-    input.data = ( void * ) input_buf;
-    input.length = input_len;
-    output.data = (void * ) output_buf;
-    output.length = input_len;
-    code = krb5_k_create_key(NULL, &seq_enc_key, &key);
-    if (code)
-        goto cleanup_arcfour;
-    code = (*kaccess.arcfour_enc_provider->encrypt)(key, 0, &input, &output);
-    krb5_k_free_key(NULL, key);
-cleanup_arcfour:
-    memset (seq_enc_key.contents, 0, seq_enc_key.length);
-    memset (usage_key.contents, 0, usage_key.length);
-    free (usage_key.contents);
-    free (seq_enc_key.contents);
-    return (code);
+        return code;
+    return (*kaccess.arcfour_gsscrypt)(keyblock, usage, &kd, &input, &output);
 }
 
 /* AEAD */
@@ -626,81 +574,29 @@
 }
 
 krb5_error_code
-kg_arcfour_docrypt_iov(krb5_context context,
-                       const krb5_keyblock *longterm_key, int ms_usage,
-                       const unsigned char *kd_data, size_t kd_data_len,
-                       gss_iov_buffer_desc *iov, int iov_count)
+kg_arcfour_docrypt_iov(krb5_context context, const krb5_keyblock *keyblock,
+                       int usage, const unsigned char *kd_data,
+                       size_t kd_data_len, gss_iov_buffer_desc *iov,
+                       int iov_count)
 {
     krb5_error_code code;
-    krb5_data input, output;
+    krb5_data kd = make_data((char *) kd_data, kd_data_len);
     krb5int_access kaccess;
-    krb5_key key;
-    krb5_keyblock seq_enc_key, usage_key;
-    unsigned char t[14];
-    size_t i = 0;
-    int exportable = (longterm_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP);
     krb5_crypto_iov *kiov = NULL;
     size_t kiov_count = 0;
 
-    usage_key.length = longterm_key->length;
-    usage_key.contents = malloc(usage_key.length);
-    if (usage_key.contents == NULL)
-        return (ENOMEM);
-    seq_enc_key.length = longterm_key->length;
-    seq_enc_key.contents = malloc(seq_enc_key.length);
-    if (seq_enc_key.contents == NULL) {
-        free ((void *) usage_key.contents);
-        return (ENOMEM);
-    }
     code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
     if (code)
-        goto cleanup_arcfour;
-
-    if (exportable) {
-        memcpy(t, kg_arcfour_l40, sizeof(kg_arcfour_l40));
-        i += sizeof(kg_arcfour_l40);
-    }
-    store_32_le(ms_usage, &t[i]);
-    i += 4;
-    input.data = (void *) &t;
-    input.length = i;
-    output.data = (void *) usage_key.contents;
-    output.length = usage_key.length;
-    code = (*kaccess.hmac)(kaccess.md5_hash_provider, longterm_key, 1,
-                           &input, &output);
-    if (code)
-        goto cleanup_arcfour;
-    if (exportable)
-        memset(usage_key.contents + 7, 0xab, 9);
-
-    input.data = ( void *) kd_data;
-    input.length = kd_data_len;
-    output.data = (void *) seq_enc_key.contents;
-    code = (*kaccess.hmac)(kaccess.md5_hash_provider, &usage_key, 1,
-                           &input, &output);
-    if (code)
-        goto cleanup_arcfour;
-
+        return code;
     code = kg_translate_iov(context, 0 /* proto */, 0 /* dce_style */,
-                            0 /* ec */, 0 /* rrc */, longterm_key->enctype,
+                            0 /* ec */, 0 /* rrc */, keyblock->enctype,
                             iov, iov_count, &kiov, &kiov_count);
     if (code)
-        goto cleanup_arcfour;
-
-    code = krb5_k_create_key(context, &seq_enc_key, &key);
-    if (code)
-        goto cleanup_arcfour;
-    code = (*kaccess.arcfour_enc_provider->encrypt_iov)(key, 0, kiov,
-                                                        kiov_count);
-    krb5_k_free_key(context, key);
-cleanup_arcfour:
-    memset (seq_enc_key.contents, 0, seq_enc_key.length);
-    memset (usage_key.contents, 0, usage_key.length);
-    free (usage_key.contents);
-    free (seq_enc_key.contents);
-    if (kiov != NULL)
-        free(kiov);
-    return (code);
+        return code;
+    code = (*kaccess.arcfour_gsscrypt_iov)(keyblock, usage, &kd,
+                                           kiov, kiov_count);
+    free(kiov);
+    return code;
 }
 
 krb5_cryptotype

Modified: trunk/src/lib/krb5/os/accessor.c
===================================================================
--- trunk/src/lib/krb5/os/accessor.c	2009-11-28 15:53:39 UTC (rev 23377)
+++ trunk/src/lib/krb5/os/accessor.c	2009-11-28 23:10:31 UTC (rev 23378)
@@ -52,11 +52,10 @@
 #define S(FIELD, VAL)   internals_temp.FIELD = VAL
             krb5int_access internals_temp;
 #endif
+            S (arcfour_gsscrypt, krb5int_arcfour_gsscrypt),
+            S (arcfour_gsscrypt_iov, krb5int_arcfour_gsscrypt_iov),
             S (free_addrlist, krb5int_free_addrlist),
-            S (hmac, krb5int_hmac_keyblock),
             S (auth_con_get_subkey_enctype, krb5_auth_con_get_subkey_enctype),
-            S (md5_hash_provider, &krb5int_hash_md5),
-            S (arcfour_enc_provider, &krb5int_enc_arcfour),
             S (sendto_udp, &krb5int_sendto),
             S (add_host_to_list, krb5int_add_host_to_list),
 




More information about the cvs-krb5 mailing list