diff --git a/src/lib/crypto/crypto_tests/t_cksum.c b/src/lib/crypto/crypto_tests/t_cksum.c
index a544d9e..50e8e7c 100644
--- a/src/lib/crypto/crypto_tests/t_cksum.c
+++ b/src/lib/crypto/crypto_tests/t_cksum.c
@@ -37,11 +37,21 @@
 #if	MD == 4
 extern struct krb5_keyhash_provider krb5int_keyhash_md4des;
 #define khp krb5int_keyhash_md4des
+static unsigned char knowncksum[] = {
+  0xe3, 0xf7, 0x6a, 0x07, 0xf3, 0x40, 0x1e, 0x35,
+  0x36, 0xb4, 0x3a, 0x3f, 0x54, 0x22, 0x6c, 0x39,
+  0x42, 0x2c, 0x35, 0x68, 0x2c, 0x35, 0x48, 0x35
+};
 #endif
 
 #if	MD == 5
 extern struct krb5_keyhash_provider krb5int_keyhash_md5des;
 #define khp krb5int_keyhash_md5des
+static unsigned char knowncksum[] = {
+  0xe3, 0xf7, 0x6a, 0x07, 0xf3, 0x40, 0x1e, 0x35,
+  0x11, 0x43, 0xee, 0x6f, 0x4c, 0x09, 0xbe, 0x1e,
+  0xdb, 0x42, 0x64, 0xd5, 0x50, 0x15, 0xdb, 0x53
+};
 #endif
 
 static void
@@ -77,7 +87,11 @@ main(argc, argv)
   krb5_keyblock		keyblock;
   krb5_key		key;
   krb5_error_code	kret=0;
-  krb5_data		plaintext, newstyle_checksum;
+  krb5_data		plaintext, newstyle_checksum, knowncksum_dat;
+  char *known_plaintext = "this is a test";
+
+  knowncksum_dat.data = (char *)knowncksum;
+  knowncksum_dat.length = sizeof(knowncksum);
 
   /* this is a terrible seed, but that's ok for the test. */
 
@@ -118,6 +132,7 @@ main(argc, argv)
     }
     if (!valid) {
       printf("verify on new checksum failed\n");
+      kret = 1;
       break;
     }
     printf("Verify succeeded for \"%s\"\n", argv[msgindex]);
@@ -130,9 +145,26 @@ main(argc, argv)
     }
     if (valid) {
       printf("verify on new checksum succeeded, but shouldn't have\n");
+      kret = 1;
       break;
     }
     printf("Verify of bad checksum OK for \"%s\"\n", argv[msgindex]);
+    if (strcmp(argv[msgindex], known_plaintext) == 0) {
+      if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &knowncksum_dat,
+				  &valid))) {
+	printf("verify on known checksum choked with %d\n", kret);
+	break;
+      }
+      if (!valid) {
+	printf("verify on known checksum failed\n");
+	kret = 1;
+	break;
+      }
+    } else {
+      printf("WARNING: input plaintext doesn't match plaintext "
+	     "of known hash.\n"
+	     "NOT verifying known checksum.\n");
+    }
     kret = 0;
   }
   free(newstyle_checksum.data);
diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
index ef10a68..89d97f7 100644
--- a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
+++ b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
@@ -38,6 +38,30 @@
 
 extern struct krb5_enc_provider krb5int_enc_des;
 
+/* Derive a key by XOR with 0xF0 bytes. */
+static krb5_error_code
+mk_xorkey(krb5_key origkey, krb5_key *xorkey)
+{
+    krb5_error_code retval = 0;
+    unsigned char xorbytes[8];
+    krb5_keyblock xorkeyblock;
+    size_t i = 0;
+
+    if (origkey->keyblock.length != sizeof(xorbytes))
+	return KRB5_CRYPTO_INTERNAL;
+    memcpy(xorbytes, origkey->keyblock.contents, sizeof(xorbytes));
+    for (i = 0; i < sizeof(xorbytes); i++)
+	xorbytes[i] ^= 0xf0;
+
+    /* Do a shallow copy here. */
+    xorkeyblock = origkey->keyblock;
+    xorkeyblock.contents = xorbytes;
+
+    retval = krb5_k_create_key(0, &xorkeyblock, xorkey);
+    zap(xorbytes, sizeof(xorbytes));
+    return retval;
+}
+
 static krb5_error_code
 k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
@@ -46,6 +70,7 @@ k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     krb5_data data;
     krb5_MD4_CTX ctx;
     unsigned char conf[CONFLENGTH];
+    krb5_key xorkey = NULL;
     struct krb5_enc_provider *enc = &krb5int_enc_des;
 
     if (output->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH))
@@ -58,6 +83,10 @@ k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &data)))
 	return(ret);
 
+    ret = mk_xorkey(key, &xorkey);
+    if (ret)
+	return ret;
+
     /* hash the confounder, then the input data */
 
     krb5int_MD4Init(&ctx);
@@ -71,7 +100,9 @@ k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     memcpy(output->data, conf, CONFLENGTH);
     memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH);
 
-    ret = enc->encrypt(key, NULL, output, output);
+    ret = enc->encrypt(xorkey, NULL, output, output);
+
+    krb5_k_free_key(NULL, xorkey);
 
     return (ret);
 }
@@ -85,10 +116,14 @@ k5_md4des_verify(krb5_key key, krb5_keyusage usage,
     krb5_error_code ret;
     krb5_MD4_CTX ctx;
     unsigned char plaintext[CONFLENGTH+RSA_MD4_CKSUM_LENGTH];
+    krb5_key xorkey = NULL;
     int compathash = 0;
     struct krb5_enc_provider *enc = &krb5int_enc_des;
     krb5_data output, iv;
 
+    iv.data = NULL;
+    iv.length = 0;
+
     if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
     if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) {
@@ -109,20 +144,23 @@ k5_md4des_verify(krb5_key key, krb5_keyusage usage,
         iv.length = key->keyblock.length;
         if (key->keyblock.contents)
             memcpy(iv.data, key->keyblock.contents, key->keyblock.length);
+    } else {
+	ret = mk_xorkey(key, &xorkey);
+	if (ret)
+	  return ret;
     }
 
     /* decrypt it */
-    output.data = plaintext;
+    output.data = (char *)plaintext;
     output.length = hash->length;
 
     if (!compathash) {
-        ret = enc->decrypt(key, NULL, hash, &output);
+        ret = enc->decrypt(xorkey, NULL, hash, &output);
+	krb5_k_free_key(NULL, xorkey);
     } else {
         ret = enc->decrypt(key, &iv, hash, &output);
-    }
-
-    if (compathash && iv.data) {
-        free (iv.data);
+	zap(iv.data, iv.length);
+        free(iv.data);
     }
 
     if (ret) return(ret);
diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
index eb189c2..4a3d623 100644
--- a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
+++ b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
@@ -38,6 +38,30 @@
 
 extern struct krb5_enc_provider krb5int_enc_des;
 
+/* Derive a key by XOR with 0xF0 bytes. */
+static krb5_error_code
+mk_xorkey(krb5_key origkey, krb5_key *xorkey)
+{
+    krb5_error_code retval = 0;
+    unsigned char xorbytes[8];
+    krb5_keyblock xorkeyblock;
+    size_t i = 0;
+
+    if (origkey->keyblock.length != sizeof(xorbytes))
+	return KRB5_CRYPTO_INTERNAL;
+    memcpy(xorbytes, origkey->keyblock.contents, sizeof(xorbytes));
+    for (i = 0; i < sizeof(xorbytes); i++)
+	xorbytes[i] ^= 0xf0;
+
+    /* Do a shallow copy here. */
+    xorkeyblock = origkey->keyblock;
+    xorkeyblock.contents = xorbytes;
+
+    retval = krb5_k_create_key(0, &xorkeyblock, xorkey);
+    zap(xorbytes, sizeof(xorbytes));
+    return retval;
+}
+
 static krb5_error_code
 k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
@@ -46,6 +70,7 @@ k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     krb5_data data;
     krb5_MD5_CTX ctx;
     unsigned char conf[CONFLENGTH];
+    krb5_key xorkey = NULL;
     struct krb5_enc_provider *enc = &krb5int_enc_des;
 
     if (output->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH))
@@ -58,6 +83,10 @@ k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &data)))
 	return(ret);
 
+    ret = mk_xorkey(key, &xorkey);
+    if (ret)
+	return ret;
+
     /* hash the confounder, then the input data */
 
     krb5int_MD5Init(&ctx);
@@ -71,7 +100,9 @@ k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     memcpy(output->data, conf, CONFLENGTH);
     memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH);
 
-    ret = enc->encrypt(key, NULL, output, output);
+    ret = enc->encrypt(xorkey, NULL, output, output);
+
+    krb5_k_free_key(NULL, xorkey);
 
     return ret;
 
@@ -85,10 +116,14 @@ k5_md5des_verify(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
     krb5_error_code ret;
     krb5_MD5_CTX ctx;
     unsigned char plaintext[CONFLENGTH+RSA_MD5_CKSUM_LENGTH];
+    krb5_key xorkey = NULL;
     int compathash = 0;
     struct krb5_enc_provider *enc = &krb5int_enc_des;
     krb5_data output, iv;
 
+    iv.data = NULL;
+    iv.length = 0;
+
     if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
 
@@ -109,20 +144,23 @@ k5_md5des_verify(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
         iv.length = key->keyblock.length;
         if (key->keyblock.contents)
             memcpy(iv.data, key->keyblock.contents, key->keyblock.length);
+    } else {
+	ret = mk_xorkey(key, &xorkey);
+	if (ret)
+	  return ret;
     }
 
     /* decrypt it */
-    output.data = plaintext;
+    output.data = (char *)plaintext;
     output.length = hash->length;
 
     if (!compathash) {
-        ret = enc->decrypt(key, NULL, hash, &output);
+        ret = enc->decrypt(xorkey, NULL, hash, &output);
+	krb5_k_free_key(NULL, xorkey);
     } else {
         ret = enc->decrypt(key, &iv, hash, &output);
-    }
-
-    if (compathash && iv.data) {
-        free (iv.data);
+	zap(iv.data, iv.length);
+        free(iv.data);
     }
 
     if (ret) return(ret);
