svn rev #23395: trunk/src/lib/crypto/krb/arcfour/

ghudson@MIT.EDU ghudson at MIT.EDU
Mon Nov 30 19:40:54 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=23395
Commit By: ghudson
Log Message:
Fix the usage fallback in krb5int_arcfour_decrypt_iov.  Factor out IOV
encryption with a keyblock since this makes four uses of it in one
file.



Changed Files:
U   trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c
Modified: trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c
===================================================================
--- trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c	2009-11-30 23:09:36 UTC (rev 23394)
+++ trunk/src/lib/crypto/krb/arcfour/arcfour_aead.c	2009-12-01 00:40:54 UTC (rev 23395)
@@ -62,7 +62,24 @@
     return 0;
 }
 
+/* Encrypt or decrypt using a keyblock. */
 static krb5_error_code
+keyblock_crypt(const struct krb5_enc_provider *enc, krb5_keyblock *keyblock,
+               const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data)
+{
+    krb5_error_code ret;
+    krb5_key key;
+
+    ret = krb5_k_create_key(NULL, keyblock, &key);
+    if (ret != 0)
+        return ret;
+    /* Works for encryption or decryption since arcfour is a stream cipher. */
+    ret = enc->encrypt_iov(key, ivec, data, num_data);
+    krb5_k_free_key(NULL, key);
+    return ret;
+}
+
+static krb5_error_code
 krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
                             const struct krb5_enc_provider *enc,
                             const struct krb5_hash_provider *hash,
@@ -75,7 +92,6 @@
     krb5_error_code ret;
     krb5_crypto_iov *header, *trailer;
     krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
-    krb5_key enc_key;
     krb5_data checksum, confounder, header_data;
     size_t i;
 
@@ -144,13 +160,7 @@
     if (ret)
         goto cleanup;
 
-    ret = krb5_k_create_key(NULL, enc_keyblock, &enc_key);
-    if (ret != 0)
-        goto cleanup;
-    ret = enc->encrypt_iov(enc_key, ivec, data, num_data);
-    krb5_k_free_key(NULL, enc_key);
-    if (ret != 0)
-        goto cleanup;
+    ret = keyblock_crypt(enc, enc_keyblock, ivec, data, num_data);
 
 cleanup:
     header->data = header_data; /* Restore header pointers. */
@@ -172,7 +182,6 @@
     krb5_error_code ret;
     krb5_crypto_iov *header, *trailer;
     krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
-    krb5_key enc_key;
     krb5_data checksum, header_data, comp_checksum = empty_data();
 
     header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
@@ -220,13 +229,9 @@
             goto cleanup;
 
         /* Decrypt the ciphertext. */
-        ret = krb5_k_create_key(NULL, enc_keyblock, &enc_key);
+        ret = keyblock_crypt(enc, enc_keyblock, ivec, data, num_data);
         if (ret != 0)
             goto cleanup;
-        ret = enc->decrypt_iov(enc_key, ivec, data, num_data);
-        krb5_k_free_key(NULL, enc_key);
-        if (ret != 0)
-            goto cleanup;
 
         /* Compute HMAC(usage key, plaintext) to get the checksum. */
         ret = krb5int_hmac_iov_keyblock(hash, usage_keyblock, data, num_data,
@@ -237,12 +242,16 @@
         if (memcmp(checksum.data, comp_checksum.data, hash->hashsize) != 0) {
             if (usage == 9) {
                 /*
-                 * RFC 4757 specifies usage 8 for TGS-REP encrypted
-                 * parts encrypted in a subkey, but the value used by MS
-                 * is actually 9.  We now use 9 to start with, but fall
-                 * back to 8 on failure in case we are communicating
-                 * with a KDC using the value from the RFC.
+                 * RFC 4757 specifies usage 8 for TGS-REP encrypted parts
+                 * encrypted in a subkey, but the value used by MS is actually
+                 * 9.  We now use 9 to start with, but fall back to 8 on
+                 * failure in case we are communicating with a KDC using the
+                 * value from the RFC.  ivec is always NULL in this case.
+                 * We need to re-encrypt the data in the wrong key first.
                  */
+                ret = keyblock_crypt(enc, enc_keyblock, NULL, data, num_data);
+                if (ret != 0)
+                    goto cleanup;
                 usage = 8;
                 continue;
             }
@@ -275,7 +284,6 @@
     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,
@@ -300,11 +308,7 @@
         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);
+    ret = keyblock_crypt(enc, enc_keyblock, 0, data, num_data);
 
 cleanup:
     krb5int_c_free_keyblock(NULL, usage_keyblock);




More information about the cvs-krb5 mailing list