svn rev #22357: trunk/src/lib/crypto/ arcfour/

ghudson@MIT.EDU ghudson at MIT.EDU
Tue May 19 22:05:53 EDT 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=22357
Commit By: ghudson
Log Message:
ticket: 6490

Restore compatibility with KDCs using key usage 8 to encrypt TGS
replies in a subkey, by implementing a fallback in
krb5_arcfour_decrypt.



Changed Files:
U   trunk/src/lib/crypto/arcfour/arcfour.c
U   trunk/src/lib/crypto/t_encrypt.c
Modified: trunk/src/lib/crypto/arcfour/arcfour.c
===================================================================
--- trunk/src/lib/crypto/arcfour/arcfour.c	2009-05-19 23:17:49 UTC (rev 22356)
+++ trunk/src/lib/crypto/arcfour/arcfour.c	2009-05-20 02:05:53 UTC (rev 22357)
@@ -252,41 +252,58 @@
   checksum.length=hashsize;
   checksum.data=input->data;
 
-  /* compute the salt */
   ms_usage=krb5int_arcfour_translate_usage(usage);
-  if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
-    strncpy(salt.data, krb5int_arcfour_l40, salt.length);
-    store_32_le(ms_usage, salt.data+10);
-  } else {
-    salt.length=4;
-    store_32_le(ms_usage, salt.data);
-  }
-  ret=krb5_hmac(hash, key, 1, &salt, &d1);
-  if (ret)
-    goto cleanup;
 
-  memcpy(k2.contents, k1.contents, k2.length);
+  /* We may have to try two ms_usage values; see below. */
+  do {
+      /* compute the salt */
+      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+	  strncpy(salt.data, krb5int_arcfour_l40, salt.length);
+	  store_32_le(ms_usage, salt.data + 10);
+      } else {
+	  salt.length = 4;
+	  store_32_le(ms_usage, salt.data);
+      }
+      ret = krb5_hmac(hash, key, 1, &salt, &d1);
+      if (ret)
+	  goto cleanup;
 
-  if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
-    memset(k1.contents+7, 0xab, 9);
+      memcpy(k2.contents, k1.contents, k2.length);
+
+      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+	  memset(k1.contents + 7, 0xab, 9);
   
-  ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
-  if (ret)
-    goto cleanup;
+      ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+      if (ret)
+	  goto cleanup;
 
-  ret=(*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
-  if (ret)
-    goto cleanup;
+      ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
+      if (ret)
+	  goto cleanup;
 
-  ret=krb5_hmac(hash, &k2, 1, &plaintext, &d1);
-  if (ret)
-    goto cleanup;
+      ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1);
+      if (ret)
+	  goto cleanup;
 
-  if (memcmp(checksum.data, d1.data, hashsize) != 0) {
-    ret=KRB5KRB_AP_ERR_BAD_INTEGRITY;
-    goto cleanup;
-  }
+      if (memcmp(checksum.data, d1.data, hashsize) != 0) {
+	  if (ms_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.
+	       */
+	      ms_usage = 8;
+	      continue;
+	  }
+	  ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+	  goto cleanup;
+      }
 
+      break;
+  } while (1);
+
   memcpy(output->data, plaintext.data+CONFOUNDERLENGTH,
 	 (plaintext.length-CONFOUNDERLENGTH));
   output->length=plaintext.length-CONFOUNDERLENGTH;

Modified: trunk/src/lib/crypto/t_encrypt.c
===================================================================
--- trunk/src/lib/crypto/t_encrypt.c	2009-05-19 23:17:49 UTC (rev 22356)
+++ trunk/src/lib/crypto/t_encrypt.c	2009-05-20 02:05:53 UTC (rev 22357)
@@ -47,14 +47,17 @@
   0
 };
 
-#define test(msg, exp) \
-printf ("%s: . . . ", msg); \
-retval = (exp);\
-if( retval) { \
-  printf( "Failed: %s\n", error_message(retval)); \
-  abort(); \
-} else printf ("OK\n");
-  
+static void
+test(const char *msg, krb5_error_code retval)
+{
+    printf("%s: . . . ", msg);
+    if (retval) {
+	printf("Failed: %s\n", error_message(retval));
+	abort();
+    } else
+	printf("OK\n");
+}
+
 static int compare_results(krb5_data *d1, krb5_data *d2)
 {
     if (d1->length != d2->length) {
@@ -186,6 +189,21 @@
     krb5_free_keyblock (context, key);
   }
 
+  /* Test the RC4 decrypt fallback from key usage 9 to 8. */
+  test ("Initializing an RC4 keyblock",
+	krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &key));
+  test ("Generating random RC4 key",
+	krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, key));
+  enc_out.ciphertext = out;
+  krb5_c_encrypt_length (context, key->enctype, in.length, &len);
+  enc_out.ciphertext.length = len;
+  check.length = 2048;
+  test ("Encrypting with RC4 key usage 8",
+	krb5_c_encrypt (context, key, 8, 0, &in, &enc_out));
+  test ("Decrypting with RC4 key usage 9",
+	krb5_c_decrypt (context, key, 9, 0, &enc_out, &check));
+  test ("Comparing", compare_results (&in, &check));
+
   free(out.data);
   free(out2.data);
   free(check.data);




More information about the cvs-krb5 mailing list