svn rev #22944: trunk/src/ include/ include/krb5/ lib/crypto/ lib/crypto/builtin/ ...

ghudson@MIT.EDU ghudson at MIT.EDU
Mon Oct 19 16:04:23 EDT 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=22944
Commit By: ghudson
Log Message:
ticket: 6576
subject: Implement new APIs to allow improved crypto performance

Merge branches/enc-perf to trunk.  Adds the krb5_key opaque type, the
krb5_k_* APIs to use them, and caching of derived keys when krb5_k_*
functions are used.  Updates the krb5 auth context and GSS id-rec to
use krb5_keys.



Changed Files:
U   trunk/src/include/k5-int.h
U   trunk/src/include/krb5/krb5.hin
U   trunk/src/lib/crypto/builtin/aes/aes_s2k.c
U   trunk/src/lib/crypto/builtin/arcfour/arcfour.c
U   trunk/src/lib/crypto/builtin/arcfour/arcfour.h
U   trunk/src/lib/crypto/builtin/arcfour/arcfour_aead.c
U   trunk/src/lib/crypto/builtin/enc_provider/aes.c
U   trunk/src/lib/crypto/builtin/enc_provider/des.c
U   trunk/src/lib/crypto/builtin/enc_provider/des3.c
U   trunk/src/lib/crypto/builtin/enc_provider/rc4.c
U   trunk/src/lib/crypto/builtin/hmac.c
U   trunk/src/lib/crypto/builtin/pbkdf2.c
U   trunk/src/lib/crypto/crypto_tests/Makefile.in
U   trunk/src/lib/crypto/crypto_tests/aes-test.c
U   trunk/src/lib/crypto/crypto_tests/t_cksum.c
U   trunk/src/lib/crypto/crypto_tests/t_cts.c
U   trunk/src/lib/crypto/crypto_tests/t_encrypt.c
U   trunk/src/lib/crypto/crypto_tests/t_hmac.c
A   trunk/src/lib/crypto/crypto_tests/t_kperf.c
U   trunk/src/lib/crypto/krb/Makefile.in
U   trunk/src/lib/crypto/krb/aead.c
U   trunk/src/lib/crypto/krb/aead.h
U   trunk/src/lib/crypto/krb/combine_keys.c
U   trunk/src/lib/crypto/krb/decrypt.c
U   trunk/src/lib/crypto/krb/decrypt_iov.c
U   trunk/src/lib/crypto/krb/dk/checksum.c
U   trunk/src/lib/crypto/krb/dk/derive.c
U   trunk/src/lib/crypto/krb/dk/dk.h
U   trunk/src/lib/crypto/krb/dk/dk_aead.c
U   trunk/src/lib/crypto/krb/dk/dk_decrypt.c
U   trunk/src/lib/crypto/krb/dk/dk_encrypt.c
U   trunk/src/lib/crypto/krb/dk/stringtokey.c
U   trunk/src/lib/crypto/krb/encrypt.c
U   trunk/src/lib/crypto/krb/encrypt_iov.c
U   trunk/src/lib/crypto/krb/etypes.h
A   trunk/src/lib/crypto/krb/key.c
U   trunk/src/lib/crypto/krb/keyblocks.c
U   trunk/src/lib/crypto/krb/keyhash_provider/descbc.c
U   trunk/src/lib/crypto/krb/keyhash_provider/hmac_md5.c
U   trunk/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
U   trunk/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
U   trunk/src/lib/crypto/krb/keyhash_provider/md5_hmac.c
U   trunk/src/lib/crypto/krb/make_checksum.c
U   trunk/src/lib/crypto/krb/make_checksum_iov.c
U   trunk/src/lib/crypto/krb/old/old.h
U   trunk/src/lib/crypto/krb/old/old_decrypt.c
U   trunk/src/lib/crypto/krb/old/old_encrypt.c
U   trunk/src/lib/crypto/krb/prf/des_prf.c
U   trunk/src/lib/crypto/krb/prf/dk_prf.c
U   trunk/src/lib/crypto/krb/prf/prf_int.h
U   trunk/src/lib/crypto/krb/prf/rc4_prf.c
U   trunk/src/lib/crypto/krb/prf.c
U   trunk/src/lib/crypto/krb/raw/raw.h
U   trunk/src/lib/crypto/krb/raw/raw_aead.c
U   trunk/src/lib/crypto/krb/raw/raw_decrypt.c
U   trunk/src/lib/crypto/krb/raw/raw_encrypt.c
U   trunk/src/lib/crypto/krb/verify_checksum.c
U   trunk/src/lib/crypto/krb/verify_checksum_iov.c
U   trunk/src/lib/crypto/krb/yarrow/ycipher.c
U   trunk/src/lib/crypto/krb/yarrow/ycipher.h
U   trunk/src/lib/crypto/libk5crypto.exports
U   trunk/src/lib/crypto/openssl/aes/aes_s2k.c
U   trunk/src/lib/crypto/openssl/arcfour/arcfour.c
U   trunk/src/lib/crypto/openssl/arcfour/arcfour.h
U   trunk/src/lib/crypto/openssl/arcfour/arcfour_aead.c
U   trunk/src/lib/crypto/openssl/enc_provider/aes.c
U   trunk/src/lib/crypto/openssl/enc_provider/des.c
U   trunk/src/lib/crypto/openssl/enc_provider/des3.c
U   trunk/src/lib/crypto/openssl/enc_provider/rc4.c
U   trunk/src/lib/crypto/openssl/hmac.c
U   trunk/src/lib/gssapi/krb5/accept_sec_context.c
U   trunk/src/lib/gssapi/krb5/delete_sec_context.c
U   trunk/src/lib/gssapi/krb5/gssapiP_krb5.h
U   trunk/src/lib/gssapi/krb5/init_sec_context.c
U   trunk/src/lib/gssapi/krb5/inq_context.c
U   trunk/src/lib/gssapi/krb5/k5seal.c
U   trunk/src/lib/gssapi/krb5/k5sealiov.c
U   trunk/src/lib/gssapi/krb5/k5sealv3.c
U   trunk/src/lib/gssapi/krb5/k5sealv3iov.c
U   trunk/src/lib/gssapi/krb5/k5unseal.c
U   trunk/src/lib/gssapi/krb5/k5unsealiov.c
U   trunk/src/lib/gssapi/krb5/lucid_context.c
U   trunk/src/lib/gssapi/krb5/ser_sctx.c
U   trunk/src/lib/gssapi/krb5/util_cksum.c
U   trunk/src/lib/gssapi/krb5/util_crypt.c
U   trunk/src/lib/gssapi/krb5/util_seed.c
U   trunk/src/lib/gssapi/krb5/util_seqnum.c
U   trunk/src/lib/gssapi/krb5/wrap_size_limit.c
U   trunk/src/lib/krb5/krb/auth_con.c
U   trunk/src/lib/krb5/krb/auth_con.h
U   trunk/src/lib/krb5/krb/copy_key.c
U   trunk/src/lib/krb5/krb/cp_key_cnt.c
U   trunk/src/lib/krb5/krb/enc_helper.c
U   trunk/src/lib/krb5/krb/mk_cred.c
U   trunk/src/lib/krb5/krb/mk_priv.c
U   trunk/src/lib/krb5/krb/mk_rep.c
U   trunk/src/lib/krb5/krb/mk_req_ext.c
U   trunk/src/lib/krb5/krb/mk_safe.c
U   trunk/src/lib/krb5/krb/rd_cred.c
U   trunk/src/lib/krb5/krb/rd_priv.c
U   trunk/src/lib/krb5/krb/rd_rep.c
U   trunk/src/lib/krb5/krb/rd_req_dec.c
U   trunk/src/lib/krb5/krb/rd_safe.c
U   trunk/src/lib/krb5/krb/ser_actx.c
U   trunk/src/lib/krb5/os/accessor.c
Modified: trunk/src/include/k5-int.h
===================================================================
--- trunk/src/include/k5-int.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/include/k5-int.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -635,6 +635,19 @@
 		       struct addrlist *, enum locate_service_type svc,
 		       int sockettype, int family);
 
+struct derived_key {
+    krb5_data constant;
+    krb5_key dkey;
+    struct derived_key *next;
+};
+
+/* Internal structure of an opaque key identifier */
+struct krb5_key_st {
+    krb5_keyblock keyblock;
+    int refcount;
+    struct derived_key *derived;
+};
+
 /* new encryption provider api */
 
 struct krb5_enc_provider {
@@ -643,12 +656,12 @@
     size_t block_size, keybytes, keylength;
 
     /* cipher-state == 0 fresh state thrown away at end */
-    krb5_error_code (*encrypt) (const krb5_keyblock *key,
+    krb5_error_code (*encrypt) (krb5_key key,
 				const krb5_data *cipher_state,
 				const krb5_data *input,
 				krb5_data *output);
 
-    krb5_error_code (*decrypt) (const krb5_keyblock *key,
+    krb5_error_code (*decrypt) (krb5_key key,
 				const krb5_data *ivec,
 				const krb5_data *input,
 				krb5_data *output);
@@ -661,13 +674,13 @@
   krb5_error_code (*free_state) (krb5_data *state);
 
     /* In-place encryption/decryption of multiple buffers */
-    krb5_error_code (*encrypt_iov) (const krb5_keyblock *key,
+    krb5_error_code (*encrypt_iov) (krb5_key key,
 				    const krb5_data *cipher_state,
 				    krb5_crypto_iov *data,
 				    size_t num_data);
 
 
-    krb5_error_code (*decrypt_iov) (const krb5_keyblock *key,
+    krb5_error_code (*decrypt_iov) (krb5_key key,
 				    const krb5_data *cipher_state,
 				    krb5_crypto_iov *data,
 				    size_t num_data);
@@ -686,27 +699,27 @@
 struct krb5_keyhash_provider {
     size_t hashsize;
 
-    krb5_error_code (*hash) (const krb5_keyblock *key,
+    krb5_error_code (*hash) (krb5_key key,
 			     krb5_keyusage keyusage,
 			     const krb5_data *ivec,
 			     const krb5_data *input,
 			     krb5_data *output);
 
-    krb5_error_code (*verify) (const krb5_keyblock *key,
+    krb5_error_code (*verify) (krb5_key key,
 			       krb5_keyusage keyusage,
 			       const krb5_data *ivec,
 			       const krb5_data *input,
 			       const krb5_data *hash,
 			       krb5_boolean *valid);
 
-    krb5_error_code (*hash_iov) (const krb5_keyblock *key,
+    krb5_error_code (*hash_iov) (krb5_key key,
 				 krb5_keyusage keyusage,
 				 const krb5_data *ivec,
 				 const krb5_crypto_iov *data,
 				 size_t num_data,
 				 krb5_data *output);
 
-    krb5_error_code (*verify_iov) (const krb5_keyblock *key,
+    krb5_error_code (*verify_iov) (krb5_key key,
 				  krb5_keyusage keyusage,
 				  const krb5_data *ivec,
 				  const krb5_crypto_iov *data,
@@ -724,7 +737,7 @@
     krb5_error_code (*encrypt_iov) (const struct krb5_aead_provider *aead,
 				    const struct krb5_enc_provider *enc,
 				    const struct krb5_hash_provider *hash,
-				    const krb5_keyblock *key,
+				    krb5_key key,
 				    krb5_keyusage keyusage,
 				    const krb5_data *ivec,
 				    krb5_crypto_iov *data,
@@ -732,7 +745,7 @@
     krb5_error_code (*decrypt_iov) (const struct krb5_aead_provider *aead,
 				    const struct krb5_enc_provider *enc,
 				    const struct krb5_hash_provider *hash,
-				    const krb5_keyblock *key,
+				    krb5_key key,
 				    krb5_keyusage keyusage,
 				    const krb5_data *ivec,
 				    krb5_crypto_iov *data,
@@ -749,11 +762,22 @@
 
 krb5_error_code krb5_hmac
 (const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, unsigned int icount,
+		krb5_key key, unsigned int icount,
 		const krb5_data *input, krb5_data *output);
 
 krb5_error_code krb5int_hmac_iov
 (const struct krb5_hash_provider *hash,
+		krb5_key key,
+		const krb5_crypto_iov *data, size_t num_data,
+		krb5_data *output);
+
+krb5_error_code krb5int_hmac_keyblock
+(const struct krb5_hash_provider *hash,
+		const krb5_keyblock *key, unsigned int icount,
+		const krb5_data *input, krb5_data *output);
+
+krb5_error_code krb5int_hmac_iov_keyblock
+(const struct krb5_hash_provider *hash,
 		const krb5_keyblock *key,
 		const krb5_crypto_iov *data, size_t num_data,
 		krb5_data *output);
@@ -808,13 +832,18 @@
 (krb5_context context, krb5_keyblock *key1, krb5_keyblock *key2,
 		krb5_keyblock *outkey);
 
+
 void  krb5int_c_free_keyblock
 (krb5_context, krb5_keyblock *key);
 void  krb5int_c_free_keyblock_contents
 	(krb5_context, krb5_keyblock *);
-krb5_error_code   krb5int_c_init_keyblock
+krb5_error_code krb5int_c_init_keyblock
 		(krb5_context, krb5_enctype enctype,
 		size_t length, krb5_keyblock **out); 
+krb5_error_code krb5int_c_copy_keyblock
+(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to);
+krb5_error_code krb5int_c_copy_keyblock_contents
+(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to);
 
 /*
  * Internal - for cleanup.
@@ -850,6 +879,11 @@
 		krb5_keyusage keyusage, const krb5_data *plain,
 		krb5_enc_data *cipher);
 
+krb5_error_code krb5_encrypt_keyhelper
+(krb5_context context, krb5_key key,
+		krb5_keyusage keyusage, const krb5_data *plain,
+		krb5_enc_data *cipher);
+
 /*
  * End "los-proto.h"
  */
@@ -2566,10 +2600,10 @@
 		krb5_data *enc_data);
 
 krb5_error_code
-krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output);
 krb5_error_code
-krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output);
 
 struct _krb5_kt {	/* should move into k5-int.h */

Modified: trunk/src/include/krb5/krb5.hin
===================================================================
--- trunk/src/include/krb5/krb5.hin	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/include/krb5/krb5.hin	2009-10-19 20:04:21 UTC (rev 22944)
@@ -341,6 +341,7 @@
  * begin "encryption.h"
  */
 
+/* Exposed contents of a key. */
 typedef struct _krb5_keyblock {
     krb5_magic magic;
     krb5_enctype enctype;
@@ -348,6 +349,16 @@
     krb5_octet *contents;
 } krb5_keyblock;
 
+/*
+ * Opaque identifier for a key.  Use with the krb5_k APIs for better
+ * performance for repeated operations with the same key usage.  Key
+ * identifiers must not be used simultaneously within multiple
+ * threads, as they may contain mutable internal state and are not
+ * mutex-protected.
+ */
+struct krb5_key_st;
+typedef struct krb5_key_st *krb5_key;
+
 #ifdef KRB5_OLD_CRYPTO
 typedef struct _krb5_encrypt_block {
     krb5_magic magic;
@@ -705,6 +716,64 @@
     (krb5_context context, krb5_enctype enctype,
 		    size_t data_length, unsigned int *size);
 
+krb5_error_code KRB5_CALLCONV
+krb5_k_create_key(krb5_context context, const krb5_keyblock *key_data,
+		  krb5_key *out);
+
+/* Keys are logically immutable and can be "copied" by reference count. */
+void KRB5_CALLCONV krb5_k_reference_key(krb5_context context, krb5_key key);
+
+/* Decrement the reference count on a key and free it if it hits zero. */
+void KRB5_CALLCONV krb5_k_free_key(krb5_context context, krb5_key key);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_key_keyblock(krb5_context context, krb5_key key,
+		    krb5_keyblock **key_data);
+
+krb5_enctype KRB5_CALLCONV
+krb5_k_key_enctype(krb5_context context, krb5_key key);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage,
+	       const krb5_data *cipher_state, const krb5_data *input,
+	       krb5_enc_data *output);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_encrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage,
+		   const krb5_data *cipher_state, krb5_crypto_iov *data,
+		   size_t num_data);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage,
+	       const krb5_data *cipher_state, const krb5_enc_data *input,
+	       krb5_data *output);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_decrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage,
+		   const krb5_data *cipher_state, krb5_crypto_iov *data,
+		   size_t num_data);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
+		     krb5_key key, krb5_keyusage usage, const krb5_data *input,
+		     krb5_checksum *cksum);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype,
+			 krb5_key key, krb5_keyusage usage,
+			 krb5_crypto_iov *data, size_t num_data);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage,
+		       const krb5_data *data, const krb5_checksum *cksum,
+		       krb5_boolean *valid);
+
+krb5_error_code KRB5_CALLCONV
+krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype,
+			   krb5_key key, krb5_keyusage usage,
+			   const krb5_crypto_iov *data, size_t num_data,
+			   krb5_boolean *valid);
+
 #ifdef KRB5_OLD_CRYPTO
 /*
  * old cryptosystem routine prototypes.  These are now layered

Modified: trunk/src/lib/crypto/builtin/aes/aes_s2k.c
===================================================================
--- trunk/src/lib/crypto/builtin/aes/aes_s2k.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/aes/aes_s2k.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -44,6 +44,7 @@
     unsigned long iter_count;
     krb5_data out;
     static const krb5_data usage = { KV5M_DATA, 8, "kerberos" };
+    krb5_key tempkey = NULL;
     krb5_error_code err;
 
     if (params) {
@@ -66,25 +67,25 @@
     if (iter_count >= MAX_ITERATION_COUNT)
 	return KRB5_ERR_BAD_S2K_PARAMS;
 
-    /*
-     * Dense key space, no parity bits or anything, so take a shortcut
-     * and use the key contents buffer for the generated bytes.
-     */
+    /* Use the output keyblock contents for temporary space. */
     out.data = (char *) key->contents;
     out.length = key->length;
     if (out.length != 16 && out.length != 32)
 	return KRB5_CRYPTO_INTERNAL;
 
     err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt);
-    if (err) {
-	memset(out.data, 0, out.length);
-	return err;
-    }
+    if (err)
+	goto cleanup;
 
-    err = krb5_derive_key (enc, key, key, &usage);
-    if (err) {
-	memset(out.data, 0, out.length);
-	return err;
-    }
-    return 0;
+    err = krb5_k_create_key (NULL, key, &tempkey);
+    if (err)
+	goto cleanup;
+
+    err = krb5_derive_keyblock (enc, tempkey, key, &usage);
+
+cleanup:
+    if (err)
+	memset (out.data, 0, out.length);
+    krb5_k_free_key (NULL, tempkey);
+    return err;
 }

Modified: trunk/src/lib/crypto/builtin/arcfour/arcfour.c
===================================================================
--- trunk/src/lib/crypto/builtin/arcfour/arcfour.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/arcfour/arcfour.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -64,11 +64,12 @@
 krb5_error_code
 krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
 		     const struct krb5_hash_provider *hash,
-		     const krb5_keyblock *key, krb5_keyusage usage,
+		     krb5_key key, krb5_keyusage usage,
 		     const krb5_data *ivec, const krb5_data *input,
 		     krb5_data *output)
 {
   krb5_keyblock k1, k2, k3;
+  krb5_key k3key = NULL;
   krb5_data d1, d2, d3, salt, plaintext, checksum, ciphertext, confounder;
   krb5_keyusage ms_usage;
   size_t keylength, keybytes, blocksize, hashsize;
@@ -83,7 +84,7 @@
   d1.data=malloc(d1.length);
   if (d1.data == NULL)
     return (ENOMEM);
-  k1 = *key;
+  k1 = key->keyblock;
   k1.length=d1.length;
   k1.contents= (void *) d1.data;
 
@@ -93,7 +94,7 @@
     free(d1.data);
     return (ENOMEM);
   }
-  k2 = *key;
+  k2 = key->keyblock;
   k2.length=d2.length;
   k2.contents=(void *) d2.data;
 
@@ -104,7 +105,7 @@
     free(d2.data);
     return (ENOMEM);
   }
-  k3 = *key;
+  k3 = key->keyblock;
   k3.length=d3.length;
   k3.contents= (void *) d3.data;
 
@@ -140,7 +141,7 @@
 
   /* begin the encryption, computer K1 */
   ms_usage=krb5int_arcfour_translate_usage(usage);
-  if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+  if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
     strncpy(salt.data, krb5int_arcfour_l40, salt.length);
     store_32_le(ms_usage, salt.data+10);
   } else {
@@ -151,7 +152,7 @@
 
   memcpy(k2.contents, k1.contents, k2.length);
 
-  if (key->enctype==ENCTYPE_ARCFOUR_HMAC_EXP)
+  if (key->keyblock.enctype==ENCTYPE_ARCFOUR_HMAC_EXP)
     memset(k1.contents+7, 0xab, 9);
 
   ret=krb5_c_random_make_octets(/* XXX */ 0, &confounder);
@@ -159,12 +160,20 @@
   if (ret)
     goto cleanup;
 
-  krb5_hmac(hash, &k2, 1, &plaintext, &checksum);
+  ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum);
+  if (ret)
+    goto cleanup;
 
-  krb5_hmac(hash, &k1, 1, &checksum, &d3);
+  ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
+  if (ret)
+    goto cleanup;
 
-  ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext);
+  ret = krb5_k_create_key(NULL, &k3, &k3key);
+  if (ret)
+    goto cleanup;
 
+  ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext);
+
  cleanup:
   memset(d1.data, 0, d1.length);
   memset(d2.data, 0, d2.length);
@@ -184,11 +193,12 @@
 krb5_error_code
 krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
 		     const struct krb5_hash_provider *hash,
-		     const krb5_keyblock *key, krb5_keyusage usage,
+		     krb5_key key, krb5_keyusage usage,
 		     const krb5_data *ivec, const krb5_data *input,
 		     krb5_data *output)
 {
   krb5_keyblock k1,k2,k3;
+  krb5_key k3key;
   krb5_data d1,d2,d3,salt,ciphertext,plaintext,checksum;
   krb5_keyusage ms_usage;
   size_t keybytes, keylength, hashsize, blocksize;
@@ -203,7 +213,7 @@
   d1.data=malloc(d1.length);
   if (d1.data == NULL)
     return (ENOMEM);
-  k1 = *key;
+  k1 = key->keyblock;
   k1.length=d1.length;
   k1.contents= (void *) d1.data;
 
@@ -213,7 +223,7 @@
     free(d1.data);
     return (ENOMEM);
   }
-  k2 = *key;
+  k2 = key->keyblock;
   k2.length=d2.length;
   k2.contents= (void *) d2.data;
 
@@ -224,7 +234,7 @@
     free(d2.data);
     return (ENOMEM);
   }
-  k3 = *key;
+  k3 = key->keyblock;
   k3.length=d3.length;
   k3.contents= (void *) d3.data;
 
@@ -257,7 +267,7 @@
   /* We may have to try two ms_usage values; see below. */
   do {
       /* compute the salt */
-      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+      if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
 	  strncpy(salt.data, krb5int_arcfour_l40, salt.length);
 	  store_32_le(ms_usage, salt.data + 10);
       } else {
@@ -270,18 +280,22 @@
 
       memcpy(k2.contents, k1.contents, k2.length);
 
-      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+      if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
 	  memset(k1.contents + 7, 0xab, 9);
 
-      ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+      ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
       if (ret)
 	  goto cleanup;
 
-      ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
+      ret = krb5_k_create_key(NULL, &k3, &k3key);
       if (ret)
+	goto cleanup;
+      ret = (*(enc->decrypt))(k3key, ivec, &ciphertext, &plaintext);
+      krb5_k_free_key(NULL, k3key);
+      if (ret)
 	  goto cleanup;
 
-      ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1);
+      ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &d1);
       if (ret)
 	  goto cleanup;
 

Modified: trunk/src/lib/crypto/builtin/arcfour/arcfour.h
===================================================================
--- trunk/src/lib/crypto/builtin/arcfour/arcfour.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/arcfour/arcfour.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -10,7 +10,7 @@
 extern 
 krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *,
 			const struct krb5_hash_provider *,
-			const krb5_keyblock *,
+			krb5_key,
 			krb5_keyusage,
 			const krb5_data *,
      			const krb5_data *,
@@ -19,7 +19,7 @@
 extern 
 krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *,
 			const struct krb5_hash_provider *,
-			const krb5_keyblock *,
+			krb5_key,
 			krb5_keyusage,
 			const krb5_data *,
 			const krb5_data *,

Modified: trunk/src/lib/crypto/builtin/arcfour/arcfour_aead.c
===================================================================
--- trunk/src/lib/crypto/builtin/arcfour/arcfour_aead.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/arcfour/arcfour_aead.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -82,7 +82,7 @@
 krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
 			    const struct krb5_enc_provider *enc,
 			    const struct krb5_hash_provider *hash,
-			    const krb5_keyblock *key,
+			    krb5_key key,
 			    krb5_keyusage usage,
 			    const krb5_data *ivec,
 			    krb5_crypto_iov *data,
@@ -91,6 +91,7 @@
     krb5_error_code ret;
     krb5_crypto_iov *header, *trailer;
     krb5_keyblock k1, k2, k3;
+    krb5_key k3key = NULL;
     krb5_data d1, d2, d3;
     krb5_data checksum, confounder, header_data;
     krb5_keyusage ms_usage;
@@ -126,15 +127,15 @@
 	    data[i].data.length = 0;
     }
 
-    ret = alloc_derived_key(enc, &k1, &d1, key);
+    ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k2, &d2, key);
+    ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k3, &d3, key);
+    ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
@@ -144,7 +145,7 @@
 
     ms_usage = krb5int_arcfour_translate_usage(usage);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
 	strncpy(salt.data, krb5int_arcfour_l40, salt.length);
 	store_32_le(ms_usage, salt.data + 10);
     } else {
@@ -157,7 +158,7 @@
 
     memcpy(k2.contents, k1.contents, k2.length);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
 	memset(k1.contents + 7, 0xAB, 9);
 
     header->data.length = hash->hashsize + CONFOUNDERLENGTH;
@@ -176,18 +177,22 @@
     header->data.length -= hash->hashsize;
     header->data.data   += hash->hashsize;
 
-    ret = krb5int_hmac_iov(hash, &k2, data, num_data, &checksum);
+    ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &checksum);
     if (ret != 0)
 	goto cleanup;
 
-    ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+    ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
     if (ret != 0)
 	goto cleanup;
 
-    ret = enc->encrypt_iov(&k3, ivec, data, num_data);
+    ret = krb5_k_create_key(NULL, &k3, &k3key);
     if (ret != 0)
 	goto cleanup;
 
+    ret = enc->encrypt_iov(k3key, ivec, data, num_data);
+    if (ret != 0)
+	goto cleanup;
+
 cleanup:
     header->data = header_data; /* restore header pointers */
 
@@ -204,6 +209,7 @@
 	free(d3.data);
     }
 
+    krb5_k_free_key(NULL, k3key);
     return ret;
 }
 
@@ -211,7 +217,7 @@
 krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
 			    const struct krb5_enc_provider *enc,
 			    const struct krb5_hash_provider *hash,
-			    const krb5_keyblock *key,
+			    krb5_key key,
 			    krb5_keyusage usage,
 			    const krb5_data *ivec,
 			    krb5_crypto_iov *data,
@@ -220,6 +226,7 @@
     krb5_error_code ret;
     krb5_crypto_iov *header, *trailer;
     krb5_keyblock k1, k2, k3;
+    krb5_key k3key = NULL;
     krb5_data d1, d2, d3;
     krb5_data checksum, header_data;
     krb5_keyusage ms_usage;
@@ -240,15 +247,15 @@
     if (trailer != NULL && trailer->data.length != 0)
 	return KRB5_BAD_MSIZE;
     
-    ret = alloc_derived_key(enc, &k1, &d1, key);
+    ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k2, &d2, key);
+    ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k3, &d3, key);
+    ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
@@ -258,7 +265,7 @@
 
     ms_usage = krb5int_arcfour_translate_usage(usage);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
 	strncpy(salt.data, krb5int_arcfour_l40, salt.length);
 	store_32_le(ms_usage, (unsigned char *)salt.data + 10);
     } else {
@@ -271,7 +278,7 @@
 
     memcpy(k2.contents, k1.contents, k2.length);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
 	memset(k1.contents + 7, 0xAB, 9);
 
     checksum.data = header->data.data;
@@ -281,18 +288,22 @@
     header->data.length -= hash->hashsize;
     header->data.data   += hash->hashsize;
 
-    ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+    ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
     if (ret != 0)
 	goto cleanup;
 
-    ret = enc->decrypt_iov(&k3, ivec, data, num_data);
+    ret = krb5_k_create_key(NULL, &k3, &k3key);
     if (ret != 0)
 	goto cleanup;
 
-    ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1);
+    ret = enc->decrypt_iov(k3key, ivec, data, num_data);
     if (ret != 0)
 	goto cleanup;
 
+    ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1);
+    if (ret != 0)
+	goto cleanup;
+
     if (memcmp(checksum.data, d1.data, hash->hashsize) != 0) {
 	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
 	goto cleanup;
@@ -314,6 +325,7 @@
 	free(d3.data);
     }
 
+    krb5_k_free_key(NULL, k3key);
     return ret;
 }
 

Modified: trunk/src/lib/crypto/builtin/enc_provider/aes.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/aes.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/enc_provider/aes.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -86,7 +86,7 @@
 }
 
 krb5_error_code
-krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     aes_ctx ctx;
@@ -95,7 +95,8 @@
 
 /*    CHECK_SIZES; */
 
-    if (aes_enc_key(key->contents, key->length, &ctx) != aes_good)
+    if (aes_enc_key(key->keyblock.contents, key->keyblock.length,
+		    &ctx) != aes_good)
 	abort();
 
     if (ivec)
@@ -140,7 +141,7 @@
 }
 
 krb5_error_code
-krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     aes_ctx ctx;
@@ -149,7 +150,8 @@
 
     CHECK_SIZES;
 
-    if (aes_dec_key(key->contents, key->length, &ctx) != aes_good)
+    if (aes_dec_key(key->keyblock.contents, key->keyblock.length,
+		    &ctx) != aes_good)
 	abort();
 
     if (ivec)
@@ -200,7 +202,7 @@
 }
 
 static krb5_error_code
-krb5int_aes_encrypt_iov(const krb5_keyblock *key,
+krb5int_aes_encrypt_iov(krb5_key key,
 		        const krb5_data *ivec,
 		        krb5_crypto_iov *data,
 		        size_t num_data)
@@ -210,7 +212,8 @@
     int nblocks = 0, blockno;
     size_t input_length, i;
 
-    if (aes_enc_key(key->contents, key->length, &ctx) != aes_good)
+    if (aes_enc_key(key->keyblock.contents, key->keyblock.length, &ctx)
+	!= aes_good)
 	abort();
 
     if (ivec != NULL)
@@ -280,7 +283,7 @@
 }
 
 static krb5_error_code
-krb5int_aes_decrypt_iov(const krb5_keyblock *key,
+krb5int_aes_decrypt_iov(krb5_key key,
 		        const krb5_data *ivec,
 		        krb5_crypto_iov *data,
 		        size_t num_data)
@@ -293,7 +296,8 @@
 
     CHECK_SIZES;
 
-    if (aes_dec_key(key->contents, key->length, &ctx) != aes_good)
+    if (aes_dec_key(key->keyblock.contents, key->keyblock.length,
+		    &ctx) != aes_good)
 	abort();
 
     if (ivec != NULL)

Modified: trunk/src/lib/crypto/builtin/enc_provider/des.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/des.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/enc_provider/des.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,14 +32,14 @@
 
 
 static krb5_error_code
-k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des_docrypt(krb5_key key, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output, int enc)
 {
     mit_des_key_schedule schedule;
 
-    /* key->enctype was checked by the caller */
+    /* key->keyblock.enctype was checked by the caller */
 
-    if (key->length != 8)
+    if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
     if ((input->length%8) != 0)
 	return(KRB5_BAD_MSIZE);
@@ -48,7 +48,7 @@
     if (input->length != output->length)
 	return(KRB5_BAD_MSIZE);
 
-    switch (mit_des_key_sched(key->contents, schedule)) {
+    switch (mit_des_key_sched(key->keyblock.contents, schedule)) {
     case -1:
 	return(KRB5DES_BAD_KEYPAR);
     case -2:
@@ -71,30 +71,30 @@
 }
 
 static krb5_error_code
-k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des_encrypt(krb5_key key, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
 {
     return(k5_des_docrypt(key, ivec, input, output, 1));
 }
 
 static krb5_error_code
-k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des_decrypt(krb5_key key, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
 {
     return(k5_des_docrypt(key, ivec, input, output, 0));
 }
 
 static krb5_error_code
-k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des_docrypt_iov(krb5_key key, const krb5_data *ivec,
 		   krb5_crypto_iov *data, size_t num_data, int enc)
 {
     mit_des_key_schedule schedule;
     size_t input_length = 0;
     unsigned int i;
 
-    /* key->enctype was checked by the caller */
+    /* key->keyblock.enctype was checked by the caller */
 
-    if (key->length != 8)
+    if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
 
     for (i = 0; i < num_data; i++) {
@@ -109,7 +109,7 @@
     if (ivec && (ivec->length != 8))
 	return(KRB5_BAD_MSIZE);
 
-    switch (mit_des_key_sched(key->contents, schedule)) {
+    switch (mit_des_key_sched(key->keyblock.contents, schedule)) {
     case -1:
 	return(KRB5DES_BAD_KEYPAR);
     case -2:
@@ -128,7 +128,7 @@
 }
 
 static krb5_error_code
-k5_des_encrypt_iov(const krb5_keyblock *key,
+k5_des_encrypt_iov(krb5_key key,
 		    const krb5_data *ivec,
 		    krb5_crypto_iov *data,
 		    size_t num_data)
@@ -137,7 +137,7 @@
 }
 
 static krb5_error_code
-k5_des_decrypt_iov(const krb5_keyblock *key,
+k5_des_decrypt_iov(krb5_key key,
 		   const krb5_data *ivec,
 		   krb5_crypto_iov *data,
 		   size_t num_data)

Modified: trunk/src/lib/crypto/builtin/enc_provider/des3.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/des3.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/enc_provider/des3.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -30,13 +30,13 @@
 #include <rand2key.h>
 
 static krb5_error_code
-validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec,
+validate_and_schedule(krb5_key key, const krb5_data *ivec,
 		      const krb5_data *input, const krb5_data *output,
 		      mit_des3_key_schedule *schedule)
 {
-    /* key->enctype was checked by the caller */
+    /* key->keyblock.enctype was checked by the caller */
 
-    if (key->length != 24)
+    if (key->keyblock.length != 24)
 	return(KRB5_BAD_KEYSIZE);
     if ((input->length%8) != 0)
 	return(KRB5_BAD_MSIZE);
@@ -45,7 +45,7 @@
     if (input->length != output->length)
 	return(KRB5_BAD_MSIZE);
 
-    switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents,
+    switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents,
 			       *schedule)) {
     case -1:
 	return(KRB5DES_BAD_KEYPAR);
@@ -56,7 +56,7 @@
 }
 
 static krb5_error_code
-validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec,
+validate_and_schedule_iov(krb5_key key, const krb5_data *ivec,
 			  const krb5_crypto_iov *data, size_t num_data,
 			  mit_des3_key_schedule *schedule)
 {
@@ -69,14 +69,14 @@
 	    input_length += iov->data.length;
     }
 
-    if (key->length != 24)
+    if (key->keyblock.length != 24)
 	return(KRB5_BAD_KEYSIZE);
     if ((input_length%8) != 0)
 	return(KRB5_BAD_MSIZE);
     if (ivec && (ivec->length != 8))
 	return(KRB5_BAD_MSIZE);
 
-    switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents,
+    switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents,
 			       *schedule)) {
     case -1:
 	return(KRB5DES_BAD_KEYPAR);
@@ -87,7 +87,7 @@
 }
 
 static krb5_error_code
-k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des3_encrypt(krb5_key key, const krb5_data *ivec,
 		const krb5_data *input, krb5_data *output)
 {
     mit_des3_key_schedule schedule;
@@ -109,7 +109,7 @@
 }
 
 static krb5_error_code
-k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des3_decrypt(krb5_key key, const krb5_data *ivec,
 		const krb5_data *input, krb5_data *output)
 {
     mit_des3_key_schedule schedule;
@@ -131,7 +131,7 @@
 }
 
 static krb5_error_code
-k5_des3_encrypt_iov(const krb5_keyblock *key,
+k5_des3_encrypt_iov(krb5_key key,
 		    const krb5_data *ivec,
 		    krb5_crypto_iov *data,
 		    size_t num_data)
@@ -154,7 +154,7 @@
 }
 
 static krb5_error_code
-k5_des3_decrypt_iov(const krb5_keyblock *key,
+k5_des3_decrypt_iov(krb5_key key,
 		    const krb5_data *ivec,
 		    krb5_crypto_iov *data,
 		    size_t num_data)

Modified: trunk/src/lib/crypto/builtin/enc_provider/rc4.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/rc4.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/enc_provider/rc4.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,7 +29,7 @@
 
 /* Interface layer to kerb5 crypto layer */
 static krb5_error_code
-k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *,
+k5_arcfour_docrypt(krb5_key, const krb5_data *,
 		   const krb5_data *, krb5_data *);
 
 static const unsigned char arcfour_weakkey1[] = {0x00, 0x00, 0xfd};
@@ -113,14 +113,14 @@
 
 /* The workhorse of the arcfour system, this impliments the cipher */
 static krb5_error_code
-k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
+k5_arcfour_docrypt(krb5_key key, const krb5_data *state,
 	       const krb5_data *input, krb5_data *output)
 {
   ArcfourContext *arcfour_ctx;
   ArcFourCipherState *cipher_state;
   int ret;
 
-  if (key->length != 16)
+  if (key->keyblock.length != 16)
     return(KRB5_BAD_KEYSIZE);
   if (state && (state->length != sizeof (ArcFourCipherState)))
     return(KRB5_BAD_MSIZE);
@@ -131,7 +131,8 @@
     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))) {
+      if ((ret=k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
+			       key->keyblock.length))) {
 	return ret;
       }
       cipher_state->initialized = 1;
@@ -142,7 +143,8 @@
     arcfour_ctx=malloc(sizeof (ArcfourContext));
     if (arcfour_ctx == NULL)
       return ENOMEM;
-    if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) {
+    if ((ret=k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
+			     key->keyblock.length))) {
       free(arcfour_ctx);
       return (ret);
     }
@@ -157,7 +159,7 @@
 
 /* In-place encryption */
 static krb5_error_code
-k5_arcfour_docrypt_iov(const krb5_keyblock *key,
+k5_arcfour_docrypt_iov(krb5_key key,
 		       const krb5_data *state,
 		       krb5_crypto_iov *data,
 		       size_t num_data)
@@ -167,7 +169,7 @@
     krb5_error_code ret;
     size_t i;
 
-    if (key->length != 16)
+    if (key->keyblock.length != 16)
 	return KRB5_BAD_KEYSIZE;
     if (state != NULL && (state->length != sizeof(ArcFourCipherState)))
 	return KRB5_BAD_MSIZE;
@@ -176,7 +178,8 @@
 	cipher_state = (ArcFourCipherState *)state->data;
 	arcfour_ctx = &cipher_state->ctx;
 	if (cipher_state->initialized == 0) {
-	    ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length);
+	    ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
+				  key->keyblock.length);
 	    if (ret != 0)
 		return ret;
 
@@ -187,7 +190,8 @@
 	if (arcfour_ctx == NULL)
 	    return ENOMEM;
 
-	ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length);
+	ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
+			      key->keyblock.length);
 	if (ret != 0) {
 	    free(arcfour_ctx);
 	    return ret;

Modified: trunk/src/lib/crypto/builtin/hmac.c
===================================================================
--- trunk/src/lib/crypto/builtin/hmac.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/hmac.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -28,6 +28,17 @@
 #include "aead.h"
 
 /*
+ * Because our built-in HMAC implementation doesn't need to invoke any
+ * encryption or keyed hash functions, it is simplest to define it in
+ * terms of keyblocks, and then supply a simple wrapper for the
+ * "normal" krb5_key-using interfaces.  The keyblock interfaces are
+ * useful for the built-in arcfour code which constructs a lot of
+ * intermediate HMAC keys.  For other back ends, it should not be
+ * necessary to supply the _keyblock versions of the hmac functions if
+ * the back end code doesn't make use of them.
+ */
+
+/*
  * the HMAC transform looks like:
  *
  * H(K XOR opad, H(K XOR ipad, text))
@@ -40,8 +51,9 @@
  */
 
 krb5_error_code
-krb5_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key,
-          unsigned int icount, const krb5_data *input, krb5_data *output)
+krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
+		      const krb5_keyblock *key, unsigned int icount,
+		      const krb5_data *input, krb5_data *output)
 {
     size_t hashsize, blocksize;
     unsigned char *xorkey, *ihash;
@@ -127,8 +139,10 @@
 }
 
 krb5_error_code
-krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key,
-                 const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+krb5int_hmac_iov_keyblock(const struct krb5_hash_provider *hash,
+			  const krb5_keyblock *key,
+			  const krb5_crypto_iov *data, size_t num_data,
+			  krb5_data *output)
 {
     krb5_data *sign_data;
     size_t num_sign_data;
@@ -156,10 +170,25 @@
     }
 
     /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */
-    ret = krb5_hmac(hash, key, num_sign_data, sign_data, output);
+    ret = krb5int_hmac_keyblock(hash, key, num_sign_data, sign_data, output);
 
     free(sign_data);
 
     return ret;
 }
 
+krb5_error_code
+krb5_hmac(const struct krb5_hash_provider *hash, krb5_key key,
+	  unsigned int icount, const krb5_data *input, krb5_data *output)
+{
+    return krb5int_hmac_keyblock(hash, &key->keyblock, icount, input, output);
+}
+
+krb5_error_code
+krb5int_hmac_iov(const struct krb5_hash_provider *hash, krb5_key key,
+		 const krb5_crypto_iov *data, size_t num_data,
+		 krb5_data *output)
+{
+    return krb5int_hmac_iov_keyblock(hash, &key->keyblock, data, num_data,
+				     output);
+}

Modified: trunk/src/lib/crypto/builtin/pbkdf2.c
===================================================================
--- trunk/src/lib/crypto/builtin/pbkdf2.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/builtin/pbkdf2.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -25,19 +25,36 @@
  * 
  *
  * Implementation of PBKDF2 from RFC 2898.
- * Not currently used; likely to be used when we get around to AES support.
  */
 
 #include <ctype.h>
 #include "k5-int.h"
 #include "hash_provider.h"
 
+/*
+ * RFC 2898 specifies PBKDF2 in terms of an underlying pseudo-random
+ * function with two arguments (password and salt||blockindex).  Right
+ * now we only use PBKDF2 with the hmac-sha1 PRF, also specified in
+ * RFC 2898, which invokes HMAC with the password as the key and the
+ * second argument as the text.  (HMAC accepts any key size up to the
+ * block size; the password is pre-hashed with unkeyed SHA1 if it is
+ * longer than the block size.)
+ *
+ * For efficiency, it is better to generate the key from the password
+ * once at the beginning, so we specify prf_func in terms of a
+ * krb5_key first argument.  That might not be convenient for a PRF
+ * which uses the password in some other way, so this might need to be
+ * adjusted in the future.
+ */
+
+typedef krb5_error_code (*prf_func)(krb5_key pass, krb5_data *salt,
+				    krb5_data *out);
+
 /* Not exported, for now.  */
 static krb5_error_code
-krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
-				       krb5_data *),
-		size_t hlen, const krb5_data *pass, const krb5_data *salt,
-		unsigned long count, const krb5_data *output);
+krb5int_pbkdf2 (prf_func prf, size_t hlen, krb5_key pass,
+		const krb5_data *salt, unsigned long count,
+		const krb5_data *output);
 
 static int debug_hmac = 0;
 
@@ -61,35 +78,21 @@
     }
     printf("\n");
 }
-static void printk(const char *descr, krb5_keyblock *k) {
-    krb5_data d;
-    d.data = (char *) k->contents;
-    d.length = k->length;
-    printd(descr, &d);
-}
 
 static krb5_error_code
-F(char *output, char *u_tmp1, char *u_tmp2,
-  krb5_error_code (*prf)(krb5_keyblock *, krb5_data *, krb5_data *),
-  size_t hlen,
-  const krb5_data *pass, const krb5_data *salt,
-  unsigned long count, int i)
+F(char *output, char *u_tmp1, char *u_tmp2, prf_func prf, size_t hlen,
+  krb5_key pass, const krb5_data *salt, unsigned long count, int i)
 {
     unsigned char ibytes[4];
     size_t tlen;
     unsigned int j, k;
-    krb5_keyblock pdata;
     krb5_data sdata;
     krb5_data out;
     krb5_error_code err;
 
-    pdata.contents = pass->data;
-    pdata.length = pass->length;
-
 #if 0
     printf("F(i=%d, count=%lu, pass=%d:%s)\n", i, count,
 	   pass->length, pass->data);
-    printk("F password", &pdata);
 #endif
 
     /* Compute U_1.  */
@@ -112,7 +115,7 @@
 #if 0
     printf("F: computing hmac #1 (U_1) with %s\n", pdata.contents);
 #endif
-    err = (*prf)(&pdata, &sdata, &out);
+    err = (*prf)(pass, &sdata, &out);
     if (err)
 	return err;
 #if 0
@@ -127,7 +130,7 @@
 	printf("F: computing hmac #%d (U_%d)\n", j, j);
 #endif
 	memcpy(u_tmp2, u_tmp1, hlen);
-	err = (*prf)(&pdata, &sdata, &out);
+	err = (*prf)(pass, &sdata, &out);
 	if (err)
 	    return err;
 #if 0
@@ -147,11 +150,9 @@
 }
 
 static krb5_error_code
-krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
-				       krb5_data *),
-		size_t hlen,
-		const krb5_data *pass, const krb5_data *salt,
-		unsigned long count, const krb5_data *output)
+krb5int_pbkdf2 (prf_func prf, size_t hlen, krb5_key pass,
+		const krb5_data *salt, unsigned long count,
+		const krb5_data *output)
 {
     int l, r, i;
     char *utmp1, *utmp2;
@@ -209,57 +210,55 @@
     return 0;
 }
 
-static krb5_error_code hmac1(const struct krb5_hash_provider *h,
-			     krb5_keyblock *key, krb5_data *in, krb5_data *out)
+/*
+ * Implements the hmac-sha1 PRF.  pass has been pre-hashed (if
+ * necessary) and converted to a key already; salt has had the block
+ * index appended to the original salt.
+ */
+static krb5_error_code
+hmac_sha1(krb5_key pass, krb5_data *salt, krb5_data *out)
 {
-    char tmp[40];
-    size_t blocksize, hashsize;
+    const struct krb5_hash_provider *h = &krb5int_hash_sha1;
     krb5_error_code err;
-    krb5_keyblock k;
 
-    k = *key;
-    key = &k;
     if (debug_hmac)
-	printk(" test key", key);
-    blocksize = h->blocksize;
-    hashsize = h->hashsize;
-    if (hashsize > sizeof(tmp))
-	abort();
-    if (key->length > blocksize) {
-	krb5_data d, d2;
-	d.data = (char *) key->contents;
-	d.length = key->length;
-	d2.data = tmp;
-	d2.length = hashsize;
-	err = h->hash (1, &d, &d2);
-	if (err)
-	    return err;
-	key->length = d2.length;
-	key->contents = (krb5_octet *) d2.data;
-	if (debug_hmac)
-	    printk(" pre-hashed key", key);
-    }
-    if (debug_hmac)
-	printd(" hmac input", in);
-    err = krb5_hmac(h, key, 1, in, out);
+	printd(" hmac input", salt);
+    err = krb5_hmac(h, pass, 1, salt, out);
     if (err == 0 && debug_hmac)
 	printd(" hmac output", out);
     return err;
 }
 
-static krb5_error_code
-foo(krb5_keyblock *pass, krb5_data *salt, krb5_data *out)
+krb5_error_code
+krb5int_pbkdf2_hmac_sha1 (const krb5_data *out, unsigned long count,
+			  const krb5_data *pass, const krb5_data *salt)
 {
+    const struct krb5_hash_provider *h = &krb5int_hash_sha1;
+    krb5_keyblock keyblock;
+    krb5_key key;
+    char tmp[40];
+    krb5_data d;
     krb5_error_code err;
 
-    memset(out->data, 0, out->length);
-    err = hmac1 (&krb5int_hash_sha1, pass, salt, out);
+    assert(h->hashsize <= sizeof(tmp));
+    if (pass->length > h->blocksize) {
+	d.data = tmp;
+	d.length = h->hashsize;
+	err = h->hash (1, pass, &d);
+	if (err)
+	    return err;
+	keyblock.length = d.length;
+	keyblock.contents = (krb5_octet *) d.data;
+    } else {
+	keyblock.length = pass->length;
+	keyblock.contents = (krb5_octet *) pass->data;
+    }
+
+    err = krb5_k_create_key(NULL, &keyblock, &key);
+    if (err)
+	return err;
+
+    err = krb5int_pbkdf2(hmac_sha1, 20, key, salt, count, out);
+    krb5_k_free_key(NULL, key);
     return err;
 }
-
-krb5_error_code
-krb5int_pbkdf2_hmac_sha1 (const krb5_data *out, unsigned long count,
-			  const krb5_data *pass, const krb5_data *salt)
-{
-    return krb5int_pbkdf2 (foo, 20, pass, salt, count, out);
-}

Modified: trunk/src/lib/crypto/crypto_tests/Makefile.in
===================================================================
--- trunk/src/lib/crypto/crypto_tests/Makefile.in	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/crypto_tests/Makefile.in	2009-10-19 20:04:21 UTC (rev 22944)
@@ -33,6 +33,7 @@
 	$(srcdir)/t_shs3.c	\
 	$(srcdir)/t_shs.c	\
 	$(srcdir)/t_verify.c	\
+	$(srcdir)/t_kperf.c	\
 	$(srcdir)/ytest.c	
 
 ##DOSBUILDTOP = ..\..\..
@@ -149,6 +150,9 @@
 t_shs3: t_shs3.o  $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
 	$(CC_LINK) -o t_shs3 t_shs3.o  $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
 
+t_kperf: t_kperf.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
+	$(CC_LINK) -o t_kperf t_kperf.o  $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
+
 ytest: ytest.o shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
 	$(CC_LINK) -o ytest ytest.o  $(SUPPORT_LIB)  $(CRYPTO_DEPLIB)
 

Modified: trunk/src/lib/crypto/crypto_tests/aes-test.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/aes-test.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/crypto_tests/aes-test.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -50,7 +50,11 @@
 }
 static void enc()
 {
-    krb5int_aes_encrypt(&enc_key, &ivec, &in, &out);
+    krb5_key key;
+
+    krb5_k_create_key(NULL, &enc_key, &key);
+    krb5int_aes_encrypt(key, &ivec, &in, &out);
+    krb5_k_free_key(NULL, key);
 }
 
 static void hexdump(const char *label, const char *cp, int len)

Modified: trunk/src/lib/crypto/crypto_tests/t_cksum.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/t_cksum.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/crypto_tests/t_cksum.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -75,6 +75,7 @@
   krb5_boolean		valid;
   size_t		length;
   krb5_keyblock		keyblock;
+  krb5_key		key;
   krb5_error_code	kret=0;
   krb5_data		plaintext, newstyle_checksum;
 
@@ -89,6 +90,8 @@
   keyblock.length = sizeof(testkey);
   keyblock.contents = testkey;
 
+  krb5_k_create_key(NULL, &keyblock, &key);
+
   length = khp.hashsize;
 
   newstyle_checksum.length = length;
@@ -102,13 +105,13 @@
     plaintext.length = strlen(argv[msgindex]);
     plaintext.data = argv[msgindex];
 
-    if ((kret = (*(khp.hash))(&keyblock, 0, 0, &plaintext, &newstyle_checksum))) {
+    if ((kret = (*(khp.hash))(key, 0, 0, &plaintext, &newstyle_checksum))) {
       printf("krb5_calculate_checksum choked with %d\n", kret);
       break;
     }
     print_checksum("correct", MD, argv[msgindex], &newstyle_checksum);
 
-    if ((kret = (*(khp.verify))(&keyblock, 0, 0, &plaintext, &newstyle_checksum,
+    if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &newstyle_checksum,
 				&valid))) {
       printf("verify on new checksum choked with %d\n", kret);
       break;
@@ -120,7 +123,7 @@
     printf("Verify succeeded for \"%s\"\n", argv[msgindex]);
 
     newstyle_checksum.data[0]++;
-    if ((kret = (*(khp.verify))(&keyblock, 0, 0, &plaintext, &newstyle_checksum,
+    if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &newstyle_checksum,
 				&valid))) {
       printf("verify on new checksum choked with %d\n", kret);
       break;

Modified: trunk/src/lib/crypto/crypto_tests/t_cts.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/t_cts.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/crypto_tests/t_cts.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -114,15 +114,12 @@
 	"I would like the General Gau's Chicken, please, and wonton soup.";
     static const unsigned char aeskey[16] = "chicken teriyaki";
     static const int lengths[] = { 17, 31, 32, 47, 48, 64 };
-    extern krb5_error_code krb5int_aes_encrypt(const krb5_keyblock *,
-					       const krb5_data *,
-					       const krb5_data *,
-					       krb5_data *);
 
     int i;
     char outbuf[64], encivbuf[16], decivbuf[16], outbuf2[64];
     krb5_data in, out, enciv, deciv, out2;
-    krb5_keyblock key;
+    krb5_keyblock keyblock;
+    krb5_key key;
     krb5_error_code err;
 
     in.data = input;
@@ -131,11 +128,17 @@
     enciv.length = deciv.length = 16;
     enciv.data = encivbuf;
     deciv.data = decivbuf;
-    key.contents = aeskey;
-    key.length = 16;
+    keyblock.contents = aeskey;
+    keyblock.length = 16;
 
+    err = krb5_k_create_key(NULL, &keyblock, &key);
+    if (err) {
+	printf("error %ld from krb5_k_create_key\n", (long)err);
+	exit(1);
+    }
+
     memset(enciv.data, 0, 16);
-    printk("AES 128-bit key", &key);
+    printk("AES 128-bit key", &keyblock);
     for (i = 0; i < sizeof(lengths)/sizeof(lengths[0]); i++) {
     memset(enciv.data, 0, 16);
     memset(deciv.data, 0, 16);
@@ -143,7 +146,7 @@
 	printf("\n");
 	in.length = out.length = lengths[i];
 	printd("IV", &enciv);
-	err = krb5int_aes_encrypt(&key, &enciv, &in, &out);
+	err = krb5int_aes_encrypt(key, &enciv, &in, &out);
 	if (err) {
 	    printf("error %ld from krb5int_aes_encrypt\n", (long)err);
 	    exit(1);
@@ -152,7 +155,7 @@
 	printd("Output", &out);
 	printd("Next IV", &enciv);
 	out2.length = out.length;
-	err = krb5int_aes_decrypt(&key, &deciv, &out, &out2);
+	err = krb5int_aes_decrypt(key, &deciv, &out, &out2);
 	if (err) {
 	    printf("error %ld from krb5int_aes_decrypt\n", (long)err);
 	    exit(1);

Modified: trunk/src/lib/crypto/crypto_tests/t_encrypt.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/t_encrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/crypto_tests/t_encrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -78,12 +78,14 @@
 main ()
 {
   krb5_context context = 0;
-  krb5_data  in, in2, out, out2, check, check2, state;
+  krb5_data  in, in2, out, out2, check, check2, state, signdata;
   krb5_crypto_iov iov[5];
-  int i;
+  int i, j, pos;
+  unsigned int dummy;
   size_t len;
   krb5_enc_data enc_out, enc_out2;
-  krb5_keyblock *key;
+  krb5_keyblock *keyblock;
+  krb5_key key;
 
   memset(iov, 0, sizeof(iov));
 
@@ -94,6 +96,8 @@
 
   test ("Seeding random number generator",
 	krb5_c_random_seed (context, &in));
+
+  /* Set up output buffers. */
   out.data = malloc(2048);
   out2.data = malloc(2048);
   check.data = malloc(2048);
@@ -107,39 +111,67 @@
   out2.length = 2048;
   check.length = 2048;
   check2.length = 2048;
+
   for (i = 0; interesting_enctypes[i]; i++) {
     krb5_enctype enctype = interesting_enctypes [i];
+
     printf ("Testing enctype %d\n", enctype);
     test ("Initializing a keyblock",
-	  krb5_init_keyblock (context, enctype, 0, &key));
-    test ("Generating random key",
-	  krb5_c_make_random_key (context, enctype, key));
+	  krb5_init_keyblock (context, enctype, 0, &keyblock));
+    test ("Generating random keyblock",
+	  krb5_c_make_random_key (context, enctype, keyblock));
+    test ("Creating opaque key from keyblock",
+	  krb5_k_create_key (context, keyblock, &key));
+
     enc_out.ciphertext = out;
     enc_out2.ciphertext = out2;
     /* We use an intermediate `len' because size_t may be different size 
        than `int' */
-    krb5_c_encrypt_length (context, key->enctype, in.length, &len);
+    krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len);
     enc_out.ciphertext.length = len;
-    test ("Encrypting",
-	  krb5_c_encrypt (context, key, 7, 0, &in, &enc_out));
+
+    /* Encrypt, decrypt, and see if we got the plaintext back again. */
+    test ("Encrypting (c)",
+	  krb5_c_encrypt (context, keyblock, 7, 0, &in, &enc_out));
     test ("Decrypting",
-	  krb5_c_decrypt (context, key, 7, 0, &enc_out, &check));
+	  krb5_c_decrypt (context, keyblock, 7, 0, &enc_out, &check));
     test ("Comparing", compare_results (&in, &check));
-    if ( krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &len) == 0 ){
-	/* We support iov/aead*/
-	int j, pos;
-	krb5_data signdata;
-	signdata.magic = KV5M_DATA;
-	signdata.data = (char *) "This should be signed";
-	signdata.length = strlen(signdata.data);
+
+    /* Try again with the opaque-key-using variants. */
+    memset(out.data, 0, out.length);
+    test ("Encrypting (k)",
+	  krb5_k_encrypt (context, key, 7, 0, &in, &enc_out));
+    test ("Decrypting",
+	  krb5_k_decrypt (context, key, 7, 0, &enc_out, &check));
+    test ("Comparing", compare_results (&in, &check));
+
+    /* Check if this enctype supports IOV encryption. */
+    if ( krb5_c_crypto_length(context, keyblock->enctype,
+			      KRB5_CRYPTO_TYPE_HEADER, &dummy) == 0 ){
+	/* Set up iovecs for stream decryption. */
+	memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length);
 	iov[0].flags= KRB5_CRYPTO_TYPE_STREAM;
+	iov[0].data.data = out2.data;
+	iov[0].data.length = enc_out.ciphertext.length;
 	iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
-	iov[0].data = enc_out.ciphertext;
-	iov[1].data = out;
-	test("IOV stream decrypting",
-	     krb5_c_decrypt_iov( context, key, 7, 0, iov, 2));
+
+	/* Decrypt the encrypted data from above and check it. */
+	test("IOV stream decrypting (c)",
+	     krb5_c_decrypt_iov( context, keyblock, 7, 0, iov, 2));
 	test("Comparing results",
 	     compare_results(&in, &iov[1].data));
+
+	/* Try again with the opaque-key-using variant. */
+	memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length);
+	test("IOV stream decrypting (k)",
+	     krb5_k_decrypt_iov( context, key, 7, 0, iov, 2));
+	test("Comparing results",
+	     compare_results(&in, &iov[1].data));
+
+	/* Set up iovecs for AEAD encryption. */
+	signdata.magic = KV5M_DATA;
+	signdata.data = (char *) "This should be signed";
+	signdata.length = strlen(signdata.data);
 	iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
 	iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
 	iov[1].data = in; /*We'll need to copy memory before encrypt*/
@@ -147,8 +179,10 @@
 	iov[2].data = signdata;
 	iov[3].flags = KRB5_CRYPTO_TYPE_PADDING;
 	iov[4].flags = KRB5_CRYPTO_TYPE_TRAILER;
+
+	/* "Allocate" data for the iovec buffers from the "out" buffer. */
 	test("Setting up iov lengths",
-	     krb5_c_crypto_length_iov(context, key->enctype, iov, 5));
+	     krb5_c_crypto_length_iov(context, keyblock->enctype, iov, 5));
 	for (j=0,pos=0; j <= 4; j++ ){
 	    if (iov[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
 		continue;
@@ -157,56 +191,70 @@
 	}
 	assert (iov[1].data.length == in.length);
 	memcpy(iov[1].data.data, in.data, in.length);
-	test("iov encrypting",
-	     krb5_c_encrypt_iov(context, key, 7, 0, iov, 5));
+
+	/* Encrypt and decrypt in place, and check the result. */
+	test("iov encrypting (c)",
+	     krb5_c_encrypt_iov(context, keyblock, 7, 0, iov, 5));
 	assert(iov[1].data.length == in.length);
 	test("iov decrypting",
-	     krb5_c_decrypt_iov(context, key, 7, 0, iov, 5));
+	     krb5_c_decrypt_iov(context, keyblock, 7, 0, iov, 5));
 	test("Comparing results",
 	     compare_results(&in, &iov[1].data));
 		       
+	/* Try again with opaque-key-using variants. */
+	test("iov encrypting (k)",
+	     krb5_k_encrypt_iov(context, key, 7, 0, iov, 5));
+	assert(iov[1].data.length == in.length);
+	test("iov decrypting",
+	     krb5_k_decrypt_iov(context, key, 7, 0, iov, 5));
+	test("Comparing results",
+	     compare_results(&in, &iov[1].data));
     }
+
     enc_out.ciphertext.length = out.length;
     check.length = 2048;
+
     test ("init_state",
-	  krb5_c_init_state (context, key, 7, &state));
+	  krb5_c_init_state (context, keyblock, 7, &state));
     test ("Encrypting with state",
-	  krb5_c_encrypt (context, key, 7, &state, &in, &enc_out));
+	  krb5_c_encrypt (context, keyblock, 7, &state, &in, &enc_out));
     test ("Encrypting again with state",
-	  krb5_c_encrypt (context, key, 7, &state, &in2, &enc_out2));
+	  krb5_c_encrypt (context, keyblock, 7, &state, &in2, &enc_out2));
     test ("free_state",
-	  krb5_c_free_state (context, key, &state));
+	  krb5_c_free_state (context, keyblock, &state));
     test ("init_state",
-	  krb5_c_init_state (context, key, 7, &state));
+	  krb5_c_init_state (context, keyblock, 7, &state));
     test ("Decrypting with state",
-	  krb5_c_decrypt (context, key, 7, &state, &enc_out, &check));
+	  krb5_c_decrypt (context, keyblock, 7, &state, &enc_out, &check));
     test ("Decrypting again with state",
-	  krb5_c_decrypt (context, key, 7, &state, &enc_out2, &check2));
+	  krb5_c_decrypt (context, keyblock, 7, &state, &enc_out2, &check2));
     test ("free_state",
-	  krb5_c_free_state (context, key, &state));
+	  krb5_c_free_state (context, keyblock, &state));
     test ("Comparing",
 	  compare_results (&in, &check));
     test ("Comparing",
 	  compare_results (&in2, &check2));
-    krb5_free_keyblock (context, key);
+
+    krb5_free_keyblock (context, keyblock);
+    krb5_k_free_key (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));
+	krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &keyblock));
   test ("Generating random RC4 key",
-	krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, key));
+	krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, keyblock));
   enc_out.ciphertext = out;
-  krb5_c_encrypt_length (context, key->enctype, in.length, &len);
+  krb5_c_encrypt_length (context, keyblock->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));
+	krb5_c_encrypt (context, keyblock, 8, 0, &in, &enc_out));
   test ("Decrypting with RC4 key usage 9",
-	krb5_c_decrypt (context, key, 9, 0, &enc_out, &check));
+	krb5_c_decrypt (context, keyblock, 9, 0, &enc_out, &check));
   test ("Comparing", compare_results (&in, &check));
 
-  krb5_free_keyblock (context, key);
+  krb5_free_keyblock (context, keyblock);
   free(out.data);
   free(out2.data);
   free(check.data);

Modified: trunk/src/lib/crypto/crypto_tests/t_hmac.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/t_hmac.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/crypto_tests/t_hmac.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -98,6 +98,7 @@
     char tmp[40];
     size_t blocksize, hashsize;
     krb5_error_code err;
+    krb5_key k;
 
     printk(" test key", key);
     blocksize = h->blocksize;
@@ -120,7 +121,9 @@
 	printk(" pre-hashed key", key);
     }
     printd(" hmac input", in);
-    err = krb5_hmac(h, key, 1, in, out);
+    krb5_k_create_key(NULL, key, &k);
+    err = krb5_hmac(h, k, 1, in, out);
+    krb5_k_free_key(NULL, k);
     if (err == 0)
 	printd(" hmac output", out);
     return err;

Copied: trunk/src/lib/crypto/crypto_tests/t_kperf.c (from rev 22941, branches/enc-perf/src/lib/crypto/crypto_tests/t_kperf.c)

Modified: trunk/src/lib/crypto/krb/Makefile.in
===================================================================
--- trunk/src/lib/crypto/krb/Makefile.in	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/Makefile.in	2009-10-19 20:04:21 UTC (rev 22944)
@@ -44,6 +44,7 @@
 	enctype_compare.o	\
 	enctype_to_string.o	\
 	etypes.o		\
+	key.o			\
 	keyblocks.o 		\
 	keyed_cksum.o		\
 	keyed_checksum_types.o	\
@@ -86,6 +87,7 @@
 	$(OUTPRE)enctype_compare.$(OBJEXT)	\
 	$(OUTPRE)enctype_to_string.$(OBJEXT)	\
 	$(OUTPRE)etypes.$(OBJEXT)		\
+	$(OUTPRE)key.$(OBJECT)			\
 	$(OUTPRE)keyblocks.$(OBJEXT) 		\
 	$(OUTPRE)keyed_cksum.$(OBJEXT)		\
 	$(OUTPRE)keyed_checksum_types.$(OBJEXT)	\
@@ -127,6 +129,7 @@
 	$(srcdir)/enctype_compare.c	\
 	$(srcdir)/enctype_to_string.c	\
 	$(srcdir)/etypes.c		\
+	$(srcdir)/key.c			\
 	$(srcdir)/keyblocks.c 		\
 	$(srcdir)/keyed_cksum.c		\
 	$(srcdir)/keyed_checksum_types.c\

Modified: trunk/src/lib/crypto/krb/aead.c
===================================================================
--- trunk/src/lib/crypto/krb/aead.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/aead.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -93,7 +93,7 @@
 
 krb5_error_code 
 krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type,
-			    const krb5_keyblock *key,
+			    krb5_key key,
 			    krb5_keyusage usage,
 			    const krb5_crypto_iov *data,
 			    size_t num_data,
@@ -107,7 +107,7 @@
 
 	if (cksum_type->keyed_etype) {
 	    e1 = find_enctype(cksum_type->keyed_etype);
-	    e2 = find_enctype(key->enctype);
+	    e2 = find_enctype(key->keyblock.enctype);
 	    if (e1 == NULL || e2 == NULL || e1->enc != e2->enc) {
 		ret = KRB5_BAD_ENCTYPE;
 		goto cleanup;
@@ -338,7 +338,7 @@
 krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
 			     const struct krb5_enc_provider *enc,
 			     const struct krb5_hash_provider *hash,
-			     const krb5_keyblock *key,
+			     krb5_key key,
 			     krb5_keyusage keyusage,
 			     const krb5_data *ivec,
 			     krb5_crypto_iov *data,
@@ -451,7 +451,7 @@
 krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead,
 			      const struct krb5_enc_provider *enc,
 			      const struct krb5_hash_provider *hash,
-			      const krb5_keyblock *key, krb5_keyusage usage,
+			      krb5_key key, krb5_keyusage usage,
 			      const krb5_data *ivec, const krb5_data *input,
 			      krb5_data *output)
 {
@@ -513,7 +513,7 @@
 krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead,
 			      const struct krb5_enc_provider *enc,
 			      const struct krb5_hash_provider *hash,
-			      const krb5_keyblock *key, krb5_keyusage usage,
+			      krb5_key key, krb5_keyusage usage,
 			      const krb5_data *ivec, const krb5_data *input,
 			      krb5_data *output)
 {

Modified: trunk/src/lib/crypto/krb/aead.h
===================================================================
--- trunk/src/lib/crypto/krb/aead.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/aead.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -36,7 +36,7 @@
 
 krb5_error_code
 krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum,
-			    const krb5_keyblock *key,
+			    krb5_key key,
 			    krb5_keyusage usage,
 			    const krb5_crypto_iov *data,
 			    size_t num_data,
@@ -87,7 +87,7 @@
 krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
 			     const struct krb5_enc_provider *enc,
 			     const struct krb5_hash_provider *hash,
-			     const krb5_keyblock *key,
+			     krb5_key key,
 			     krb5_keyusage keyusage,
 			     const krb5_data *ivec,
 			     krb5_crypto_iov *data,
@@ -97,7 +97,7 @@
 krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead,
 			      const struct krb5_enc_provider *enc,
 			      const struct krb5_hash_provider *hash,
-			      const krb5_keyblock *key, krb5_keyusage usage,
+			      krb5_key key, krb5_keyusage usage,
 			      const krb5_data *ivec, const krb5_data *input,
 			      krb5_data *output);
 
@@ -105,7 +105,7 @@
 krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead,
 			      const struct krb5_enc_provider *enc,
 			      const struct krb5_hash_provider *hash,
-			      const krb5_keyblock *key, krb5_keyusage usage,
+			      krb5_key key, krb5_keyusage usage,
 			      const krb5_data *ivec, const krb5_data *input,
 			      krb5_data *output);
 

Modified: trunk/src/lib/crypto/krb/combine_keys.c
===================================================================
--- trunk/src/lib/crypto/krb/combine_keys.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/combine_keys.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -79,7 +79,8 @@
     size_t keybytes, keylength;
     const struct krb5_enc_provider *enc;
     krb5_data input, randbits;
-    krb5_keyblock tkey;
+    krb5_keyblock tkeyblock;
+    krb5_key tkey = NULL;
     krb5_error_code ret;
     const struct krb5_keytypes *ktp;
     krb5_boolean myalloc = FALSE;
@@ -152,13 +153,17 @@
 
     randbits.length = keybytes;
     randbits.data = (char *) rnd;
-    tkey.length = keylength;
-    tkey.contents = output;
+    tkeyblock.length = keylength;
+    tkeyblock.contents = output;
 
-    ret = (*enc->make_key)(&randbits, &tkey);
+    ret = (*enc->make_key)(&randbits, &tkeyblock);
     if (ret)
 	goto cleanup;
 
+    ret = krb5_k_create_key(NULL, &tkeyblock, &tkey);
+    if (ret)
+	goto cleanup;
+
     /*
      * Run through derive-key one more time to produce the final key.
      * Note that the input to derive-key is the ASCII string "combine".
@@ -185,7 +190,7 @@
 	myalloc = TRUE;
     }
 
-    ret = krb5_derive_key(enc, &tkey, outkey, &input);
+    ret = krb5_derive_keyblock(enc, tkey, outkey, &input);
     if (ret) {
 	if (myalloc) {
 	    free(outkey->contents);
@@ -200,6 +205,7 @@
     zapfree(rnd, keybytes);
     zapfree(combined, keybytes * 2);
     zapfree(output, keylength);
+    krb5_k_free_key(NULL, tkey);
     return ret;
 }
 
@@ -215,6 +221,7 @@
     unsigned char *inblockdata = NULL, *outblockdata = NULL;
     krb5_data inblock, outblock;
     krb5_error_code ret;
+    krb5_key key = NULL;
 
     blocksize = enc->block_size;
     keybytes = enc->keybytes;
@@ -226,6 +233,9 @@
     outblockdata = k5alloc(blocksize, &ret);
     if (ret)
 	goto cleanup;
+    ret = krb5_k_create_key(NULL, inkey, &key);
+    if (ret)
+	goto cleanup;
 
     inblock.data = (char *) inblockdata;
     inblock.length = blocksize;
@@ -246,7 +256,7 @@
 
     n = 0;
     while (n < keybytes) {
-	ret = (*enc->encrypt)(inkey, 0, &inblock, &outblock);
+	ret = (*enc->encrypt)(key, 0, &inblock, &outblock);
 	if (ret)
 	    goto cleanup;
 
@@ -263,6 +273,7 @@
 cleanup:
     zapfree(inblockdata, blocksize);
     zapfree(outblockdata, blocksize);
+    krb5_k_free_key(NULL, key);
     return ret;
 }
 

Modified: trunk/src/lib/crypto/krb/decrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/decrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/decrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,13 +29,13 @@
 #include "aead.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
+krb5_k_decrypt(krb5_context context, krb5_key key,
 	       krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_enc_data *input, krb5_data *output)
 {
     const struct krb5_keytypes *ktp;
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL)
 	return KRB5_BAD_ENCTYPE;
 
@@ -53,3 +53,19 @@
     return (*ktp->decrypt)(ktp->enc, ktp->hash, key, usage, ivec,
 			   &input->ciphertext, output);
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_decrypt(krb5_context context, const krb5_keyblock *keyblock,
+	       krb5_keyusage usage, const krb5_data *ivec,
+	       const krb5_enc_data *input, krb5_data *output)
+{
+    krb5_key key;
+    krb5_error_code ret;
+
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_decrypt(context, key, usage, ivec, input, output);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/decrypt_iov.c
===================================================================
--- trunk/src/lib/crypto/krb/decrypt_iov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/decrypt_iov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,8 +29,8 @@
 #include "aead.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_decrypt_iov(krb5_context context,
-		   const krb5_keyblock *key,
+krb5_k_decrypt_iov(krb5_context context,
+		   krb5_key key,
 		   krb5_keyusage usage,
 		   const krb5_data *cipher_state,
 		   krb5_crypto_iov *data,
@@ -38,7 +38,7 @@
 {
     const struct krb5_keytypes *ktp;
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL || ktp->aead == NULL)
 	return KRB5_BAD_ENCTYPE;
 
@@ -53,3 +53,22 @@
 				     usage, cipher_state, data, num_data);
 }
 
+krb5_error_code KRB5_CALLCONV
+krb5_c_decrypt_iov(krb5_context context,
+		   const krb5_keyblock *keyblock,
+		   krb5_keyusage usage,
+		   const krb5_data *cipher_state,
+		   krb5_crypto_iov *data,
+		   size_t num_data)
+{
+    krb5_key key;
+    krb5_error_code ret;
+
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_decrypt_iov(context, key, usage, cipher_state, data,
+			     num_data);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/dk/checksum.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/checksum.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/checksum.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -33,19 +33,17 @@
 
 krb5_error_code
 krb5_dk_make_checksum(const struct krb5_hash_provider *hash,
-		      const krb5_keyblock *key, krb5_keyusage usage,
+		      krb5_key key, krb5_keyusage usage,
 		      const krb5_data *input, krb5_data *output)
 {
     const struct krb5_keytypes *ktp;
     const struct krb5_enc_provider *enc;
-    size_t keylength;
     krb5_error_code ret;
     unsigned char constantdata[K5CLENGTH];
     krb5_data datain;
-    unsigned char *kcdata;
-    krb5_keyblock kc;
+    krb5_key kc;
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL)
 	return KRB5_BAD_ENCTYPE;
     enc = ktp->enc;
@@ -55,15 +53,6 @@
      * output->length will be tested in krb5_hmac.
      */
 
-    /* Allocate and set to-be-derived keys. */
-    keylength = enc->keylength;
-    kcdata = malloc(keylength);
-    if (kcdata == NULL)
-	return ENOMEM;
-
-    kc.contents = kcdata;
-    kc.length = keylength;
-
     /* Derive the key. */
  
     datain.data = (char *) constantdata;
@@ -75,37 +64,34 @@
 
     ret = krb5_derive_key(enc, key, &kc, &datain);
     if (ret)
-	goto cleanup;
+	return ret;
 
     /* hash the data */
 
     datain = *input;
 
-    ret = krb5_hmac(hash, &kc, 1, &datain, output);
+    ret = krb5_hmac(hash, kc, 1, &datain, output);
     if (ret)
 	memset(output->data, 0, output->length);
 
-cleanup:
-    zapfree(kcdata, keylength);
+    krb5_k_free_key(NULL, kc);
     return ret;
 }
 
 krb5_error_code
 krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash,
-		          const krb5_keyblock *key, krb5_keyusage usage,
+		          krb5_key key, krb5_keyusage usage,
 			  const krb5_crypto_iov *data, size_t num_data,
 			  krb5_data *output)
 {
     const struct krb5_keytypes *ktp;
     const struct krb5_enc_provider *enc;
-    size_t keylength;
     krb5_error_code ret;
     unsigned char constantdata[K5CLENGTH];
     krb5_data datain;
-    unsigned char *kcdata;
-    krb5_keyblock kc;
+    krb5_key kc;
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL)
 	return KRB5_BAD_ENCTYPE;
     enc = ktp->enc;
@@ -115,16 +101,6 @@
      * output->length will be tested in krb5_hmac.
      */
 
-    /* Allocate and set to-be-derived keys. */
-
-    keylength = enc->keylength;
-    kcdata = malloc(keylength);
-    if (kcdata == NULL)
-	return ENOMEM;
-
-    kc.contents = kcdata;
-    kc.length = keylength;
-
     /* Derive the key. */
  
     datain.data = (char *) constantdata;
@@ -136,17 +112,14 @@
 
     ret = krb5_derive_key(enc, key, &kc, &datain);
     if (ret)
-	goto cleanup;
+	return ret;
 
     /* Hash the data. */
 
-    ret = krb5int_hmac_iov(hash, &kc, data, num_data, output);
+    ret = krb5int_hmac_iov(hash, kc, data, num_data, output);
     if (ret)
 	memset(output->data, 0, output->length);
 
-cleanup:
-    zapfree(kcdata, keylength);
-
-    return(ret);
+    krb5_k_free_key(NULL, kc);
+    return ret;
 }
-

Modified: trunk/src/lib/crypto/krb/dk/derive.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/derive.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/derive.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -27,10 +27,67 @@
 #include "k5-int.h"
 #include "dk.h"
 
+static krb5_key
+find_cached_dkey(struct derived_key *list, const krb5_data *constant)
+{
+    for (; list; list = list->next) {
+	if (data_eq(list->constant, *constant)) {
+	    krb5_k_reference_key(NULL, list->dkey);
+	    return list->dkey;
+	}
+    }
+    return NULL;
+}
+
+static krb5_error_code
+add_cached_dkey(krb5_key key, const krb5_data *constant,
+		const krb5_keyblock *dkeyblock, krb5_key *cached_dkey)
+{
+    krb5_key dkey;
+    krb5_error_code ret;
+    struct derived_key *dkent = NULL;
+    char *data = NULL;
+
+    /* Allocate fields for the new entry. */
+    dkent = malloc(sizeof(*dkent));
+    if (dkent == NULL)
+	goto cleanup;
+    data = malloc(constant->length);
+    if (data == NULL)
+	goto cleanup;
+    ret = krb5_k_create_key(NULL, dkeyblock, &dkey);
+    if (ret != 0)
+	goto cleanup;
+
+    /* Add the new entry to the list. */
+    memcpy(data, constant->data, constant->length);
+    dkent->dkey = dkey;
+    dkent->constant.data = data;
+    dkent->constant.length = constant->length;
+    dkent->next = key->derived;
+    key->derived = dkent;
+
+    /* Return a "copy" of the cached key. */
+    krb5_k_reference_key(NULL, dkey);
+    *cached_dkey = dkey;
+    return 0;
+
+cleanup:
+    free(dkent);
+    free(data);
+    return ENOMEM;
+}
+
+/*
+ * Compute a derived key into the keyblock outkey.  This variation on
+ * krb5_derive_key does not cache the result, as it is only used
+ * directly in situations which are not expected to be repeated with
+ * the same inkey and constant.
+ */
 krb5_error_code
-krb5_derive_key(const struct krb5_enc_provider *enc,
-		const krb5_keyblock *inkey, krb5_keyblock *outkey,
-		const krb5_data *in_constant)
+krb5_derive_keyblock(const struct krb5_enc_provider *enc,
+		     krb5_key inkey, krb5_keyblock *outkey,
+		     const krb5_data *in_constant)
 {
     size_t blocksize, keybytes, n;
     unsigned char *inblockdata = NULL, *outblockdata = NULL, *rawkey = NULL;
@@ -40,7 +97,8 @@
     blocksize = enc->block_size;
     keybytes = enc->keybytes;
 
-    if (inkey->length != enc->keylength || outkey->length != enc->keylength)
+    if (inkey->keyblock.length != enc->keylength ||
+	outkey->length != enc->keylength)
 	return KRB5_CRYPTO_INTERNAL;
 
     /* Allocate and set up buffers. */
@@ -103,10 +161,48 @@
     return ret;
 }
 
+krb5_error_code
+krb5_derive_key(const struct krb5_enc_provider *enc,
+		krb5_key inkey, krb5_key *outkey,
+		const krb5_data *in_constant)
+{
+    krb5_keyblock keyblock;
+    krb5_error_code ret;
+    krb5_key dkey;
 
+    *outkey = NULL;
+
+    /* Check for a cached result. */
+    dkey = find_cached_dkey(inkey->derived, in_constant);
+    if (dkey != NULL) {
+	*outkey = dkey;
+	return 0;
+    }
+
+    /* Derive into a temporary keyblock. */
+    keyblock.length = enc->keylength;
+    keyblock.contents = malloc(keyblock.length);
+    if (keyblock.contents == NULL)
+	return ENOMEM;
+    ret = krb5_derive_keyblock(enc, inkey, &keyblock, in_constant);
+    if (ret)
+	goto cleanup;
+
+    /* Cache the derived key. */
+    ret = add_cached_dkey(inkey, in_constant, &keyblock, &dkey);
+    if (ret != 0)
+	goto cleanup;
+
+    *outkey = dkey;
+
+cleanup:
+    zapfree(keyblock.contents, keyblock.length);
+    return ret;
+}
+
 krb5_error_code
 krb5_derive_random(const struct krb5_enc_provider *enc,
-		   const krb5_keyblock *inkey, krb5_data *outrnd,
+		   krb5_key inkey, krb5_data *outrnd,
 		   const krb5_data *in_constant)
 {
     size_t blocksize, keybytes, n;
@@ -117,7 +213,7 @@
     blocksize = enc->block_size;
     keybytes = enc->keybytes;
 
-    if (inkey->length != enc->keylength || outrnd->length != keybytes)
+    if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
 	return KRB5_CRYPTO_INTERNAL;
 
     /* Allocate and set up buffers. */

Modified: trunk/src/lib/crypto/krb/dk/dk.h
===================================================================
--- trunk/src/lib/crypto/krb/dk/dk.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/dk.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,7 +32,7 @@
 
 krb5_error_code krb5_dk_encrypt(const struct krb5_enc_provider *enc,
 				const struct krb5_hash_provider *hash,
-				const krb5_keyblock *key, krb5_keyusage usage,
+				krb5_key key, krb5_keyusage usage,
 				const krb5_data *ivec,
 				const krb5_data *input, krb5_data *output);
 
@@ -42,7 +42,7 @@
 
 krb5_error_code krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
 				       const struct krb5_hash_provider *hash,
-				       const krb5_keyblock *key,
+				       krb5_key key,
 				       krb5_keyusage usage,
 				       const krb5_data *ivec,
 				       const krb5_data *input,
@@ -50,13 +50,13 @@
 
 krb5_error_code krb5_dk_decrypt(const struct krb5_enc_provider *enc,
 				const struct krb5_hash_provider *hash,
-				const krb5_keyblock *key, krb5_keyusage usage,
+				krb5_key key, krb5_keyusage usage,
 				const krb5_data *ivec, const krb5_data *input,
 				krb5_data *arg_output);
 
 krb5_error_code krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc,
 				       const struct krb5_hash_provider *hash,
-				       const krb5_keyblock *key,
+				       krb5_key key,
 				       krb5_keyusage usage,
 				       const krb5_data *ivec,
 				       const krb5_data *input,
@@ -68,26 +68,31 @@
 					 const krb5_data *params,
 					 krb5_keyblock *key);
 
+krb5_error_code krb5_derive_keyblock(const struct krb5_enc_provider *enc,
+				     krb5_key inkey,
+				     krb5_keyblock *outkey,
+				     const krb5_data *in_constant);
+
 krb5_error_code krb5_derive_key(const struct krb5_enc_provider *enc,
-				const krb5_keyblock *inkey,
-				krb5_keyblock *outkey,
+				krb5_key inkey,
+				krb5_key *outkey,
 				const krb5_data *in_constant);
 
 krb5_error_code krb5_dk_make_checksum(const struct krb5_hash_provider *hash,
-				      const krb5_keyblock *key,
+				      krb5_key key,
 				      krb5_keyusage usage,
 				      const krb5_data *input,
 				      krb5_data *output);
 
 krb5_error_code
 krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash,
-			     const krb5_keyblock *key, krb5_keyusage usage,
+			     krb5_key key, krb5_keyusage usage,
 			     const krb5_crypto_iov *data, size_t num_data,
 			     krb5_data *output);
 
 krb5_error_code
 krb5_derive_random(const struct krb5_enc_provider *enc,
-		   const krb5_keyblock *inkey, krb5_data *outrnd,
+		   krb5_key inkey, krb5_data *outrnd,
 		   const krb5_data *in_constant);
 
 /* AEAD */

Modified: trunk/src/lib/crypto/krb/dk/dk_aead.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/dk_aead.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/dk_aead.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -61,7 +61,7 @@
 krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
 		       const struct krb5_enc_provider *enc,
 		       const struct krb5_hash_provider *hash,
-		       const krb5_keyblock *key,
+		       krb5_key key,
 		       krb5_keyusage usage,
 		       const krb5_data *ivec,
 		       krb5_crypto_iov *data,
@@ -71,7 +71,7 @@
     unsigned char constantdata[K5CLENGTH];
     krb5_data d1, d2;
     krb5_crypto_iov *header, *trailer, *padding;
-    krb5_keyblock ke, ki;
+    krb5_key ke = NULL, ki = NULL;
     size_t i;
     unsigned int blocksize = 0;
     unsigned int plainlen = 0;
@@ -79,9 +79,6 @@
     unsigned int padsize = 0;
     unsigned char *cksum = NULL;
 
-    ke.contents = ki.contents = NULL;
-    ke.length = ki.length = 0;
-
     /* E(Confounder | Plaintext | Pad) | Checksum */
 
     ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING,
@@ -126,14 +123,6 @@
 	padding->data.length = padsize;
     }
 
-    ke.length = enc->keylength;
-    ke.contents = k5alloc(ke.length, &ret);
-    if (ret != 0)
-	goto cleanup;
-    ki.length = enc->keylength;
-    ki.contents = k5alloc(ki.length, &ret);
-    if (ret != 0)
-	goto cleanup;
     cksum = k5alloc(hash->hashsize, &ret);
     if (ret != 0)
 	goto cleanup;
@@ -169,14 +158,14 @@
     d2.length = hash->hashsize;
     d2.data = (char *)cksum;
 
-    ret = krb5int_hmac_iov(hash, &ki, data, num_data, &d2);
+    ret = krb5int_hmac_iov(hash, ki, data, num_data, &d2);
     if (ret != 0)
 	goto cleanup;
 
     /* Encrypt the plaintext (header | data | padding) */
     assert(enc->encrypt_iov != NULL);
 
-    ret = (*enc->encrypt_iov)(&ke, ivec, data, num_data); /* updates ivec */
+    ret = (*enc->encrypt_iov)(ke, ivec, data, num_data); /* updates ivec */
     if (ret != 0)
 	goto cleanup;
 
@@ -187,8 +176,8 @@
     trailer->data.length = hmacsize;
 
 cleanup:
-    zapfree(ke.contents, ke.length);
-    zapfree(ki.contents, ki.length);
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
     free(cksum);
     return ret;
 }
@@ -197,7 +186,7 @@
 krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
 		       const struct krb5_enc_provider *enc,
 		       const struct krb5_hash_provider *hash,
-		       const krb5_keyblock *key,
+		       krb5_key key,
 		       krb5_keyusage usage,
 		       const krb5_data *ivec,
 		       krb5_crypto_iov *data,
@@ -207,7 +196,7 @@
     unsigned char constantdata[K5CLENGTH];
     krb5_data d1;
     krb5_crypto_iov *header, *trailer;
-    krb5_keyblock ke, ki;
+    krb5_key ke = NULL, ki = NULL;
     size_t i;
     unsigned int blocksize = 0; /* enc block size, not confounder len */
     unsigned int cipherlen = 0;
@@ -220,9 +209,6 @@
 					    usage, ivec, data, num_data);
     }
 
-    ke.contents = ki.contents = NULL;
-    ke.length = ki.length = 0;
-
     /* E(Confounder | Plaintext | Pad) | Checksum */
 
     ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING,
@@ -262,14 +248,6 @@
     if (trailer == NULL || trailer->data.length != hmacsize)
 	return KRB5_BAD_MSIZE;
 
-    ke.length = enc->keylength;
-    ke.contents = k5alloc(ke.length, &ret);
-    if (ret != 0)
-	goto cleanup;
-    ki.length = enc->keylength;
-    ki.contents = k5alloc(ki.length, &ret);
-    if (ret != 0)
-	goto cleanup;
     cksum = k5alloc(hash->hashsize, &ret);
     if (ret != 0)
 	goto cleanup;
@@ -296,7 +274,7 @@
     /* Decrypt the plaintext (header | data | padding). */
     assert(enc->decrypt_iov != NULL);
 
-    ret = (*enc->decrypt_iov)(&ke, ivec, data, num_data); /* updates ivec */
+    ret = (*enc->decrypt_iov)(ke, ivec, data, num_data); /* updates ivec */
     if (ret != 0)
 	goto cleanup;
 
@@ -304,7 +282,7 @@
     d1.length = hash->hashsize; /* non-truncated length */
     d1.data = (char *)cksum;
 
-    ret = krb5int_hmac_iov(hash, &ki, data, num_data, &d1);
+    ret = krb5int_hmac_iov(hash, ki, data, num_data, &d1);
     if (ret != 0)
 	goto cleanup;
 
@@ -315,10 +293,9 @@
     }
 
 cleanup:
-    zapfree(ke.contents, ke.length);
-    zapfree(ki.contents, ki.length);
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
     free(cksum);
-
     return ret;
 }
 

Modified: trunk/src/lib/crypto/krb/dk/dk_decrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/dk_decrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/dk_decrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,7 +32,7 @@
 static krb5_error_code
 krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
 				 const struct krb5_hash_provider *hash,
-				 const krb5_keyblock *key,
+				 krb5_key key,
 				 krb5_keyusage usage,
 				 const krb5_data *ivec,
 				 const krb5_data *input,
@@ -43,7 +43,7 @@
 krb5_error_code
 krb5_dk_decrypt(const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, krb5_keyusage usage,
+		krb5_key key, krb5_keyusage usage,
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *output)
 {
@@ -54,7 +54,7 @@
 krb5_error_code
 krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc,
 		       const struct krb5_hash_provider *hash,
-		       const krb5_keyblock *key, krb5_keyusage usage,
+		       krb5_key key, krb5_keyusage usage,
 		       const krb5_data *ivec, const krb5_data *input,
 		       krb5_data *output)
 {
@@ -65,22 +65,20 @@
 static krb5_error_code
 krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
 				 const struct krb5_hash_provider *hash,
-				 const krb5_keyblock *key, krb5_keyusage usage,
+				 krb5_key key, krb5_keyusage usage,
 				 const krb5_data *ivec, const krb5_data *input,
 				 krb5_data *output, size_t hmacsize,
 				 int ivec_mode)
 {
     krb5_error_code ret;
-    size_t hashsize, blocksize, keylength, enclen, plainlen;
-    unsigned char *plaindata = NULL, *kedata = NULL, *kidata = NULL;
-    unsigned char *cksum = NULL, *cn;
-    krb5_keyblock ke, ki;
+    size_t hashsize, blocksize, enclen, plainlen;
+    unsigned char *plaindata = NULL, *cksum = NULL, *cn;
+    krb5_key ke = NULL, ki = NULL;
     krb5_data d1, d2;
     unsigned char constantdata[K5CLENGTH];
 
     hashsize = hash->hashsize;
     blocksize = enc->block_size;
-    keylength = enc->keylength;
 
     if (hmacsize == 0)
 	hmacsize = hashsize;
@@ -90,12 +88,6 @@
     enclen = input->length - hmacsize;
 
     /* Allocate and set up ciphertext and to-be-derived keys. */
-    kedata = k5alloc(keylength, &ret);
-    if (ret != 0)
-	goto cleanup;
-    kidata = k5alloc(keylength, &ret);
-    if (ret != 0)
-	goto cleanup;
     plaindata = k5alloc(enclen, &ret);
     if (ret != 0)
 	goto cleanup;
@@ -103,11 +95,6 @@
     if (ret != 0)
 	goto cleanup;
 
-    ke.contents = kedata;
-    ke.length = keylength;
-    ki.contents = kidata;
-    ki.length = keylength;
-
     /* Derive the keys. */
 
     d1.data = (char *) constantdata;
@@ -135,7 +122,7 @@
     d2.length = enclen;
     d2.data = (char *) plaindata;
 
-    ret = (*enc->decrypt)(&ke, ivec, &d1, &d2);
+    ret = (*enc->decrypt)(ke, ivec, &d1, &d2);
     if (ret != 0)
 	goto cleanup;
 
@@ -155,7 +142,7 @@
     d1.length = hashsize;
     d1.data = (char *) cksum;
 
-    ret = krb5_hmac(hash, &ki, 1, &d2, &d1);
+    ret = krb5_hmac(hash, ki, 1, &d2, &d1);
     if (ret != 0)
 	goto cleanup;
 
@@ -183,8 +170,8 @@
 	memcpy(ivec->data, cn, blocksize);
 
 cleanup:
-    zapfree(kedata, keylength);
-    zapfree(kidata, keylength);
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
     zapfree(plaindata, enclen);
     zapfree(cksum, hashsize);
     return ret;

Modified: trunk/src/lib/crypto/krb/dk/dk_encrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/dk_encrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/dk_encrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -53,20 +53,19 @@
 krb5_error_code
 krb5_dk_encrypt(const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, krb5_keyusage usage,
+		krb5_key key, krb5_keyusage usage,
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *output)
 {
-    size_t blocksize, keylength, plainlen, enclen;
+    size_t blocksize, plainlen, enclen;
     krb5_error_code ret;
     unsigned char constantdata[K5CLENGTH];
     krb5_data d1, d2;
-    unsigned char *plaintext = NULL, *kedata = NULL, *kidata = NULL;
+    unsigned char *plaintext = NULL;
     char *cn;
-    krb5_keyblock ke, ki;
+    krb5_key ke = NULL, ki = NULL;
 
     blocksize = enc->block_size;
-    keylength = enc->keylength;
     plainlen = krb5_roundup(blocksize + input->length, blocksize);
 
     krb5_dk_encrypt_length(enc, hash, input->length, &enclen);
@@ -78,21 +77,10 @@
 
     /* Allocate and set up plaintext and to-be-derived keys. */
 
-    kedata = k5alloc(keylength, &ret);
-    if (ret != 0)
-	goto cleanup;
-    kidata = k5alloc(keylength, &ret);
-    if (ret != 0)
-	goto cleanup;
-    plaintext = k5alloc(plainlen, &ret);
-    if (ret != 0)
-	goto cleanup;
+    plaintext = malloc(plainlen);
+    if (plaintext == NULL)
+	return ENOMEM;
 
-    ke.contents = kedata;
-    ke.length = keylength;
-    ki.contents = kidata;
-    ki.length = keylength;
-
     /* Derive the keys. */
 
     d1.data = (char *) constantdata;
@@ -134,7 +122,7 @@
     d2.length = plainlen;
     d2.data = output->data;
 
-    ret = (*enc->encrypt)(&ke, ivec, &d1, &d2);
+    ret = (*enc->encrypt)(ke, ivec, &d1, &d2);
     if (ret != 0)
 	goto cleanup;
 
@@ -150,7 +138,7 @@
 
     output->length = enclen;
 
-    ret = krb5_hmac(hash, &ki, 1, &d1, &d2);
+    ret = krb5_hmac(hash, ki, 1, &d1, &d2);
     if (ret != 0) {
 	memset(d2.data, 0, d2.length);
 	goto cleanup;
@@ -161,8 +149,8 @@
 	memcpy(ivec->data, cn, blocksize);
 
 cleanup:
-    zapfree(kedata, keylength);
-    zapfree(kidata, keylength);
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
     zapfree(plaintext, plainlen);
     return ret;
 }
@@ -186,7 +174,7 @@
 
 static krb5_error_code
 trunc_hmac (const struct krb5_hash_provider *hash,
-	    const krb5_keyblock *ki, unsigned int num,
+	    krb5_key ki, unsigned int num,
 	    const krb5_data *input, const krb5_data *output)
 {
     size_t hashsize;
@@ -211,23 +199,22 @@
 krb5_error_code
 krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
 		       const struct krb5_hash_provider *hash,
-		       const krb5_keyblock *key, krb5_keyusage usage,
+		       krb5_key key, krb5_keyusage usage,
 		       const krb5_data *ivec, const krb5_data *input,
 		       krb5_data *output)
 {
-    size_t blocksize, keybytes, keylength, plainlen, enclen;
+    size_t blocksize, keybytes, plainlen, enclen;
     krb5_error_code ret;
     unsigned char constantdata[K5CLENGTH];
     krb5_data d1, d2;
-    unsigned char *plaintext = NULL, *kedata = NULL, *kidata = NULL;
+    unsigned char *plaintext = NULL;
     char *cn;
-    krb5_keyblock ke, ki;
+    krb5_key ke = NULL, ki = NULL;
 
     /* allocate and set up plaintext and to-be-derived keys */
 
     blocksize = enc->block_size;
     keybytes = enc->keybytes;
-    keylength = enc->keylength;
     plainlen = blocksize+input->length;
 
     krb5int_aes_encrypt_length(enc, hash, input->length, &enclen);
@@ -237,21 +224,10 @@
     if (output->length < enclen)
 	return KRB5_BAD_MSIZE;
 
-    kedata = k5alloc(keylength, &ret);
-    if (ret != 0)
-	goto cleanup;
-    kidata = k5alloc(keylength, &ret);
-    if (ret != 0)
-	goto cleanup;
-    plaintext = k5alloc(plainlen, &ret);
-    if (ret != 0)
-	goto cleanup;
+    plaintext = malloc(plainlen);
+    if (plaintext == NULL)
+	return ENOMEM;
 
-    ke.contents = kedata;
-    ke.length = keylength;
-    ki.contents = kidata;
-    ki.length = keylength;
-
     /* Derive the keys. */
 
     d1.data = (char *) constantdata;
@@ -294,7 +270,7 @@
     d2.length = plainlen;
     d2.data = output->data;
 
-    ret = (*enc->encrypt)(&ke, ivec, &d1, &d2);
+    ret = (*enc->encrypt)(ke, ivec, &d1, &d2);
     if (ret != 0)
 	goto cleanup;
 
@@ -311,7 +287,7 @@
     if (d2.length != 96 / 8)
 	abort();
 
-    ret = trunc_hmac(hash, &ki, 1, &d1, &d2);
+    ret = trunc_hmac(hash, ki, 1, &d1, &d2);
     if (ret != 0) {
 	memset(d2.data, 0, d2.length);
 	goto cleanup;
@@ -324,8 +300,8 @@
 	memcpy(ivec->data, cn, blocksize);
 
 cleanup:
-    zapfree(kedata, keylength);
-    zapfree(kidata, keylength);
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
     zapfree(plaintext, plainlen);
     return ret;
 }

Modified: trunk/src/lib/crypto/krb/dk/stringtokey.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/stringtokey.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/dk/stringtokey.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,15 +32,16 @@
 krb5_error_code
 krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
 			 const krb5_data *string, const krb5_data *salt,
-			 const krb5_data *parms, krb5_keyblock *key)
+			 const krb5_data *parms, krb5_keyblock *keyblock)
 {
     krb5_error_code ret;
     size_t keybytes, keylength, concatlen;
     unsigned char *concat = NULL, *foldstring = NULL, *foldkeydata = NULL;
     krb5_data indata;
-    krb5_keyblock foldkey;
+    krb5_keyblock foldkeyblock;
+    krb5_key foldkey = NULL;
 
-    /* key->length is checked by krb5_derive_key. */
+    /* keyblock->length is checked by krb5_derive_key. */
 
     keybytes = enc->keybytes;
     keylength = enc->keylength;
@@ -67,25 +68,30 @@
 
     indata.length = keybytes;
     indata.data = (char *) foldstring;
-    foldkey.length = keylength;
-    foldkey.contents = foldkeydata;
+    foldkeyblock.length = keylength;
+    foldkeyblock.contents = foldkeydata;
 
-    ret = (*enc->make_key)(&indata, &foldkey);
+    ret = (*enc->make_key)(&indata, &foldkeyblock);
     if (ret != 0)
 	goto cleanup;
 
+    ret = krb5_k_create_key(NULL, &foldkeyblock, &foldkey);
+    if (ret != 0)
+	goto cleanup;
+
     /* now derive the key from this one */
 
     indata.length = kerberos_len;
     indata.data = (char *) kerberos;
 
-    ret = krb5_derive_key(enc, &foldkey, key, &indata);
+    ret = krb5_derive_keyblock(enc, foldkey, keyblock, &indata);
     if (ret != 0)
-	memset(key->contents, 0, key->length);
+	memset(keyblock->contents, 0, keyblock->length);
 
 cleanup:
     zapfree(concat, concatlen);
     zapfree(foldstring, keybytes);
     zapfree(foldkeydata, keylength);
+    krb5_k_free_key(NULL, foldkey);
     return ret;
 }

Modified: trunk/src/lib/crypto/krb/encrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/encrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/encrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,19 +29,19 @@
 #include "aead.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_encrypt(krb5_context context, const krb5_keyblock *key,
+krb5_k_encrypt(krb5_context context, krb5_key key,
 	       krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_data *input, krb5_enc_data *output)
 {
     const struct krb5_keytypes *ktp;
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL)
 	return KRB5_BAD_ENCTYPE;
 
     output->magic = KV5M_ENC_DATA;
     output->kvno = 0;
-    output->enctype = key->enctype;
+    output->enctype = key->keyblock.enctype;
 
     if (ktp->encrypt == NULL) {
 	assert(ktp->aead != NULL);
@@ -54,3 +54,19 @@
     return (*ktp->encrypt)(ktp->enc, ktp->hash, key, usage, ivec, input,
 			   &output->ciphertext);
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_encrypt(krb5_context context, const krb5_keyblock *keyblock,
+	       krb5_keyusage usage, const krb5_data *ivec,
+	       const krb5_data *input, krb5_enc_data *output)
+{
+    krb5_key key;
+    krb5_error_code ret;
+
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_encrypt(context, key, usage, ivec, input, output);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/encrypt_iov.c
===================================================================
--- trunk/src/lib/crypto/krb/encrypt_iov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/encrypt_iov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -28,8 +28,8 @@
 #include "etypes.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_encrypt_iov(krb5_context context,
-		   const krb5_keyblock *key,
+krb5_k_encrypt_iov(krb5_context context,
+		   krb5_key key,
 		   krb5_keyusage usage,
 		   const krb5_data *cipher_state,
 		   krb5_crypto_iov *data,
@@ -37,7 +37,7 @@
 {
     const struct krb5_keytypes *ktp;
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL || ktp->aead == NULL)
 	return KRB5_BAD_ENCTYPE;
 
@@ -45,3 +45,22 @@
 				     key, usage, cipher_state, data, num_data);
 }
 
+krb5_error_code KRB5_CALLCONV
+krb5_c_encrypt_iov(krb5_context context,
+		   const krb5_keyblock *keyblock,
+		   krb5_keyusage usage,
+		   const krb5_data *cipher_state,
+		   krb5_crypto_iov *data,
+		   size_t num_data)
+{
+    krb5_key key;
+    krb5_error_code ret;
+
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_encrypt_iov(context, key, usage, cipher_state, data,
+			     num_data);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/etypes.h
===================================================================
--- trunk/src/lib/crypto/krb/etypes.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/etypes.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -33,7 +33,7 @@
 typedef krb5_error_code (*krb5_crypt_func)(const struct krb5_enc_provider *enc,
 					   const struct
 					   krb5_hash_provider *hash,
-					   const krb5_keyblock *key,
+					   krb5_key key,
 					   krb5_keyusage keyusage,
 					   const krb5_data *ivec,
 					   const krb5_data *input,
@@ -48,7 +48,7 @@
 
 typedef krb5_error_code (*krb5_prf_func)(const struct krb5_enc_provider *enc,
 					 const struct krb5_hash_provider *hash,
-					 const krb5_keyblock *key,
+					 krb5_key key,
 					 const krb5_data *in, krb5_data *out);
 
 struct krb5_keytypes {

Copied: trunk/src/lib/crypto/krb/key.c (from rev 22941, branches/enc-perf/src/lib/crypto/krb/key.c)

Modified: trunk/src/lib/crypto/krb/keyblocks.c
===================================================================
--- trunk/src/lib/crypto/krb/keyblocks.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/keyblocks.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -62,7 +62,6 @@
     return 0;
 }
 
-
 void 
 krb5int_c_free_keyblock(krb5_context context, register krb5_keyblock *val)
 {
@@ -78,3 +77,38 @@
 	key->contents = NULL;
     }
 }
+
+krb5_error_code
+krb5int_c_copy_keyblock(krb5_context context, const krb5_keyblock *from,
+			krb5_keyblock **to)
+{
+    krb5_keyblock *new_key;
+    krb5_error_code code;
+
+    *to = NULL;
+    new_key = malloc(sizeof(*new_key));
+    if (!new_key)
+	return ENOMEM;
+    code = krb5int_c_copy_keyblock_contents(context, from, new_key);
+    if (code) {
+	free(new_key);
+	return code;
+    }
+    *to = new_key;
+    return 0;
+}
+
+krb5_error_code
+krb5int_c_copy_keyblock_contents(krb5_context context,
+				 const krb5_keyblock *from, krb5_keyblock *to)
+{
+    *to = *from;
+    if (to->length) {
+        to->contents = malloc(to->length);
+        if (!to->contents)
+            return ENOMEM;
+        memcpy(to->contents, from->contents, to->length);
+    } else
+        to->contents = 0;
+    return 0;
+}

Modified: trunk/src/lib/crypto/krb/keyhash_provider/descbc.c
===================================================================
--- trunk/src/lib/crypto/krb/keyhash_provider/descbc.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/keyhash_provider/descbc.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,12 +29,12 @@
 #include "keyhash_provider.h"
 
 static krb5_error_code
-k5_descbc_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec,
+k5_descbc_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
 {
     mit_des_key_schedule schedule;
 
-    if (key->length != 8)
+    if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
     if ((input->length%8) != 0)
 	return(KRB5_BAD_MSIZE);
@@ -43,7 +43,7 @@
     if (output->length != 8)
 	return(KRB5_CRYPTO_INTERNAL);
 
-    switch (mit_des_key_sched(key->contents, schedule)) {
+    switch (mit_des_key_sched(key->keyblock.contents, schedule)) {
     case -1:
 	return(KRB5DES_BAD_KEYPAR);
     case -2:

Modified: trunk/src/lib/crypto/krb/keyhash_provider/hmac_md5.c
===================================================================
--- trunk/src/lib/crypto/krb/keyhash_provider/hmac_md5.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/keyhash_provider/hmac_md5.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -36,24 +36,23 @@
 #include "../aead.h"
 
 static  krb5_error_code
-k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage,
+k5_hmac_md5_hash (krb5_key key, krb5_keyusage usage,
 		  const krb5_data *iv,
 		  const krb5_data *input, krb5_data *output)
 {
   krb5_keyusage ms_usage;
   krb5_error_code ret;
-  krb5_keyblock ks;
+  krb5_keyblock keyblock;
+  krb5_key ks = NULL;
   krb5_data ds, ks_constant, md5tmp;
   krb5_MD5_CTX ctx;
   char t[4];
   
 
-  ds.length = key->length;
-  ks.length = key->length;
+  ds.length = key->keyblock.length;
   ds.data = malloc(ds.length);
   if (ds.data == NULL)
     return ENOMEM;
-  ks.contents = (void *) ds.data;
 
   ks_constant.data = "signaturekey";
   ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/
@@ -63,6 +62,12 @@
   if (ret)
     goto cleanup;
 
+  keyblock.length = key->keyblock.length;
+  keyblock.contents = (void *) ds.data;
+  ret = krb5_k_create_key(NULL, &keyblock, &ks);
+  if (ret)
+      goto cleanup;
+
   krb5_MD5Init (&ctx);
   ms_usage = krb5int_arcfour_translate_usage (usage);
   store_32_le(ms_usage, t);
@@ -72,36 +77,36 @@
   krb5_MD5Final(&ctx);
   md5tmp.data = (void *) ctx.digest;
   md5tmp.length = 16;
-  ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp,
+
+  ret = krb5_hmac ( &krb5int_hash_md5, ks, 1, &md5tmp,
 		    output);
 
     cleanup:
   memset(&ctx, 0, sizeof(ctx));
-  memset (ks.contents, 0, ks.length);
-  free (ks.contents);
+  zapfree(ds.data, ds.length);
+  krb5_k_free_key(NULL, ks);
   return ret;
 }
 
 static  krb5_error_code
-k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage,
+k5_hmac_md5_hash_iov (krb5_key key, krb5_keyusage usage,
 		      const krb5_data *iv,
 		      const krb5_crypto_iov *data, size_t num_data,
 		      krb5_data *output)
 {
   krb5_keyusage ms_usage;
   krb5_error_code ret;
-  krb5_keyblock ks;
+  krb5_keyblock keyblock;
+  krb5_key ks = NULL;
   krb5_data ds, ks_constant, md5tmp;
   krb5_MD5_CTX ctx;
   char t[4];
   size_t i;
 
-  ds.length = key->length;
-  ks.length = key->length;
+  ds.length = key->keyblock.length;
   ds.data = malloc(ds.length);
   if (ds.data == NULL)
     return ENOMEM;
-  ks.contents = (void *) ds.data;
 
   ks_constant.data = "signaturekey";
   ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/
@@ -111,6 +116,12 @@
   if (ret)
     goto cleanup;
 
+  keyblock.length = key->keyblock.length;
+  keyblock.contents = (void *) ds.data;
+  ret = krb5_k_create_key(NULL, &keyblock, &ks);
+  if (ret)
+      goto cleanup;
+
   krb5_MD5Init (&ctx);
   ms_usage = krb5int_arcfour_translate_usage (usage);
   store_32_le(ms_usage, t);
@@ -125,13 +136,13 @@
   krb5_MD5Final(&ctx);
   md5tmp.data = (void *) ctx.digest;
   md5tmp.length = 16;
-  ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp,
+  ret = krb5_hmac ( &krb5int_hash_md5, ks, 1, &md5tmp,
 		    output);
 
     cleanup:
   memset(&ctx, 0, sizeof(ctx));
-  memset (ks.contents, 0, ks.length);
-  free (ks.contents);
+  zapfree(keyblock.contents, keyblock.length);
+  krb5_k_free_key(NULL, ks);
   return ret;
 }
 

Modified: trunk/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
===================================================================
--- trunk/src/lib/crypto/krb/keyhash_provider/k5_md4des.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/keyhash_provider/k5_md4des.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -39,7 +39,7 @@
 extern struct krb5_enc_provider krb5int_enc_des;
 
 static krb5_error_code
-k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec,
+k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
 {
     krb5_error_code ret;
@@ -77,7 +77,7 @@
 }
 
 static krb5_error_code
-k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage,
+k5_md4des_verify(krb5_key key, krb5_keyusage usage,
 		 const krb5_data *ivec,
 		 const krb5_data *input, const krb5_data *hash,
 		 krb5_boolean *valid)
@@ -89,7 +89,7 @@
     struct krb5_enc_provider *enc = &krb5int_enc_des;
     krb5_data output, iv;
 
-    if (key->length != 8)
+    if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
     if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) {
 #ifdef KRB5_MD4DES_BETA5_COMPAT
@@ -104,11 +104,11 @@
     }
 
     if (compathash) {
-        iv.data = malloc(key->length);
+        iv.data = malloc(key->keyblock.length);
         if (!iv.data) return ENOMEM;
-        iv.length = key->length;
-        if (key->contents)
-            memcpy(iv.data, key->contents, key->length);
+        iv.length = key->keyblock.length;
+        if (key->keyblock.contents)
+            memcpy(iv.data, key->keyblock.contents, key->keyblock.length);
     }
 
     /* decrypt it */

Modified: trunk/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
===================================================================
--- trunk/src/lib/crypto/krb/keyhash_provider/k5_md5des.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/keyhash_provider/k5_md5des.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -39,7 +39,7 @@
 extern struct krb5_enc_provider krb5int_enc_des;
 
 static krb5_error_code
-k5_md5des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec,
+k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
 	       const krb5_data *input, krb5_data *output)
 {
     krb5_error_code ret;
@@ -78,7 +78,7 @@
 }
 
 static krb5_error_code
-k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec,
+k5_md5des_verify(krb5_key key, krb5_keyusage usage, const krb5_data *ivec,
 		 const krb5_data *input, const krb5_data *hash,
 		 krb5_boolean *valid)
 {
@@ -89,7 +89,7 @@
     struct krb5_enc_provider *enc = &krb5int_enc_des;
     krb5_data output, iv;
 
-    if (key->length != 8)
+    if (key->keyblock.length != 8)
 	return(KRB5_BAD_KEYSIZE);
 
     if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) {
@@ -104,11 +104,11 @@
     }
 
     if (compathash) {
-        iv.data = malloc(key->length);
+        iv.data = malloc(key->keyblock.length);
         if (!iv.data) return ENOMEM;
-        iv.length = key->length;
-        if (key->contents)
-            memcpy(iv.data, key->contents, key->length);
+        iv.length = key->keyblock.length;
+        if (key->keyblock.contents)
+            memcpy(iv.data, key->keyblock.contents, key->keyblock.length);
     }
 
     /* decrypt it */

Modified: trunk/src/lib/crypto/krb/keyhash_provider/md5_hmac.c
===================================================================
--- trunk/src/lib/crypto/krb/keyhash_provider/md5_hmac.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/keyhash_provider/md5_hmac.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -33,7 +33,7 @@
 #include "hash_provider.h"
 
 static  krb5_error_code
-k5_md5_hmac_hash (const krb5_keyblock *key, krb5_keyusage usage,
+k5_md5_hmac_hash (krb5_key key, krb5_keyusage usage,
 		  const krb5_data *iv,
 		  const krb5_data *input, krb5_data *output)
 {

Modified: trunk/src/lib/crypto/krb/make_checksum.c
===================================================================
--- trunk/src/lib/crypto/krb/make_checksum.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/make_checksum.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -30,8 +30,8 @@
 #include "dk.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
-		     const krb5_keyblock *key, krb5_keyusage usage,
+krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
+		     krb5_key key, krb5_keyusage usage,
 		     const krb5_data *input, krb5_checksum *cksum)
 {
     unsigned int i;
@@ -68,7 +68,7 @@
 	/* check if key is compatible */
 	if (ctp->keyed_etype) {
 	    ktp1 = find_enctype(ctp->keyed_etype);
-	    ktp2 = find_enctype(key->enctype);
+	    ktp2 = find_enctype(key->keyblock.enctype);
 	    if (ktp1 == NULL || ktp2 == NULL || ktp1->enc != ktp2->enc) {
 		ret = KRB5_BAD_ENCTYPE;
 		goto cleanup;
@@ -115,3 +115,21 @@
 
     return ret;
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
+		     const krb5_keyblock *keyblock, krb5_keyusage usage,
+		     const krb5_data *input, krb5_checksum *cksum)
+{
+    krb5_key key = NULL;
+    krb5_error_code ret;
+
+    if (keyblock != NULL) {
+	ret = krb5_k_create_key(context, keyblock, &key);
+	if (ret != 0)
+	    return ret;
+    }
+    ret = krb5_k_make_checksum(context, cksumtype, key, usage, input, cksum);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/make_checksum_iov.c
===================================================================
--- trunk/src/lib/crypto/krb/make_checksum_iov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/make_checksum_iov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,9 +29,9 @@
 #include "aead.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_make_checksum_iov(krb5_context context,
+krb5_k_make_checksum_iov(krb5_context context,
 			 krb5_cksumtype cksumtype,
-			 const krb5_keyblock *key,
+			 krb5_key key,
 			 krb5_keyusage usage,
 			 krb5_crypto_iov *data,
 			 size_t num_data)
@@ -81,3 +81,23 @@
 
     return(ret);
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_make_checksum_iov(krb5_context context,
+			 krb5_cksumtype cksumtype,
+			 const krb5_keyblock *keyblock,
+			 krb5_keyusage usage,
+			 krb5_crypto_iov *data,
+			 size_t num_data)
+{
+    krb5_key key;
+    krb5_error_code ret;
+
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_make_checksum_iov(context, cksumtype, key, usage,
+				   data, num_data);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/old/old.h
===================================================================
--- trunk/src/lib/crypto/krb/old/old.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/old/old.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -34,14 +34,14 @@
 krb5_error_code krb5_old_encrypt
 (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, krb5_keyusage usage,
+		krb5_key key, krb5_keyusage usage,
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *output);
 
 krb5_error_code krb5_old_decrypt
 (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, krb5_keyusage usage,
+		krb5_key key, krb5_keyusage usage,
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *arg_output);
 

Modified: trunk/src/lib/crypto/krb/old/old_decrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/old/old_decrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/old/old_decrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -30,7 +30,7 @@
 krb5_error_code
 krb5_old_decrypt(const struct krb5_enc_provider *enc,
 		 const struct krb5_hash_provider *hash,
-		 const krb5_keyblock *key,
+		 krb5_key key,
 		 krb5_keyusage usage,
 		 const krb5_data *ivec,
 		 const krb5_data *input,
@@ -87,9 +87,9 @@
 	cn = NULL;
 
     /* XXX this is gross, but I don't have much choice */
-    if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
-	crcivec.length = key->length;
-	crcivec.data = (char *) key->contents;
+    if ((key->keyblock.enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
+	crcivec.length = key->keyblock.length;
+	crcivec.data = (char *) key->keyblock.contents;
 	ivec = &crcivec;
     }
 

Modified: trunk/src/lib/crypto/krb/old/old_encrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/old/old_encrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/old/old_encrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -44,7 +44,7 @@
 krb5_error_code
 krb5_old_encrypt(const struct krb5_enc_provider *enc,
 		 const struct krb5_hash_provider *hash,
-		 const krb5_keyblock *key,
+		 krb5_key key,
 		 krb5_keyusage usage,
 		 const krb5_data *ivec,
 		 const krb5_data *input,
@@ -87,9 +87,9 @@
     /* encrypt it */
 
     /* XXX this is gross, but I don't have much choice */
-    if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
-	crcivec.length = key->length;
-	crcivec.data = (char *) key->contents;
+    if ((key->keyblock.enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
+	crcivec.length = key->keyblock.length;
+	crcivec.data = (char *) key->keyblock.contents;
 	ivec = &crcivec;
 	real_ivec = 0;
     } else

Modified: trunk/src/lib/crypto/krb/prf/des_prf.c
===================================================================
--- trunk/src/lib/crypto/krb/prf/des_prf.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/prf/des_prf.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -35,8 +35,7 @@
 krb5_error_code
 krb5int_des_prf (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key,
-		const krb5_data *in, krb5_data *out)
+		krb5_key key, const krb5_data *in, krb5_data *out)
 {
   krb5_data tmp;
   krb5_error_code ret = 0;

Modified: trunk/src/lib/crypto/krb/prf/dk_prf.c
===================================================================
--- trunk/src/lib/crypto/krb/prf/dk_prf.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/prf/dk_prf.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -35,12 +35,11 @@
 krb5_error_code
 krb5int_dk_prf (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key,
-		const krb5_data *in, krb5_data *out)
+		krb5_key key, const krb5_data *in, krb5_data *out)
 {
   krb5_data tmp;
   krb5_data prfconst;
-  krb5_keyblock *kp = NULL;
+  krb5_key kp = NULL;
   krb5_error_code ret = 0;
   
   prfconst.data = (char *) "prf";
@@ -51,14 +50,10 @@
     return ENOMEM;
   hash->hash(1, in, &tmp);
   tmp.length = (tmp.length/enc->block_size)*enc->block_size; /*truncate to block size*/
-  ret = krb5int_c_init_keyblock(0, key->enctype,
-			   key->length, &kp);
-    if (ret == 0)
-      ret = krb5_derive_key(enc, key, kp, &prfconst);
+  ret = krb5_derive_key(enc, key, &kp, &prfconst);
   if (ret == 0)
-    ret = enc->encrypt(kp, NULL, &tmp, out);
-      if (kp)
-	krb5int_c_free_keyblock(0, kp);
+      ret = enc->encrypt(kp, NULL, &tmp, out);
+  krb5_k_free_key(NULL, kp);
   free (tmp.data);
   return ret;
 }

Modified: trunk/src/lib/crypto/krb/prf/prf_int.h
===================================================================
--- trunk/src/lib/crypto/krb/prf/prf_int.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/prf/prf_int.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,19 +32,17 @@
 krb5_error_code 
 krb5int_arcfour_prf(const struct krb5_enc_provider *enc,
                     const struct krb5_hash_provider *hash,
-                    const krb5_keyblock *key,
-                    const krb5_data *in, krb5_data *out);
+                    krb5_key key, const krb5_data *in, krb5_data *out);
 
 krb5_error_code
 krb5int_des_prf (const struct krb5_enc_provider *enc,
                 const struct krb5_hash_provider *hash,
-                const krb5_keyblock *key,
-                 const krb5_data *in, krb5_data *out);
+                krb5_key key, const krb5_data *in, krb5_data *out);
 
 krb5_error_code
 krb5int_dk_prf(const struct krb5_enc_provider *enc,
                const struct krb5_hash_provider *hash,
-               const krb5_keyblock *key, const krb5_data *in, krb5_data *out);
+               krb5_key key, const krb5_data *in, krb5_data *out);
 
 #endif  /*PRF_INTERNAL_DEFS*/
 

Modified: trunk/src/lib/crypto/krb/prf/rc4_prf.c
===================================================================
--- trunk/src/lib/crypto/krb/prf/rc4_prf.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/prf/rc4_prf.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,8 +32,7 @@
 krb5_error_code 
 krb5int_arcfour_prf(const struct krb5_enc_provider *enc,
                     const struct krb5_hash_provider *hash,
-                    const krb5_keyblock *key,
-                    const krb5_data *in, krb5_data *out)
+                    krb5_key key, const krb5_data *in, krb5_data *out)
 {
     assert(out->length == 20);
     return krb5_hmac(&krb5int_hash_sha1, key, 1, in, out);

Modified: trunk/src/lib/crypto/krb/prf.c
===================================================================
--- trunk/src/lib/crypto/krb/prf.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/prf.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -50,15 +50,17 @@
 }
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_prf(krb5_context context, const krb5_keyblock *key,
+krb5_c_prf(krb5_context context, const krb5_keyblock *keyblock,
 	   krb5_data *input, krb5_data *output)
 {
     const struct krb5_keytypes *ktp;
+    krb5_key key;
+    krb5_error_code ret;
 
     assert(input && output);
     assert(output->data);
 
-    ktp = find_enctype(key->enctype);
+    ktp = find_enctype(keyblock->enctype);
     if (ktp == NULL)
 	return KRB5_BAD_ENCTYPE;
     if (ktp->prf == NULL)
@@ -67,5 +69,10 @@
     output->magic = KV5M_DATA;
     if (ktp->prf_length != output->length)
 	return KRB5_CRYPTO_INTERNAL;
-    return (*ktp->prf)(ktp->enc, ktp->hash, key, input, output);
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = (*ktp->prf)(ktp->enc, ktp->hash, key, input, output);
+    krb5_k_free_key(context, key);
+    return ret;
 }

Modified: trunk/src/lib/crypto/krb/raw/raw.h
===================================================================
--- trunk/src/lib/crypto/krb/raw/raw.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/raw/raw.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -34,14 +34,14 @@
 krb5_error_code krb5_raw_encrypt
 (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, krb5_keyusage usage,
+		krb5_key key, krb5_keyusage usage,
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *output);
 
 krb5_error_code krb5_raw_decrypt
 (const struct krb5_enc_provider *enc,
 		const struct krb5_hash_provider *hash,
-		const krb5_keyblock *key, krb5_keyusage usage,
+		krb5_key key, krb5_keyusage usage,
 		const krb5_data *ivec, const krb5_data *input,
 		krb5_data *arg_output);
 

Modified: trunk/src/lib/crypto/krb/raw/raw_aead.c
===================================================================
--- trunk/src/lib/crypto/krb/raw/raw_aead.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/raw/raw_aead.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -54,7 +54,7 @@
 krb5int_raw_encrypt_iov(const struct krb5_aead_provider *aead,
 			const struct krb5_enc_provider *enc,
 			const struct krb5_hash_provider *hash,
-			const krb5_keyblock *key,
+			krb5_key key,
 			krb5_keyusage usage,
 			const krb5_data *ivec,
 			krb5_crypto_iov *data,
@@ -104,7 +104,7 @@
 krb5int_raw_decrypt_iov(const struct krb5_aead_provider *aead,
 			const struct krb5_enc_provider *enc,
 			const struct krb5_hash_provider *hash,
-			const krb5_keyblock *key,
+			krb5_key key,
 			krb5_keyusage usage,
 			const krb5_data *ivec,
 			krb5_crypto_iov *data,

Modified: trunk/src/lib/crypto/krb/raw/raw_decrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/raw/raw_decrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/raw/raw_decrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -30,7 +30,7 @@
 krb5_error_code
 krb5_raw_decrypt(const struct krb5_enc_provider *enc,
 		 const struct krb5_hash_provider *hash,
-		 const krb5_keyblock *key, krb5_keyusage usage,
+		 krb5_key key, krb5_keyusage usage,
 		 const krb5_data *ivec, const krb5_data *input,
 		 krb5_data *output)
 {

Modified: trunk/src/lib/crypto/krb/raw/raw_encrypt.c
===================================================================
--- trunk/src/lib/crypto/krb/raw/raw_encrypt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/raw/raw_encrypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -42,7 +42,7 @@
 krb5_error_code
 krb5_raw_encrypt(const struct krb5_enc_provider *enc,
 		 const struct krb5_hash_provider *hash,
-		 const krb5_keyblock *key, krb5_keyusage usage,
+		 krb5_key key, krb5_keyusage usage,
 		 const krb5_data *ivec, const krb5_data *input,
 		 krb5_data *output)
 {

Modified: trunk/src/lib/crypto/krb/verify_checksum.c
===================================================================
--- trunk/src/lib/crypto/krb/verify_checksum.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/verify_checksum.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -28,7 +28,7 @@
 #include "cksumtypes.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key,
+krb5_k_verify_checksum(krb5_context context, krb5_key key,
 		       krb5_keyusage usage, const krb5_data *data,
 		       const krb5_checksum *cksum, krb5_boolean *valid)
 {
@@ -79,7 +79,7 @@
 
     computed.length = hashsize;
 
-    ret = krb5_c_make_checksum(context, cksum->checksum_type, key, usage,
+    ret = krb5_k_make_checksum(context, cksum->checksum_type, key, usage,
 			       data, &computed);
     if (ret)
 	return ret;
@@ -89,3 +89,21 @@
     free(computed.contents);
     return 0;
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *keyblock,
+		       krb5_keyusage usage, const krb5_data *data,
+		       const krb5_checksum *cksum, krb5_boolean *valid)
+{
+    krb5_key key = NULL;
+    krb5_error_code ret;
+
+    if (keyblock != NULL) {
+	ret = krb5_k_create_key(context, keyblock, &key);
+	if (ret != 0)
+	    return ret;
+    }
+    ret = krb5_k_verify_checksum(context, key, usage, data, cksum, valid);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/verify_checksum_iov.c
===================================================================
--- trunk/src/lib/crypto/krb/verify_checksum_iov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/verify_checksum_iov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -29,9 +29,9 @@
 #include "aead.h"
 
 krb5_error_code KRB5_CALLCONV
-krb5_c_verify_checksum_iov(krb5_context context, 
+krb5_k_verify_checksum_iov(krb5_context context,
 			   krb5_cksumtype checksum_type,
-			   const krb5_keyblock *key,
+			   krb5_key key,
 			   krb5_keyusage usage,
 			   const krb5_crypto_iov *data,
 			   size_t num_data,
@@ -94,3 +94,24 @@
     free(computed.data);
     return 0;
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_verify_checksum_iov(krb5_context context,
+			   krb5_cksumtype checksum_type,
+			   const krb5_keyblock *keyblock,
+			   krb5_keyusage usage,
+			   const krb5_crypto_iov *data,
+			   size_t num_data,
+			   krb5_boolean *valid)
+{
+    krb5_key key;
+    krb5_error_code ret;
+
+    ret = krb5_k_create_key(context, keyblock, &key);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_verify_checksum_iov(context, checksum_type, key, usage, data,
+				     num_data, valid);
+    krb5_k_free_key(context, key);
+    return ret;
+}

Modified: trunk/src/lib/crypto/krb/yarrow/ycipher.c
===================================================================
--- trunk/src/lib/crypto/krb/yarrow/ycipher.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/yarrow/ycipher.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -42,27 +42,28 @@
   const struct krb5_enc_provider *enc = &yarrow_enc_provider;
   krb5_error_code ret;
   krb5_data randombits;
+  krb5_keyblock keyblock;
+
   keybytes = enc->keybytes;
   keylength = enc->keylength;
   assert (keybytes == CIPHER_KEY_SIZE);
-  if (ctx->key.contents) {
-    memset (ctx->key.contents, 0, ctx->key.length);
-    free (ctx->key.contents);
-  }
-  ctx->key.contents = (void *) malloc  (keylength);
-  ctx->key.length = keylength;
-  if (ctx->key.contents == NULL)
+  krb5_k_free_key(NULL, ctx->key);
+  ctx->key = NULL;
+  keyblock.contents = malloc(keylength);
+  keyblock.length = keylength;
+  if (keyblock.contents == NULL)
     return (YARROW_NOMEM);
   randombits.data = (char *) key;
   randombits.length = keybytes;
-  ret = enc->make_key (&randombits, &ctx->key);
-  if (ret) {
-    memset (ctx->key.contents, 0, ctx->key.length);
-    free(ctx->key.contents);
-    ctx->key.contents = NULL;
-    return (YARROW_FAIL);
-  }
-  return (YARROW_OK);
+  ret = enc->make_key(&randombits, &keyblock);
+  if (ret != 0)
+      goto cleanup;
+  ret = krb5_k_create_key(NULL, &keyblock, &ctx->key);
+cleanup:
+  free(keyblock.contents);
+  if (ret)
+    return YARROW_FAIL;
+  return YARROW_OK;
 }
 
 int krb5int_yarrow_cipher_encrypt_block
@@ -76,7 +77,7 @@
   ind.length = CIPHER_BLOCK_SIZE;
   outd.data = (char *) out;
   outd.length = CIPHER_BLOCK_SIZE;
-  ret = enc->encrypt (&ctx->key, 0, &ind, &outd);
+  ret = enc->encrypt(ctx->key, 0, &ind, &outd);
   if (ret)
     return YARROW_FAIL;
   return YARROW_OK;
@@ -87,10 +88,6 @@
 (CIPHER_CTX *ctx)
 
 {
- if (ctx->key.contents) {
-    memset (ctx->key.contents, 0, ctx->key.length);
-    free (ctx->key.contents);
-  }
-  ctx->key.contents = 0;
-  ctx->key.length = 0;
+  krb5_k_free_key(NULL, ctx->key);
+  ctx->key = NULL;
 }

Modified: trunk/src/lib/crypto/krb/yarrow/ycipher.h
===================================================================
--- trunk/src/lib/crypto/krb/yarrow/ycipher.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/krb/yarrow/ycipher.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -7,7 +7,7 @@
 
 typedef struct 
 {
-    krb5_keyblock key;
+    krb5_key key;
 } CIPHER_CTX;
 
 /* We need to choose a cipher. To do this, choose an enc_provider.

Modified: trunk/src/lib/crypto/libk5crypto.exports
===================================================================
--- trunk/src/lib/crypto/libk5crypto.exports	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/libk5crypto.exports	2009-10-19 20:04:21 UTC (rev 22944)
@@ -72,6 +72,18 @@
 krb5_free_cksumtypes
 krb5_hmac
 krb5_init_random_key
+krb5_k_create_key
+krb5_k_decrypt
+krb5_k_decrypt_iov
+krb5_k_encrypt
+krb5_k_encrypt_iov
+krb5_k_free_key
+krb5_k_key_enctype
+krb5_k_key_keyblock
+krb5_k_make_checksum
+krb5_k_make_checksum_iov
+krb5_k_verify_checksum
+krb5_k_verify_checksum_iov
 krb5_nfold
 krb5_old_decrypt
 krb5_old_encrypt
@@ -100,6 +112,8 @@
 krb5int_arcfour_string_to_key
 krb5int_arcfour_translate_usage
 krb5int_c_combine_keys
+krb5int_c_copy_keyblock
+krb5int_c_copy_keyblock_contents
 krb5int_c_free_keyblock
 krb5int_c_free_keyblock_contents
 krb5int_c_init_keyblock
@@ -122,6 +136,7 @@
 krb5int_hash_md4
 krb5int_hash_md5
 krb5int_hash_sha1
+krb5int_hmac_keyblock
 krb5int_keyhash_descbc
 krb5int_keyhash_hmac_md5
 krb5int_keyhash_md4des

Modified: trunk/src/lib/crypto/openssl/aes/aes_s2k.c
===================================================================
--- trunk/src/lib/crypto/openssl/aes/aes_s2k.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/aes/aes_s2k.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -44,6 +44,7 @@
     unsigned long iter_count;
     krb5_data out;
     static const krb5_data usage = { KV5M_DATA, 8, "kerberos" };
+    krb5_key tempkey = NULL;
     krb5_error_code err;
 
     if (params) {
@@ -66,25 +67,25 @@
     if (iter_count >= MAX_ITERATION_COUNT)
 	return KRB5_ERR_BAD_S2K_PARAMS;
 
-    /*
-     * Dense key space, no parity bits or anything, so take a shortcut
-     * and use the key contents buffer for the generated bytes.
-     */
+    /* Use the output keyblock contents for temporary space. */
     out.data = (char *) key->contents;
     out.length = key->length;
     if (out.length != 16 && out.length != 32)
 	return KRB5_CRYPTO_INTERNAL;
 
     err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt);
-    if (err) {
-	memset(out.data, 0, out.length);
-	return err;
-    }
+    if (err)
+	goto cleanup;
 
-    err = krb5_derive_key (enc, key, key, &usage);
-    if (err) {
-	memset(out.data, 0, out.length);
-	return err;
-    }
-    return 0;
+    err = krb5_k_create_key (NULL, key, &tempkey);
+    if (err)
+	goto cleanup;
+
+    err = krb5_derive_keyblock (enc, tempkey, key, &usage);
+
+cleanup:
+    if (err)
+	memset (out.data, 0, out.length);
+    krb5_k_free_key (NULL, tempkey);
+    return err;
 }

Modified: trunk/src/lib/crypto/openssl/arcfour/arcfour.c
===================================================================
--- trunk/src/lib/crypto/openssl/arcfour/arcfour.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/arcfour/arcfour.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -65,11 +65,12 @@
 krb5_error_code
 krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
 		     const struct krb5_hash_provider *hash,
-		     const krb5_keyblock *key, krb5_keyusage usage,
+		     krb5_key key, krb5_keyusage usage,
 		     const krb5_data *ivec, const krb5_data *input,
 		     krb5_data *output)
 {
   krb5_keyblock k1, k2, k3;
+  krb5_key k3key = NULL;
   krb5_data d1, d2, d3, salt, plaintext, checksum, ciphertext, confounder;
   krb5_keyusage ms_usage;
   size_t keylength, keybytes, blocksize, hashsize;
@@ -84,7 +85,7 @@
   d1.data=malloc(d1.length);
   if (d1.data == NULL)
     return (ENOMEM);
-  k1 = *key;
+  k1 = key->keyblock;
   k1.length=d1.length;
   k1.contents= (void *) d1.data;
 
@@ -94,7 +95,7 @@
     free(d1.data);
     return (ENOMEM);
   }
-  k2 = *key;
+  k2 = key->keyblock;
   k2.length=d2.length;
   k2.contents=(void *) d2.data;
 
@@ -105,7 +106,7 @@
     free(d2.data);
     return (ENOMEM);
   }
-  k3 = *key;
+  k3 = key->keyblock;
   k3.length=d3.length;
   k3.contents= (void *) d3.data;
 
@@ -141,7 +142,7 @@
 
   /* begin the encryption, computer K1 */
   ms_usage=krb5int_arcfour_translate_usage(usage);
-  if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+  if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
     strncpy(salt.data, krb5int_arcfour_l40, salt.length);
     store_32_le(ms_usage, salt.data+10);
   } else {
@@ -152,7 +153,7 @@
 
   memcpy(k2.contents, k1.contents, k2.length);
 
-  if (key->enctype==ENCTYPE_ARCFOUR_HMAC_EXP)
+  if (key->keyblock.enctype==ENCTYPE_ARCFOUR_HMAC_EXP)
     memset(k1.contents+7, 0xab, 9);
 
   ret=krb5_c_random_make_octets(/* XXX */ 0, &confounder);
@@ -160,12 +161,20 @@
   if (ret)
     goto cleanup;
 
-  krb5_hmac(hash, &k2, 1, &plaintext, &checksum);
+  ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum);
+  if (ret)
+    goto cleanup;
 
-  krb5_hmac(hash, &k1, 1, &checksum, &d3);
+  ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
+  if (ret)
+    goto cleanup;
 
-  ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext);
+  ret = krb5_k_create_key(NULL, &k3, &k3key);
+  if (ret)
+    goto cleanup;
 
+  ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext);
+
  cleanup:
   memset(d1.data, 0, d1.length);
   memset(d2.data, 0, d2.length);
@@ -185,11 +194,12 @@
 krb5_error_code
 krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
 		     const struct krb5_hash_provider *hash,
-		     const krb5_keyblock *key, krb5_keyusage usage,
+		     krb5_key key, krb5_keyusage usage,
 		     const krb5_data *ivec, const krb5_data *input,
 		     krb5_data *output)
 {
   krb5_keyblock k1,k2,k3;
+  krb5_key k3key;
   krb5_data d1,d2,d3,salt,ciphertext,plaintext,checksum;
   krb5_keyusage ms_usage;
   size_t keybytes, keylength, hashsize, blocksize;
@@ -204,7 +214,7 @@
   d1.data=malloc(d1.length);
   if (d1.data == NULL)
     return (ENOMEM);
-  k1 = *key;
+  k1 = key->keyblock;
   k1.length=d1.length;
   k1.contents= (void *) d1.data;
 
@@ -214,7 +224,7 @@
     free(d1.data);
     return (ENOMEM);
   }
-  k2 = *key;
+  k2 = key->keyblock;
   k2.length=d2.length;
   k2.contents= (void *) d2.data;
 
@@ -225,7 +235,7 @@
     free(d2.data);
     return (ENOMEM);
   }
-  k3 = *key;
+  k3 = key->keyblock;
   k3.length=d3.length;
   k3.contents= (void *) d3.data;
 
@@ -258,7 +268,7 @@
   /* We may have to try two ms_usage values; see below. */
   do {
       /* compute the salt */
-      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+      if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
 	  strncpy(salt.data, krb5int_arcfour_l40, salt.length);
 	  store_32_le(ms_usage, salt.data + 10);
       } else {
@@ -271,18 +281,22 @@
 
       memcpy(k2.contents, k1.contents, k2.length);
 
-      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+      if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
 	  memset(k1.contents + 7, 0xab, 9);
 
-      ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+      ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
       if (ret)
 	  goto cleanup;
 
-      ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
+      ret = krb5_k_create_key(NULL, &k3, &k3key);
       if (ret)
+	goto cleanup;
+      ret = (*(enc->decrypt))(k3key, ivec, &ciphertext, &plaintext);
+      krb5_k_free_key(NULL, k3key);
+      if (ret)
 	  goto cleanup;
 
-      ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1);
+      ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &d1);
       if (ret)
 	  goto cleanup;
 

Modified: trunk/src/lib/crypto/openssl/arcfour/arcfour.h
===================================================================
--- trunk/src/lib/crypto/openssl/arcfour/arcfour.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/arcfour/arcfour.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -10,7 +10,7 @@
 extern 
 krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *,
 			const struct krb5_hash_provider *,
-			const krb5_keyblock *,
+			krb5_key,
 			krb5_keyusage,
 			const krb5_data *,
      			const krb5_data *,
@@ -19,7 +19,7 @@
 extern 
 krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *,
 			const struct krb5_hash_provider *,
-			const krb5_keyblock *,
+			krb5_key,
 			krb5_keyusage,
 			const krb5_data *,
 			const krb5_data *,
@@ -34,10 +34,5 @@
 
 extern const struct krb5_enc_provider krb5int_enc_arcfour;
 extern const struct krb5_aead_provider krb5int_aead_arcfour;
- krb5_error_code krb5int_arcfour_prf(
-					 const struct krb5_enc_provider *enc,
-					 const struct krb5_hash_provider *hash,
-					 const krb5_keyblock *key,
-					 const krb5_data *in, krb5_data *out);
 
 #endif /* ARCFOUR_H */

Modified: trunk/src/lib/crypto/openssl/arcfour/arcfour_aead.c
===================================================================
--- trunk/src/lib/crypto/openssl/arcfour/arcfour_aead.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/arcfour/arcfour_aead.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -82,7 +82,7 @@
 krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
 			    const struct krb5_enc_provider *enc,
 			    const struct krb5_hash_provider *hash,
-			    const krb5_keyblock *key,
+			    krb5_key key,
 			    krb5_keyusage usage,
 			    const krb5_data *ivec,
 			    krb5_crypto_iov *data,
@@ -91,6 +91,7 @@
     krb5_error_code ret;
     krb5_crypto_iov *header, *trailer;
     krb5_keyblock k1, k2, k3;
+    krb5_key k3key = NULL;
     krb5_data d1, d2, d3;
     krb5_data checksum, confounder, header_data;
     krb5_keyusage ms_usage;
@@ -126,15 +127,15 @@
 	    data[i].data.length = 0;
     }
 
-    ret = alloc_derived_key(enc, &k1, &d1, key);
+    ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k2, &d2, key);
+    ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k3, &d3, key);
+    ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
@@ -144,7 +145,7 @@
 
     ms_usage = krb5int_arcfour_translate_usage(usage);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
 	strncpy(salt.data, krb5int_arcfour_l40, salt.length);
 	store_32_le(ms_usage, salt.data + 10);
     } else {
@@ -157,7 +158,7 @@
 
     memcpy(k2.contents, k1.contents, k2.length);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
 	memset(k1.contents + 7, 0xAB, 9);
 
     header->data.length = hash->hashsize + CONFOUNDERLENGTH;
@@ -176,18 +177,22 @@
     header->data.length -= hash->hashsize;
     header->data.data   += hash->hashsize;
 
-    ret = krb5int_hmac_iov(hash, &k2, data, num_data, &checksum);
+    ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &checksum);
     if (ret != 0)
 	goto cleanup;
 
-    ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+    ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
     if (ret != 0)
 	goto cleanup;
 
-    ret = enc->encrypt_iov(&k3, ivec, data, num_data);
+    ret = krb5_k_create_key(NULL, &k3, &k3key);
     if (ret != 0)
 	goto cleanup;
 
+    ret = enc->encrypt_iov(k3key, ivec, data, num_data);
+    if (ret != 0)
+	goto cleanup;
+
 cleanup:
     header->data = header_data; /* restore header pointers */
 
@@ -204,6 +209,7 @@
 	free(d3.data);
     }
 
+    krb5_k_free_key(NULL, k3key);
     return ret;
 }
 
@@ -211,7 +217,7 @@
 krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
 			    const struct krb5_enc_provider *enc,
 			    const struct krb5_hash_provider *hash,
-			    const krb5_keyblock *key,
+			    krb5_key key,
 			    krb5_keyusage usage,
 			    const krb5_data *ivec,
 			    krb5_crypto_iov *data,
@@ -220,6 +226,7 @@
     krb5_error_code ret;
     krb5_crypto_iov *header, *trailer;
     krb5_keyblock k1, k2, k3;
+    krb5_key k3key = NULL;
     krb5_data d1, d2, d3;
     krb5_data checksum, header_data;
     krb5_keyusage ms_usage;
@@ -240,15 +247,15 @@
     if (trailer != NULL && trailer->data.length != 0)
 	return KRB5_BAD_MSIZE;
     
-    ret = alloc_derived_key(enc, &k1, &d1, key);
+    ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k2, &d2, key);
+    ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
-    ret = alloc_derived_key(enc, &k3, &d3, key);
+    ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock);
     if (ret != 0)
 	goto cleanup;
 
@@ -258,7 +265,7 @@
 
     ms_usage = krb5int_arcfour_translate_usage(usage);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
 	strncpy(salt.data, krb5int_arcfour_l40, salt.length);
 	store_32_le(ms_usage, (unsigned char *)salt.data + 10);
     } else {
@@ -271,7 +278,7 @@
 
     memcpy(k2.contents, k1.contents, k2.length);
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
 	memset(k1.contents + 7, 0xAB, 9);
 
     checksum.data = header->data.data;
@@ -281,18 +288,22 @@
     header->data.length -= hash->hashsize;
     header->data.data   += hash->hashsize;
 
-    ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+    ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
     if (ret != 0)
 	goto cleanup;
 
-    ret = enc->decrypt_iov(&k3, ivec, data, num_data);
+    ret = krb5_k_create_key(NULL, &k3, &k3key);
     if (ret != 0)
 	goto cleanup;
 
-    ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1);
+    ret = enc->decrypt_iov(k3key, ivec, data, num_data);
     if (ret != 0)
 	goto cleanup;
 
+    ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1);
+    if (ret != 0)
+	goto cleanup;
+
     if (memcmp(checksum.data, d1.data, hash->hashsize) != 0) {
 	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
 	goto cleanup;
@@ -314,6 +325,7 @@
 	free(d3.data);
     }
 
+    krb5_k_free_key(NULL, k3key);
     return ret;
 }
 

Modified: trunk/src/lib/crypto/openssl/enc_provider/aes.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/aes.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/enc_provider/aes.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -36,22 +36,22 @@
 
 /* proto's */
 static krb5_error_code
-cts_enc(const krb5_keyblock *key, const krb5_data *ivec,
+cts_enc(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output);
 static krb5_error_code
-cbc_enc(const krb5_keyblock *key, const krb5_data *ivec,
+cbc_enc(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output);
 static krb5_error_code
-cts_decr(const krb5_keyblock *key, const krb5_data *ivec,
+cts_decr(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output);
 static krb5_error_code
-cbc_decr(const krb5_keyblock *key, const krb5_data *ivec,
+cbc_decr(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output);
 static krb5_error_code
-cts_encr_iov(const krb5_keyblock *key, const krb5_data *ivec,
+cts_encr_iov(krb5_key key, const krb5_data *ivec,
                     krb5_crypto_iov *data, size_t num_data, size_t dlen);
 static krb5_error_code
-cts_decr_iov(const krb5_keyblock *key, const krb5_data *ivec,
+cts_decr_iov(krb5_key key, const krb5_data *ivec,
                     krb5_crypto_iov *data, size_t num_data, size_t dlen);
 
 #define NUM_BITS 8
@@ -69,7 +69,7 @@
 }
 
 static krb5_error_code
-cbc_enc(const krb5_keyblock *key, const krb5_data *ivec,
+cbc_enc(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     int             ret = 0, tmp_len = 0;
@@ -77,7 +77,7 @@
     unsigned char  *tmp_buf = NULL;
     EVP_CIPHER_CTX  ciph_ctx;
 
-    key_buf = OPENSSL_malloc(key->length);
+    key_buf = OPENSSL_malloc(key->keyblock.length);
     if (!key_buf)
         return ENOMEM;
 
@@ -87,11 +87,11 @@
         OPENSSL_free(key_buf);
         return ENOMEM;
     }
-    memcpy(key_buf, key->contents, key->length);
+    memcpy(key_buf, key->keyblock.contents, key->keyblock.length);
 
     EVP_CIPHER_CTX_init(&ciph_ctx);
 
-    ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->length),
+    ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length),
                   NULL, key_buf, (ivec) ? (unsigned char*)ivec->data : NULL);
 
     if (ret == 1){
@@ -112,7 +112,7 @@
         ret = KRB5_CRYPTO_INTERNAL;
     }
 
-    memset(key_buf, 0, key->length);
+    memset(key_buf, 0, key->keyblock.length);
     memset(tmp_buf, 0, input->length);
     OPENSSL_free(key_buf);
     OPENSSL_free(tmp_buf);
@@ -121,7 +121,7 @@
 }
 
 static krb5_error_code
-cbc_decr(const krb5_keyblock *key, const krb5_data *ivec,
+cbc_decr(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     int              ret = 0, tmp_len = 0;
@@ -129,7 +129,7 @@
     unsigned char   *tmp_buf = NULL;
     EVP_CIPHER_CTX   ciph_ctx;
 
-    key_buf = OPENSSL_malloc(key->length);
+    key_buf = OPENSSL_malloc(key->keyblock.length);
     if (!key_buf)
         return ENOMEM;
 
@@ -139,11 +139,11 @@
         OPENSSL_free(key_buf);
         return ENOMEM;
     }
-    memcpy(key_buf, key->contents, key->length);
+    memcpy(key_buf, key->keyblock.contents, key->keyblock.length);
 
     EVP_CIPHER_CTX_init(&ciph_ctx);
 
-    ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->length),
+    ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length),
                   NULL, key_buf, (ivec) ? (unsigned char*)ivec->data : NULL);
     if (ret == 1) {
         EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); 
@@ -164,7 +164,7 @@
         ret = KRB5_CRYPTO_INTERNAL;
     }
 
-    memset(key_buf, 0, key->length);
+    memset(key_buf, 0, key->keyblock.length);
     memset(tmp_buf, 0, input->length);
     OPENSSL_free(key_buf);
     OPENSSL_free(tmp_buf);
@@ -173,7 +173,7 @@
 }
 
 static krb5_error_code
-cts_enc(const krb5_keyblock *key, const krb5_data *ivec,
+cts_enc(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     int             ret = 0, tmp_len = 0;
@@ -194,7 +194,8 @@
         return ENOMEM;
     tmp_len = input->length;
 
-    AES_set_encrypt_key(key->contents, NUM_BITS * key->length, &enck);
+    AES_set_encrypt_key(key->keyblock.contents,
+			NUM_BITS * key->keyblock.length, &enck);
 
     size = CRYPTO_cts128_encrypt((unsigned char *)input->data, tmp_buf,
                                  input->length, &enck,
@@ -217,7 +218,7 @@
 }
 
 static krb5_error_code
-cts_decr(const krb5_keyblock *key, const krb5_data *ivec,
+cts_decr(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     int    ret = 0, tmp_len = 0;
@@ -238,7 +239,8 @@
         return ENOMEM;
     tmp_len = input->length;
 
-    AES_set_decrypt_key(key->contents, NUM_BITS * key->length, &deck);
+    AES_set_decrypt_key(key->keyblock.contents,
+			NUM_BITS * key->keyblock.length, &deck);
 
     size = CRYPTO_cts128_decrypt((unsigned char *)input->data, tmp_buf,
                                  input->length, &deck,
@@ -261,7 +263,7 @@
 }
 
 static krb5_error_code
-cts_encr_iov(const krb5_keyblock *key,
+cts_encr_iov(krb5_key key,
 		        const krb5_data *ivec,
 		        krb5_crypto_iov *data,
 		        size_t num_data, size_t dlen)
@@ -313,7 +315,8 @@
         if (tlen > dlen) break;
     }
 
-    AES_set_encrypt_key(key->contents, NUM_BITS * key->length, &enck);
+    AES_set_encrypt_key(key->keyblock.contents,
+			NUM_BITS * key->keyblock.length, &enck);
 
     size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck,
                                  iv_cts, (cbc128_f)AES_cbc_encrypt);
@@ -336,7 +339,7 @@
 }
 
 static krb5_error_code
-cts_decr_iov(const krb5_keyblock *key,
+cts_decr_iov(krb5_key key,
 		        const krb5_data *ivec,
 		        krb5_crypto_iov *data,
 		        size_t num_data, size_t dlen)
@@ -373,7 +376,8 @@
     memset(oblock, 0, oblock_len);
     memset(dbuf, 0, dlen);
 
-    AES_set_decrypt_key(key->contents, NUM_BITS * key->length, &deck);
+    AES_set_decrypt_key(key->keyblock.contents,
+			NUM_BITS * key->keyblock.length, &deck);
 
     tlen = 0;
     for (;;) {
@@ -411,7 +415,7 @@
 }
 
 krb5_error_code
-krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     int  ret = 0;
@@ -426,7 +430,7 @@
 }
 
 krb5_error_code
-krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec,
 		    const krb5_data *input, krb5_data *output)
 {
     int ret = 0;
@@ -445,7 +449,7 @@
 }
 
 static krb5_error_code
-krb5int_aes_encrypt_iov(const krb5_keyblock *key,
+krb5int_aes_encrypt_iov(krb5_key key,
 		        const krb5_data *ivec,
 		        krb5_crypto_iov *data,
 		        size_t num_data)
@@ -470,7 +474,7 @@
 }
 
 static krb5_error_code
-krb5int_aes_decrypt_iov(const krb5_keyblock *key,
+krb5int_aes_decrypt_iov(krb5_key key,
 		        const krb5_data *ivec,
 		        krb5_crypto_iov *data,
 		        size_t num_data)

Modified: trunk/src/lib/crypto/openssl/enc_provider/des.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/des.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/enc_provider/des.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -11,11 +11,11 @@
 #define DES_KEY_BYTES   7
 
 static krb5_error_code
-validate(const krb5_keyblock *key, const krb5_data *ivec,
+validate(krb5_key key, const krb5_data *ivec,
                       const krb5_data *input, const krb5_data *output)
 {
-    /* key->enctype was checked by the caller */
-    if (key->length != KRB5_MIT_DES_KEYSIZE)
+    /* key->keyblock.enctype was checked by the caller */
+    if (key->keyblock.length != KRB5_MIT_DES_KEYSIZE)
         return(KRB5_BAD_KEYSIZE);
     if ((input->length%8) != 0)
         return(KRB5_BAD_MSIZE);
@@ -28,7 +28,7 @@
 }
 
 static krb5_error_code
-validate_iov(const krb5_keyblock *key, const krb5_data *ivec,
+validate_iov(krb5_key key, const krb5_data *ivec,
                           const krb5_crypto_iov *data, size_t num_data)
 {
     size_t i, input_length;
@@ -39,7 +39,7 @@
             input_length += iov->data.length;
     }
 
-    if (key->length != KRB5_MIT_DES3_KEYSIZE)
+    if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE)
         return(KRB5_BAD_KEYSIZE);
     if ((input_length%DES_BLOCK_SIZE) != 0)
         return(KRB5_BAD_MSIZE);
@@ -50,7 +50,7 @@
 }
 
 static krb5_error_code
-k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des_encrypt(krb5_key key, const krb5_data *ivec,
            const krb5_data *input, krb5_data *output)
 {
     int              ret = 0, tmp_len = 0;
@@ -63,8 +63,8 @@
     if (ret)
         return ret;
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     tmp_buf_len = output->length*2;
     tmp_buf=OPENSSL_malloc(tmp_buf_len);
@@ -103,10 +103,10 @@
 
 
 static krb5_error_code
-k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des_decrypt(krb5_key key, const krb5_data *ivec,
            const krb5_data *input, krb5_data *output)
 {
-    /* key->enctype was checked by the caller */
+    /* key->keyblock.enctype was checked by the caller */
     int              ret = 0, tmp_len = 0;
     unsigned char   *keybuf  = NULL;
     unsigned char   *tmp_buf;
@@ -116,8 +116,8 @@
     if (ret)
         return ret;
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     tmp_buf=OPENSSL_malloc(output->length);
     if (!tmp_buf)
@@ -152,7 +152,7 @@
 }
 
 static krb5_error_code
-k5_des_encrypt_iov(const krb5_keyblock *key,
+k5_des_encrypt_iov(krb5_key key,
             const krb5_data *ivec,
             krb5_crypto_iov *data,
             size_t num_data)
@@ -176,8 +176,8 @@
     IOV_BLOCK_STATE_INIT(&input_pos);
     IOV_BLOCK_STATE_INIT(&output_pos);
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     ret = validate_iov(key, ivec, data, num_data);
     if (ret)
@@ -229,7 +229,7 @@
 }
 
 static krb5_error_code
-k5_des_decrypt_iov(const krb5_keyblock *key,
+k5_des_decrypt_iov(krb5_key key,
            const krb5_data *ivec,
            krb5_crypto_iov *data,
            size_t num_data)
@@ -254,8 +254,8 @@
     IOV_BLOCK_STATE_INIT(&input_pos);
     IOV_BLOCK_STATE_INIT(&output_pos);
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     ret = validate_iov(key, ivec, data, num_data);
     if (ret)

Modified: trunk/src/lib/crypto/openssl/enc_provider/des3.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/des3.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/enc_provider/des3.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -11,12 +11,12 @@
 #define DES_BLOCK_SIZE  8
 
 static krb5_error_code
-validate(const krb5_keyblock *key, const krb5_data *ivec,
+validate(krb5_key key, const krb5_data *ivec,
 		      const krb5_data *input, const krb5_data *output)
 {
-    /* key->enctype was checked by the caller */
+    /* key->keyblock.enctype was checked by the caller */
 
-    if (key->length != KRB5_MIT_DES3_KEYSIZE)
+    if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE)
 	return(KRB5_BAD_KEYSIZE);
     if ((input->length%DES_BLOCK_SIZE) != 0)
 	return(KRB5_BAD_MSIZE);
@@ -29,7 +29,7 @@
 }
 
 static krb5_error_code
-validate_iov(const krb5_keyblock *key, const krb5_data *ivec,
+validate_iov(krb5_key key, const krb5_data *ivec,
 			  const krb5_crypto_iov *data, size_t num_data)
 {
     size_t i, input_length;
@@ -40,7 +40,7 @@
 	    input_length += iov->data.length;
     }
 
-    if (key->length != KRB5_MIT_DES3_KEYSIZE)
+    if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE)
 	return(KRB5_BAD_KEYSIZE);
     if ((input_length%DES_BLOCK_SIZE) != 0)
 	return(KRB5_BAD_MSIZE);
@@ -51,7 +51,7 @@
 }
 
 static krb5_error_code
-k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des3_encrypt(krb5_key key, const krb5_data *ivec,
 		const krb5_data *input, krb5_data *output)
 {
     int              ret = 0, tmp_len = 0;
@@ -64,8 +64,8 @@
     if (ret)
 	return ret;
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     tmp_buf_len = output->length * 2;
     tmp_buf = OPENSSL_malloc(tmp_buf_len);
@@ -104,7 +104,7 @@
 }
 
 static krb5_error_code
-k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
+k5_des3_decrypt(krb5_key key, const krb5_data *ivec,
 		const krb5_data *input, krb5_data *output)
 {
     int              ret = 0, tmp_len = 0;
@@ -117,8 +117,8 @@
     if (ret)
 	return ret;
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     tmp_buf_len = output->length;
     tmp_buf=OPENSSL_malloc(tmp_buf_len);
@@ -156,7 +156,7 @@
 }
 
 static krb5_error_code
-k5_des3_encrypt_iov(const krb5_keyblock *key,
+k5_des3_encrypt_iov(krb5_key key,
 		    const krb5_data *ivec,
 		    krb5_crypto_iov *data,
 		    size_t num_data)
@@ -185,8 +185,8 @@
     IOV_BLOCK_STATE_INIT(&input_pos);
     IOV_BLOCK_STATE_INIT(&output_pos);
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     memset(oblock, 0, oblock_len);
 
@@ -236,7 +236,7 @@
 }
 
 static krb5_error_code
-k5_des3_decrypt_iov(const krb5_keyblock *key,
+k5_des3_decrypt_iov(krb5_key key,
 		    const krb5_data *ivec,
 		    krb5_crypto_iov *data,
 		    size_t num_data)
@@ -265,8 +265,8 @@
     IOV_BLOCK_STATE_INIT(&input_pos);
     IOV_BLOCK_STATE_INIT(&output_pos);
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     memset(oblock, 0, oblock_len);
 

Modified: trunk/src/lib/crypto/openssl/enc_provider/rc4.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/rc4.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/enc_provider/rc4.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -15,7 +15,7 @@
 
 /* prototypes */
 static krb5_error_code
-k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *,
+k5_arcfour_docrypt(krb5_key, const krb5_data *,
            const krb5_data *, krb5_data *);
 static krb5_error_code 
 k5_arcfour_free_state ( krb5_data *state);
@@ -29,7 +29,7 @@
 
 /* In-place rc4 crypto */
 static krb5_error_code
-k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
+k5_arcfour_docrypt(krb5_key key, const krb5_data *state,
            const krb5_data *input, krb5_data *output)
 {
     int ret = 0, tmp_len = 0;
@@ -37,14 +37,14 @@
     unsigned char   *tmp_buf = NULL;
     EVP_CIPHER_CTX  ciph_ctx;
 
-    if (key->length != RC4_KEY_SIZE)
+    if (key->keyblock.length != RC4_KEY_SIZE)
         return(KRB5_BAD_KEYSIZE);
 
     if (input->length != output->length)
         return(KRB5_BAD_MSIZE);
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     EVP_CIPHER_CTX_init(&ciph_ctx);
 
@@ -72,7 +72,7 @@
 
 /* In-place IOV crypto */
 static krb5_error_code
-k5_arcfour_docrypt_iov(const krb5_keyblock *key,
+k5_arcfour_docrypt_iov(krb5_key key,
                const krb5_data *state,
                krb5_crypto_iov *data,
                size_t num_data)
@@ -84,8 +84,8 @@
     krb5_crypto_iov *iov     = NULL;
     EVP_CIPHER_CTX  ciph_ctx;
 
-    keybuf=key->contents;
-    keybuf[key->length] = '\0';
+    keybuf=key->keyblock.contents;
+    keybuf[key->keyblock.length] = '\0';
 
     EVP_CIPHER_CTX_init(&ciph_ctx);
 

Modified: trunk/src/lib/crypto/openssl/hmac.c
===================================================================
--- trunk/src/lib/crypto/openssl/hmac.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/crypto/openssl/hmac.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,8 +32,9 @@
 }
 
 krb5_error_code
-krb5_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key,
-          unsigned int icount, const krb5_data *input, krb5_data *output)
+krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
+		      const krb5_keyblock *key, unsigned int icount,
+		      const krb5_data *input, krb5_data *output)
 {
     unsigned int i = 0, md_len = 0; 
     unsigned char md[EVP_MAX_MD_SIZE];
@@ -72,8 +73,10 @@
 }
 
 krb5_error_code
-krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key,
-                 const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+krb5int_hmac_iov_keyblock(const struct krb5_hash_provider *hash,
+                          const krb5_keyblock *key,
+                          const krb5_crypto_iov *data, size_t num_data,
+                          krb5_data *output)
 {
     krb5_data *sign_data;
     size_t num_sign_data;
@@ -101,10 +104,25 @@
     }
 
     /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */
-    ret = krb5_hmac(hash, key, num_sign_data, sign_data, output);
+    ret = krb5int_hmac_keyblock(hash, key, num_sign_data, sign_data, output);
 
     free(sign_data);
 
     return ret;
 }
 
+krb5_error_code
+krb5_hmac(const struct krb5_hash_provider *hash, krb5_key key,
+         unsigned int icount, const krb5_data *input, krb5_data *output)
+{
+    return krb5int_hmac_keyblock(hash, &key->keyblock, icount, input, output);
+}
+
+krb5_error_code
+krb5int_hmac_iov(const struct krb5_hash_provider *hash, krb5_key key,
+                const krb5_crypto_iov *data, size_t num_data,
+                krb5_data *output)
+{
+    return krb5int_hmac_iov_keyblock(hash, &key->keyblock, data, num_data,
+                                    output);
+}

Modified: trunk/src/lib/gssapi/krb5/accept_sec_context.c
===================================================================
--- trunk/src/lib/gssapi/krb5/accept_sec_context.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/accept_sec_context.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -437,6 +437,7 @@
     int no_encap = 0;
     krb5_flags ap_req_options = 0;
     krb5_enctype negotiated_etype;
+    krb5_keyblock *keyblock = NULL;
     krb5_authdata_context ad_context = NULL;
 
     code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
@@ -883,22 +884,21 @@
     krb5_auth_con_set_authdata_context(context, auth_context, NULL);
 
     if ((code = krb5_auth_con_getrecvsubkey(context, auth_context,
-                                            &ctx->subkey))) {
+                                            &keyblock))) {
         major_status = GSS_S_FAILURE;
         goto fail;
     }
 
     /* use the session key if the subkey isn't present */
 
-    if (ctx->subkey == NULL) {
-        if ((code = krb5_auth_con_getkey(context, auth_context,
-                                         &ctx->subkey))) {
+    if (keyblock == NULL) {
+        if ((code = krb5_auth_con_getkey(context, auth_context, &keyblock))) {
             major_status = GSS_S_FAILURE;
             goto fail;
         }
     }
 
-    if (ctx->subkey == NULL) {
+    if (keyblock == NULL) {
         /* this isn't a very good error, but it's not clear to me this
            can actually happen */
         major_status = GSS_S_FAILURE;
@@ -906,6 +906,12 @@
         goto fail;
     }
 
+    code = krb5_k_create_key(context, keyblock, &ctx->subkey);
+    if (code) {
+        major_status = GSS_S_FAILURE;
+        goto fail;
+    }
+
     ctx->enc = NULL;
     ctx->seq = NULL;
     ctx->have_acceptor_subkey = 0;
@@ -1033,12 +1039,19 @@
             /* Get the new acceptor subkey.  With the code above, there
                should always be one if we make it to this point.  */
             code = krb5_auth_con_getsendsubkey(context, auth_context,
-                                               &ctx->acceptor_subkey);
+                                               &keyblock);
             if (code != 0) {
                 major_status = GSS_S_FAILURE;
                 goto fail;
             }
+            code = krb5_k_create_key(context, keyblock, &ctx->acceptor_subkey);
+            if (code != 0) {
+                major_status = GSS_S_FAILURE;
+                goto fail;
+            }
             ctx->have_acceptor_subkey = 1;
+            krb5_free_keyblock(context, keyblock);
+            keyblock = NULL;
 
             code = kg_setup_keys(context, ctx, ctx->acceptor_subkey,
                                  &ctx->acceptor_subkey_cksumtype);
@@ -1150,6 +1163,8 @@
         xfree(reqcksum.contents);
     if (ap_rep.data)
         krb5_free_data_contents(context, &ap_rep);
+    if (keyblock)
+        krb5_free_keyblock(context, keyblock);
     if (major_status == GSS_S_COMPLETE ||
         (major_status == GSS_S_CONTINUE_NEEDED && code != KRB5KRB_AP_ERR_MSG_TYPE)) {
         ctx->k5_context = context;

Modified: trunk/src/lib/gssapi/krb5/delete_sec_context.c
===================================================================
--- trunk/src/lib/gssapi/krb5/delete_sec_context.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/delete_sec_context.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -82,19 +82,19 @@
         g_order_free(&(ctx->seqstate));
 
     if (ctx->enc)
-        krb5_free_keyblock(context, ctx->enc);
+        krb5_k_free_key(context, ctx->enc);
 
     if (ctx->seq)
-        krb5_free_keyblock(context, ctx->seq);
+        krb5_k_free_key(context, ctx->seq);
 
     if (ctx->here)
         kg_release_name(context, 0, &ctx->here);
     if (ctx->there)
         kg_release_name(context, 0, &ctx->there);
     if (ctx->subkey)
-        krb5_free_keyblock(context, ctx->subkey);
+        krb5_k_free_key(context, ctx->subkey);
     if (ctx->acceptor_subkey)
-        krb5_free_keyblock(context, ctx->acceptor_subkey);
+        krb5_k_free_key(context, ctx->acceptor_subkey);
 
     if (ctx->auth_context) {
         if (ctx->cred_rcache)

Modified: trunk/src/lib/gssapi/krb5/gssapiP_krb5.h
===================================================================
--- trunk/src/lib/gssapi/krb5/gssapiP_krb5.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/gssapiP_krb5.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -190,15 +190,14 @@
     unsigned char seed[16];
     krb5_gss_name_t here;
     krb5_gss_name_t there;
-    krb5_keyblock *subkey; /*One of two potential keys to use with RFC
-                            * 4121 packets; this key must always be set.*/
+    krb5_key subkey; /* One of two potential keys to use with RFC 4121
+                      * packets; this key must always be set. */
     int signalg;
     size_t cksum_size;
     int sealalg;
-    krb5_keyblock *enc; /*RFC 1964 encryption key;seq xored with a
-                         *                           constant for DES,
-                         * seq for other RFC 1964 enctypes  */ 
-  krb5_keyblock *seq; /*RFC 1964 sequencing key*/
+    krb5_key enc; /* RFC 1964 encryption key; seq xored with a constant
+                   * for DES, seq for other RFC 1964 enctypes  */
+    krb5_key seq; /* RFC 1964 sequencing key */
     krb5_ticket_times krb_times;
     krb5_flags krb_flags;
     /* XXX these used to be signed.  the old spec is inspecific, and
@@ -218,7 +217,7 @@
        1964 tokens is permitted.*/
     int proto;
     krb5_cksumtype cksumtype;    /* for "main" subkey */
-    krb5_keyblock *acceptor_subkey; /* CFX only */
+    krb5_key acceptor_subkey; /* CFX only */
     krb5_cksumtype acceptor_subkey_cksumtype;
     int cred_rcache;             /* did we get rcache from creds? */
     krb5_authdata **authdata;
@@ -259,32 +258,32 @@
  int bigend);
 
 krb5_error_code kg_make_seq_num (krb5_context context,
-                                 krb5_keyblock *key,
+                                 krb5_key key,
                                  int direction, krb5_ui_4 seqnum, unsigned char *cksum,
                                  unsigned char *buf);
 
 krb5_error_code kg_get_seq_num (krb5_context context,
-                                krb5_keyblock *key,
+                                krb5_key key,
                                 unsigned char *cksum, unsigned char *buf, int *direction,
                                 krb5_ui_4 *seqnum);
 
 krb5_error_code kg_make_seed (krb5_context context,
-                              krb5_keyblock *key,
+                              krb5_key key,
                               unsigned char *seed);
 
 krb5_error_code
 kg_setup_keys(krb5_context context,
               krb5_gss_ctx_id_rec *ctx,
-              krb5_keyblock *subkey,
+              krb5_key subkey,
               krb5_cksumtype *cksumtype);
 
-int kg_confounder_size (krb5_context context, krb5_keyblock *key);
+int kg_confounder_size (krb5_context context, krb5_key key);
 
 krb5_error_code kg_make_confounder (krb5_context context,
-                                    krb5_keyblock *key, unsigned char *buf);
+                                    krb5_key key, unsigned char *buf);
 
 krb5_error_code kg_encrypt (krb5_context context,
-                            krb5_keyblock *key, int usage,
+                            krb5_key key, int usage,
                             krb5_pointer iv,
                             krb5_const_pointer in,
                             krb5_pointer out,
@@ -293,7 +292,7 @@
 krb5_error_code kg_encrypt_iov (krb5_context context,
                                 int proto, int dce_style,
                                 size_t ec, size_t rrc,
-                                krb5_keyblock *key, int usage,
+                                krb5_key key, int usage,
                                 krb5_pointer iv,
                                 gss_iov_buffer_desc *iov,
                                 int iov_count);
@@ -312,7 +311,7 @@
                         int iov_count);
 
 krb5_error_code kg_decrypt (krb5_context context,
-                            krb5_keyblock *key,  int usage,
+                            krb5_key key,  int usage,
                             krb5_pointer iv,
                             krb5_const_pointer in,
                             krb5_pointer out,
@@ -321,7 +320,7 @@
 krb5_error_code kg_decrypt_iov (krb5_context context,
                                 int proto, int dce_style,
                                 size_t ec, size_t rrc,
-                                krb5_keyblock *key,  int usage,
+                                krb5_key key,  int usage,
                                 krb5_pointer iv,
                                 gss_iov_buffer_desc *iov,
                                 int iov_count);
@@ -409,8 +408,8 @@
 krb5_error_code kg_make_checksum_iov_v1(krb5_context context,
                 krb5_cksumtype type,
                 size_t token_cksum_len,
-                krb5_keyblock *seq,
-                krb5_keyblock *enc, /* for conf len */
+                krb5_key seq,
+                krb5_key enc, /* for conf len */
                 krb5_keyusage sign_usage,
                 gss_iov_buffer_desc *iov,
                 int iov_count,
@@ -420,7 +419,7 @@
 krb5_error_code kg_make_checksum_iov_v3(krb5_context context,
                 krb5_cksumtype type,
                 size_t rrc,
-                krb5_keyblock *key,
+                krb5_key key,
                 krb5_keyusage sign_usage,
                 gss_iov_buffer_desc *iov,
                 int iov_count);
@@ -428,7 +427,7 @@
 krb5_error_code kg_verify_checksum_iov_v3(krb5_context context,
                 krb5_cksumtype type,
                 size_t rrc,
-                krb5_keyblock *key,
+                krb5_key key,
                 krb5_keyusage sign_usage,
                 gss_iov_buffer_desc *iov,
                 int iov_count,

Modified: trunk/src/lib/gssapi/krb5/init_sec_context.c
===================================================================
--- trunk/src/lib/gssapi/krb5/init_sec_context.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/init_sec_context.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -482,6 +482,7 @@
     krb5_gss_ctx_id_rec *ctx, *ctx_free;
     krb5_timestamp now;
     gss_buffer_desc token;
+    krb5_keyblock *keyblock;
 
     k5_mutex_assert_locked(&cred->lock);
     major_status = GSS_S_FAILURE;
@@ -602,8 +603,14 @@
 
         krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp);
         ctx->seq_send = seq_temp;
-        krb5_auth_con_getsendsubkey(context, ctx->auth_context,
-                                    &ctx->subkey);
+        code = krb5_auth_con_getsendsubkey(context, ctx->auth_context,
+                                           &keyblock);
+        if (code != 0)
+            goto fail;
+        code = krb5_k_create_key(context, keyblock, &ctx->subkey);
+        krb5_free_keyblock(context, keyblock);
+        if (code != 0)
+            goto fail;
     }
 
     krb5_free_creds(context, k_cred);
@@ -668,7 +675,7 @@
         if (ctx_free->there)
             kg_release_name(context, 0, &ctx_free->there);
         if (ctx_free->subkey)
-            krb5_free_keyblock(context, ctx_free->subkey);
+            krb5_k_free_key(context, ctx_free->subkey);
         xfree(ctx_free);
     } else
         (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
@@ -797,7 +804,7 @@
          * To be removed in 1999 -- proven
          */
         krb5_auth_con_setuseruserkey(context, ctx->auth_context,
-                                     ctx->subkey);
+                                     &ctx->subkey->keyblock);
         if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
                          &ap_rep_data)))
             goto fail;
@@ -811,11 +818,11 @@
 
     if (ap_rep_data->subkey != NULL &&
         (ctx->proto == 1 || (ctx->gss_flags & GSS_C_DCE_STYLE) ||
-         ap_rep_data->subkey->enctype != ctx->subkey->enctype)) {
+         ap_rep_data->subkey->enctype != ctx->subkey->keyblock.enctype)) {
         /* Keep acceptor's subkey.  */
         ctx->have_acceptor_subkey = 1;
-        code = krb5_copy_keyblock(context, ap_rep_data->subkey,
-                                  &ctx->acceptor_subkey);
+        code = krb5_k_create_key(context, ap_rep_data->subkey,
+                                 &ctx->acceptor_subkey);
         if (code) {
             krb5_free_ap_rep_enc_part(context, ap_rep_data);
             goto fail;

Modified: trunk/src/lib/gssapi/krb5/inq_context.c
===================================================================
--- trunk/src/lib/gssapi/krb5/inq_context.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/inq_context.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -187,7 +187,7 @@
     gss_buffer_set_t *data_set)
 {
     krb5_gss_ctx_id_rec *ctx;
-    krb5_keyblock *key;
+    krb5_key key;
     gss_buffer_desc keyvalue, keyinfo;
     OM_uint32 major_status, minor;
     unsigned char oid_buf[GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH + 6];
@@ -196,8 +196,8 @@
     ctx = (krb5_gss_ctx_id_rec *) context_handle;
     key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey;
 
-    keyvalue.value = key->contents;
-    keyvalue.length = key->length;
+    keyvalue.value = key->keyblock.contents;
+    keyvalue.length = key->keyblock.length;
 
     major_status = generic_gss_add_buffer_set_member(minor_status, &keyvalue, data_set);
     if (GSS_ERROR(major_status))
@@ -209,7 +209,7 @@
     major_status = generic_gss_oid_compose(minor_status,
                                            GSS_KRB5_SESSION_KEY_ENCTYPE_OID,
                                            GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH,
-                                           key->enctype,
+                                           key->keyblock.enctype,
                                            &oid);
     if (GSS_ERROR(major_status))
         goto cleanup;

Modified: trunk/src/lib/gssapi/krb5/k5seal.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5seal.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/k5seal.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -53,8 +53,8 @@
 
 static krb5_error_code
 make_seal_token_v1 (krb5_context context,
-                    krb5_keyblock *enc,
-                    krb5_keyblock *seq,
+                    krb5_key enc,
+                    krb5_key seq,
                     gssint_uint64 *seqnum,
                     int direction,
                     gss_buffer_t text,
@@ -197,7 +197,7 @@
         (void) memcpy(data_ptr+8, plain, msglen);
     plaind.length = 8 + (bigend ? text->length : msglen);
     plaind.data = data_ptr;
-    code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+    code = krb5_k_make_checksum(context, md5cksum.checksum_type, seq,
                                 sign_usage, &plaind, &md5cksum);
     xfree(data_ptr);
 
@@ -212,7 +212,7 @@
 
         if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL,
                                (g_OID_equal(oid, gss_mech_krb5_old) ?
-                                seq->contents : NULL),
+                                seq->keyblock.contents : NULL),
                                md5cksum.contents, md5cksum.contents, 16))) {
             krb5_free_checksum_contents(context, &md5cksum);
             xfree (plain);
@@ -259,7 +259,7 @@
             krb5_keyblock *enc_key;
             int i;
             store_32_be(*seqnum, bigend_seqnum);
-            code = krb5_copy_keyblock (context, enc, &enc_key);
+            code = krb5_k_key_keyblock(context, enc, &enc_key);
             if (code)
             {
                 xfree(plain);

Modified: trunk/src/lib/gssapi/krb5/k5sealiov.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5sealiov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/k5sealiov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -193,7 +193,7 @@
     case SGN_ALG_3:
         code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
                           (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
-                           ctx->seq->contents : NULL),
+                           ctx->seq->keyblock.contents : NULL),
                           md5cksum.contents, md5cksum.contents, 16);
         if (code != 0)
             goto cleanup;
@@ -226,7 +226,7 @@
 
             store_32_be(ctx->seq_send, bigend_seqnum);
 
-            code = krb5_copy_keyblock(context, ctx->enc, &enc_key);
+            code = krb5_k_key_keyblock(context, ctx->enc, &enc_key);
             if (code != 0)
                 goto cleanup;
 
@@ -408,13 +408,12 @@
     gss_headerlen = gss_padlen = gss_trailerlen = 0;
 
     if (ctx->proto == 1) {
+        krb5_key key;
         krb5_enctype enctype;
         size_t ec;
 
-        if (ctx->have_acceptor_subkey)
-            enctype = ctx->acceptor_subkey->enctype;
-        else
-            enctype = ctx->subkey->enctype;
+        key = (ctx->have_acceptor_subkey) ? ctx->acceptor_subkey : ctx->subkey;
+        enctype = key->keyblock.enctype;
 
         code = krb5_c_crypto_length(context, enctype,
                                     conf_req_flag ?

Modified: trunk/src/lib/gssapi/krb5/k5sealv3.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5sealv3.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/k5sealv3.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -81,7 +81,7 @@
     size_t ec;
     unsigned short tok_id;
     krb5_checksum sum;
-    krb5_keyblock *key;
+    krb5_key key;
     krb5_cksumtype cksumtype;
 
     assert(ctx->big_endian == 0);
@@ -136,7 +136,7 @@
             return ENOMEM;
 
         /* Get size of ciphertext.  */
-        bufsize = 16 + krb5_encrypt_size (plain.length, key->enctype);
+        bufsize = 16 + krb5_encrypt_size (plain.length, key->keyblock.enctype);
         /* Allocate space for header plus encrypted data.  */
         outbuf = malloc(bufsize);
         if (outbuf == NULL) {
@@ -164,8 +164,8 @@
 
         cipher.ciphertext.data = (char *)outbuf + 16;
         cipher.ciphertext.length = bufsize - 16;
-        cipher.enctype = key->enctype;
-        err = krb5_c_encrypt(context, key, key_usage, 0, &plain, &cipher);
+        cipher.enctype = key->keyblock.enctype;
+        err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher);
         zap(plain.data, plain.length);
         free(plain.data);
         plain.data = 0;
@@ -245,7 +245,7 @@
         sum.contents = outbuf + 16 + message2->length;
         sum.length = cksumsize;
 
-        err = krb5_c_make_checksum(context, cksumtype, key,
+        err = krb5_k_make_checksum(context, cksumtype, key,
                                    key_usage, &plain, &sum);
         zap(plain.data, plain.length);
         free(plain.data);
@@ -317,7 +317,7 @@
     krb5_checksum sum;
     krb5_error_code err;
     krb5_boolean valid;
-    krb5_keyblock *key;
+    krb5_key key;
     krb5_cksumtype cksumtype;
 
     if (ctx->big_endian != 0)
@@ -398,14 +398,14 @@
 
             For all current cryptosystems, the ciphertext size will
             be larger than the plaintext size.  */
-            cipher.enctype = key->enctype;
+            cipher.enctype = key->keyblock.enctype;
             cipher.ciphertext.length = bodysize - 16;
             cipher.ciphertext.data = (char *)ptr + 16;
             plain.length = bodysize - 16;
             plain.data = malloc(plain.length);
             if (plain.data == NULL)
                 goto no_mem;
-            err = krb5_c_decrypt(context, key, key_usage, 0,
+            err = krb5_k_decrypt(context, key, key_usage, 0,
                                  &cipher, &plain);
             if (err) {
                 free(plain.data);
@@ -459,7 +459,7 @@
             }
             sum.contents = ptr+bodysize-ec;
             sum.checksum_type = cksumtype;
-            err = krb5_c_verify_checksum(context, key, key_usage,
+            err = krb5_k_verify_checksum(context, key, key_usage,
                                          &plain, &sum, &valid);
             if (err)
                 goto error;
@@ -496,7 +496,7 @@
         sum.length = bodysize - 16;
         sum.contents = ptr + 16;
         sum.checksum_type = cksumtype;
-        err = krb5_c_verify_checksum(context, key, key_usage,
+        err = krb5_k_verify_checksum(context, key, key_usage,
                                      &plain, &sum, &valid);
         free(plain.data);
         plain.data = NULL;

Modified: trunk/src/lib/gssapi/krb5/k5sealv3iov.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5sealv3iov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/k5sealv3iov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -53,7 +53,7 @@
     int key_usage;
     size_t rrc = 0;
     unsigned int  gss_headerlen, gss_trailerlen;
-    krb5_keyblock *key;
+    krb5_key key;
     krb5_cksumtype cksumtype;
     size_t data_length, assoc_data_length;
 
@@ -95,24 +95,26 @@
         size_t ec = 0;
         size_t conf_data_length = data_length - assoc_data_length;
 
-        code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
+        code = krb5_c_crypto_length(context, key->keyblock.enctype,
+                                    KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
         if (code != 0)
             goto cleanup;
 
-        code = krb5_c_padding_length(context, key->enctype,
+        code = krb5_c_padding_length(context, key->keyblock.enctype,
                                      conf_data_length + 16 /* E(Header) */, &k5_padlen);
         if (code != 0)
             goto cleanup;
 
         if (k5_padlen == 0 && (ctx->gss_flags & GSS_C_DCE_STYLE)) {
             /* Windows rejects AEAD tokens with non-zero EC */
-            code = krb5_c_block_size(context, key->enctype, &ec);
+            code = krb5_c_block_size(context, key->keyblock.enctype, &ec);
             if (code != 0)
                 goto cleanup;
         } else
             ec = k5_padlen;
 
-        code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
+        code = krb5_c_crypto_length(context, key->keyblock.enctype,
+                                    KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
         if (code != 0)
             goto cleanup;
 
@@ -186,7 +188,9 @@
 
         gss_headerlen = 16;
 
-        code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &gss_trailerlen);
+        code = krb5_c_crypto_length(context, key->keyblock.enctype,
+                                    KRB5_CRYPTO_TYPE_CHECKSUM,
+                                    &gss_trailerlen);
         if (code != 0)
             goto cleanup;
 
@@ -291,7 +295,7 @@
     int key_usage;
     size_t rrc, ec;
     size_t data_length, assoc_data_length;
-    krb5_keyblock *key;
+    krb5_key key;
     gssint_uint64 seqnum;
     krb5_boolean valid;
     krb5_cksumtype cksumtype;
@@ -357,7 +361,7 @@
         rrc = load_16_be(ptr + 6);
         seqnum = load_64_be(ptr + 8);
 
-        code = krb5_c_crypto_length(context, key->enctype,
+        code = krb5_c_crypto_length(context, key->keyblock.enctype,
                                     conf_flag ? KRB5_CRYPTO_TYPE_TRAILER :
                                                 KRB5_CRYPTO_TYPE_CHECKSUM,
                                     &k5_trailerlen);

Modified: trunk/src/lib/gssapi/krb5/k5unseal.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5unseal.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/k5unseal.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -176,7 +176,7 @@
                 krb5_keyblock *enc_key;
                 int i;
                 store_32_be(seqnum, bigend_seqnum);
-                code = krb5_copy_keyblock (context, ctx->enc, &enc_key);
+                code = krb5_k_key_keyblock(context, ctx->enc, &enc_key);
                 if (code)
                 {
                     xfree(plain);
@@ -287,7 +287,7 @@
 
         plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
         plaind.data = data_ptr;
-        code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+        code = krb5_k_make_checksum(context, md5cksum.checksum_type,
                                     ctx->seq, sign_usage,
                                     &plaind, &md5cksum);
         xfree(data_ptr);
@@ -301,7 +301,7 @@
 
         if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
                                (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
-                                ctx->seq->contents : NULL),
+                                ctx->seq->keyblock.contents : NULL),
                                md5cksum.contents, md5cksum.contents, 16))) {
             krb5_free_checksum_contents(context, &md5cksum);
             if (toktype == KG_TOK_SEAL_MSG)
@@ -354,7 +354,7 @@
             (ctx->big_endian ? token.length : plainlen);
         plaind.data = data_ptr;
         krb5_free_checksum_contents(context, &md5cksum);
-        code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+        code = krb5_k_make_checksum(context, md5cksum.checksum_type,
                                     ctx->seq, sign_usage,
                                     &plaind, &md5cksum);
         xfree(data_ptr);
@@ -400,7 +400,7 @@
 
         plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
         plaind.data = data_ptr;
-        code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+        code = krb5_k_make_checksum(context, md5cksum.checksum_type,
                                     ctx->seq, sign_usage,
                                     &plaind, &md5cksum);
         xfree(data_ptr);

Modified: trunk/src/lib/gssapi/krb5/k5unsealiov.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5unsealiov.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/k5unsealiov.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -153,7 +153,7 @@
 
                 store_32_be(seqnum, bigend_seqnum);
 
-                code = krb5_copy_keyblock(context, ctx->enc, &enc_key);
+                code = krb5_k_key_keyblock(context, ctx->enc, &enc_key);
                 if (code != 0) {
                     retval = GSS_S_FAILURE;
                     goto cleanup;
@@ -231,7 +231,7 @@
     case SGN_ALG_3:
         code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
                           (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
-                           ctx->seq->contents : NULL),
+                           ctx->seq->keyblock.contents : NULL),
                           md5cksum.contents, md5cksum.contents, 16);
         if (code != 0) {
             retval = GSS_S_FAILURE;
@@ -518,7 +518,7 @@
     case KG2_TOK_WRAP_MSG:
     case KG2_TOK_DEL_CTX: {
         size_t ec, rrc;
-        krb5_enctype enctype = ctx->enc->enctype;
+        krb5_enctype enctype = ctx->enc->keyblock.enctype;
         unsigned int k5_headerlen = 0;
         unsigned int k5_trailerlen = 0;
 

Modified: trunk/src/lib/gssapi/krb5/lucid_context.c
===================================================================
--- trunk/src/lib/gssapi/krb5/lucid_context.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/lucid_context.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -213,7 +213,7 @@
         lctx->rfc1964_kd.sign_alg = gctx->signalg;
         lctx->rfc1964_kd.seal_alg = gctx->sealalg;
         /* Copy key */
-        if ((retval = copy_keyblock_to_lucid_key(gctx->seq,
+        if ((retval = copy_keyblock_to_lucid_key(&gctx->seq->keyblock,
                                                  &lctx->rfc1964_kd.ctx_key)))
             goto error_out;
     }
@@ -221,11 +221,11 @@
         /* Copy keys */
         /* (subkey is always present, either a copy of the kerberos
            session key or a subkey) */
-        if ((retval = copy_keyblock_to_lucid_key(gctx->subkey,
+        if ((retval = copy_keyblock_to_lucid_key(&gctx->subkey->keyblock,
                                                  &lctx->cfx_kd.ctx_key)))
             goto error_out;
         if (gctx->have_acceptor_subkey) {
-            if ((retval = copy_keyblock_to_lucid_key(gctx->acceptor_subkey,
+            if ((retval = copy_keyblock_to_lucid_key(&gctx->acceptor_subkey->keyblock,
                                                      &lctx->cfx_kd.acceptor_subkey)))
                 goto error_out;
             lctx->cfx_kd.have_acceptor_subkey = 1;

Modified: trunk/src/lib/gssapi/krb5/ser_sctx.c
===================================================================
--- trunk/src/lib/gssapi/krb5/ser_sctx.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/ser_sctx.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -304,19 +304,19 @@
         if (!kret && ctx->subkey)
             kret = krb5_size_opaque(kcontext,
                                     KV5M_KEYBLOCK,
-                                    (krb5_pointer) ctx->subkey,
+                                    (krb5_pointer) &ctx->subkey->keyblock,
                                     &required);
 
         if (!kret && ctx->enc)
             kret = krb5_size_opaque(kcontext,
                                     KV5M_KEYBLOCK,
-                                    (krb5_pointer) ctx->enc,
+                                    (krb5_pointer) &ctx->enc->keyblock,
                                     &required);
 
         if (!kret && ctx->seq)
             kret = krb5_size_opaque(kcontext,
                                     KV5M_KEYBLOCK,
-                                    (krb5_pointer) ctx->seq,
+                                    (krb5_pointer) &ctx->seq->keyblock,
                                     &required);
 
         if (!kret)
@@ -339,8 +339,8 @@
                                     &required);
         if (!kret && ctx->acceptor_subkey)
             kret = krb5_size_opaque(kcontext,
-                                    KV5M_KEYBLOCK,
-                                    (krb5_pointer) ctx->acceptor_subkey,
+                                    KV5M_KEYBLOCK, (krb5_pointer)
+                                    &ctx->acceptor_subkey->keyblock,
                                     &required);
         if (!kret && ctx->authdata) {
             krb5_int32 i;
@@ -459,20 +459,20 @@
 
             if (!kret && ctx->subkey)
                 kret = krb5_externalize_opaque(kcontext,
-                                               KV5M_KEYBLOCK,
-                                               (krb5_pointer) ctx->subkey,
+                                               KV5M_KEYBLOCK, (krb5_pointer)
+                                               &ctx->subkey->keyblock,
                                                &bp, &remain);
 
             if (!kret && ctx->enc)
                 kret = krb5_externalize_opaque(kcontext,
-                                               KV5M_KEYBLOCK,
-                                               (krb5_pointer) ctx->enc,
+                                               KV5M_KEYBLOCK, (krb5_pointer)
+                                               &ctx->enc->keyblock,
                                                &bp, &remain);
 
             if (!kret && ctx->seq)
                 kret = krb5_externalize_opaque(kcontext,
-                                               KV5M_KEYBLOCK,
-                                               (krb5_pointer) ctx->seq,
+                                               KV5M_KEYBLOCK, (krb5_pointer)
+                                               &ctx->seq->keyblock,
                                                &bp, &remain);
 
             if (!kret && ctx->seqstate)
@@ -499,8 +499,8 @@
                                            &bp, &remain);
             if (!kret && ctx->acceptor_subkey)
                 kret = krb5_externalize_opaque(kcontext,
-                                               KV5M_KEYBLOCK,
-                                               (krb5_pointer) ctx->acceptor_subkey,
+                                               KV5M_KEYBLOCK, (krb5_pointer)
+                                               &ctx->acceptor_subkey->keyblock,
                                                &bp, &remain);
             if (!kret)
                 kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype,
@@ -554,6 +554,22 @@
     return(kret);
 }
 
+/* Internalize a keyblock and convert it to a key. */
+static krb5_error_code
+intern_key(krb5_context ctx, krb5_key *key, krb5_octet **bp, size_t *sp)
+{
+    krb5_keyblock *keyblock;
+    krb5_error_code ret;
+
+    ret = krb5_internalize_opaque(ctx, KV5M_KEYBLOCK,
+                                  (krb5_pointer *) &keyblock, bp, sp);
+    if (ret != 0)
+        return ret;
+    ret = krb5_k_create_key(ctx, keyblock, key);
+    krb5_free_keyblock(ctx, keyblock);
+    return ret;
+}
+
 /*
  * Internalize this krb5_gss_ctx_id_t.
  */
@@ -670,26 +686,17 @@
                     kret = 0;
             }
             if (!kret &&
-                (kret = krb5_internalize_opaque(kcontext,
-                                                KV5M_KEYBLOCK,
-                                                (krb5_pointer *) &ctx->subkey,
-                                                &bp, &remain))) {
+                (kret = intern_key(kcontext, &ctx->subkey, &bp, &remain))) {
                 if (kret == EINVAL)
                     kret = 0;
             }
             if (!kret &&
-                (kret = krb5_internalize_opaque(kcontext,
-                                                KV5M_KEYBLOCK,
-                                                (krb5_pointer *) &ctx->enc,
-                                                &bp, &remain))) {
+                (kret = intern_key(kcontext, &ctx->enc, &bp, &remain))) {
                 if (kret == EINVAL)
                     kret = 0;
             }
             if (!kret &&
-                (kret = krb5_internalize_opaque(kcontext,
-                                                KV5M_KEYBLOCK,
-                                                (krb5_pointer *) &ctx->seq,
-                                                &bp, &remain))) {
+                (kret = intern_key(kcontext, &ctx->seq, &bp, &remain))) {
                 if (kret == EINVAL)
                     kret = 0;
             }
@@ -720,10 +727,8 @@
                 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
             ctx->cksumtype = ibuf;
             if (!kret &&
-                (kret = krb5_internalize_opaque(kcontext,
-                                                KV5M_KEYBLOCK,
-                                                (krb5_pointer *) &ctx->acceptor_subkey,
-                                                &bp, &remain))) {
+                (kret = intern_key(kcontext, &ctx->acceptor_subkey,
+                                   &bp, &remain))) {
                 if (kret == EINVAL)
                     kret = 0;
             }
@@ -781,11 +786,11 @@
                 *argp = (krb5_pointer) ctx;
             } else {
                 if (ctx->seq)
-                    krb5_free_keyblock(kcontext, ctx->seq);
+                    krb5_k_free_key(kcontext, ctx->seq);
                 if (ctx->enc)
-                    krb5_free_keyblock(kcontext, ctx->enc);
+                    krb5_k_free_key(kcontext, ctx->enc);
                 if (ctx->subkey)
-                    krb5_free_keyblock(kcontext, ctx->subkey);
+                    krb5_k_free_key(kcontext, ctx->subkey);
                 if (ctx->there)
                     kg_release_name(kcontext, 0, &ctx->there);
                 if (ctx->here)

Modified: trunk/src/lib/gssapi/krb5/util_cksum.c
===================================================================
--- trunk/src/lib/gssapi/krb5/util_cksum.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/util_cksum.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -112,8 +112,8 @@
 kg_make_checksum_iov_v1(krb5_context context,
                         krb5_cksumtype type,
                         size_t cksum_len,
-                        krb5_keyblock *seq,
-                        krb5_keyblock *enc,
+                        krb5_key seq,
+                        krb5_key enc,
                         krb5_keyusage sign_usage,
                         gss_iov_buffer_desc *iov,
                         int iov_count,
@@ -137,7 +137,7 @@
 
     /* Checksum over ( Header | Confounder | Data | Pad ) */
     if (toktype == KG_TOK_WRAP_MSG)
-        conf_len = kg_confounder_size(context, (krb5_keyblock *)enc);
+        conf_len = kg_confounder_size(context, enc);
 
     /* Checksum output */
     kiov[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
@@ -173,7 +173,7 @@
         i++;
     }
 
-    code = krb5_c_make_checksum_iov(context, type, seq, sign_usage, kiov, kiov_count);
+    code = krb5_k_make_checksum_iov(context, type, seq, sign_usage, kiov, kiov_count);
     if (code == 0) {
         checksum->length = kiov[0].data.length;
         checksum->contents = (unsigned char *)kiov[0].data.data;
@@ -189,7 +189,7 @@
 checksum_iov_v3(krb5_context context,
                 krb5_cksumtype type,
                 size_t rrc,
-                krb5_keyblock *key,
+                krb5_key key,
                 krb5_keyusage sign_usage,
                 gss_iov_buffer_desc *iov,
                 int iov_count,
@@ -207,7 +207,7 @@
     if (verify)
         *valid = FALSE;
 
-    code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen);
+    code = krb5_c_crypto_length(context, key->keyblock.enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen);
     if (code != 0)
         return code;
 
@@ -258,9 +258,9 @@
     i++;
 
     if (verify)
-        code = krb5_c_verify_checksum_iov(context, type, key, sign_usage, kiov, kiov_count, valid);
+        code = krb5_k_verify_checksum_iov(context, type, key, sign_usage, kiov, kiov_count, valid);
     else
-        code = krb5_c_make_checksum_iov(context, type, key, sign_usage, kiov, kiov_count);
+        code = krb5_k_make_checksum_iov(context, type, key, sign_usage, kiov, kiov_count);
 
     xfree(kiov);
 
@@ -271,7 +271,7 @@
 kg_make_checksum_iov_v3(krb5_context context,
                         krb5_cksumtype type,
                         size_t rrc,
-                        krb5_keyblock *key,
+                        krb5_key key,
                         krb5_keyusage sign_usage,
                         gss_iov_buffer_desc *iov,
                         int iov_count)
@@ -284,7 +284,7 @@
 kg_verify_checksum_iov_v3(krb5_context context,
                           krb5_cksumtype type,
                           size_t rrc,
-                          krb5_keyblock *key,
+                          krb5_key key,
                           krb5_keyusage sign_usage,
                           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-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/util_crypt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -59,39 +59,53 @@
 static krb5_error_code
 kg_copy_keys(krb5_context context,
              krb5_gss_ctx_id_rec *ctx,
-             krb5_keyblock *subkey)
+             krb5_key subkey)
 {
     krb5_error_code code;
 
-    if (ctx->enc != NULL) {
-        krb5_free_keyblock(context, ctx->enc);
-        ctx->enc = NULL;
-    }
+    krb5_k_free_key(context, ctx->enc);
+    ctx->enc = NULL;
+    code = krb5_k_create_key(context, &subkey->keyblock, &ctx->enc);
+    if (code != 0)
+        return code;
 
-    code = krb5_copy_keyblock(context, subkey, &ctx->enc);
+    krb5_k_free_key(context, ctx->seq);
+    ctx->seq = NULL;
+    code = krb5_k_create_key(context, &subkey->keyblock, &ctx->seq);
     if (code != 0)
         return code;
 
-    if (ctx->seq != NULL) {
-        krb5_free_keyblock(context, ctx->seq);
-        ctx->seq = NULL;
-    }
+    return 0;
+}
 
-    code = krb5_copy_keyblock(context, subkey, &ctx->seq);
+static krb5_error_code
+kg_derive_des_enc_key(krb5_context context, krb5_key subkey, krb5_key *out)
+{
+    krb5_error_code code;
+    krb5_keyblock *keyblock;
+    unsigned int i;
+
+    *out = NULL;
+
+    code = krb5_k_key_keyblock(context, subkey, &keyblock);
     if (code != 0)
         return code;
 
-    return 0;
+    for (i = 0; i < keyblock->length; i++)
+        keyblock->contents[i] ^= 0xF0;
+
+    code = krb5_k_create_key(context, keyblock, out);
+    krb5_free_keyblock(context, keyblock);
+    return code;
 }
 
 krb5_error_code
 kg_setup_keys(krb5_context context,
               krb5_gss_ctx_id_rec *ctx,
-              krb5_keyblock *subkey,
+              krb5_key subkey,
               krb5_cksumtype *cksumtype)
 {
     krb5_error_code code;
-    unsigned int i;
     krb5int_access kaccess;
 
     assert(ctx != NULL);
@@ -109,36 +123,40 @@
     if (code != 0)
         return code;
 
-    code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype,
+    code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
+                                                    subkey->keyblock.enctype,
                                                     cksumtype);
     if (code != 0)
         return code;
 
-    switch (subkey->enctype) {
+    switch (subkey->keyblock.enctype) {
     case ENCTYPE_DES_CBC_MD5:
     case ENCTYPE_DES_CBC_MD4:
     case ENCTYPE_DES_CBC_CRC:
-        code = kg_copy_keys(context, ctx, subkey);
+        krb5_k_free_key(context, ctx->seq);
+        code = krb5_k_create_key(context, &subkey->keyblock, &ctx->seq);
         if (code != 0)
             return code;
 
-        ctx->enc->enctype = ENCTYPE_DES_CBC_RAW;
-        ctx->seq->enctype = ENCTYPE_DES_CBC_RAW;
+        krb5_k_free_key(context, ctx->enc);
+        code = kg_derive_des_enc_key(context, subkey, &ctx->enc);
+        if (code != 0)
+            return code;
+
+        ctx->enc->keyblock.enctype = ENCTYPE_DES_CBC_RAW;
+        ctx->seq->keyblock.enctype = ENCTYPE_DES_CBC_RAW;
         ctx->signalg = SGN_ALG_DES_MAC_MD5;
         ctx->cksum_size = 8;
         ctx->sealalg = SEAL_ALG_DES;
 
-        for (i = 0; i < ctx->enc->length; i++)
-            /*SUPPRESS 113*/
-            ctx->enc->contents[i] ^= 0xF0;
         break;
     case ENCTYPE_DES3_CBC_SHA1:
         code = kg_copy_keys(context, ctx, subkey);
         if (code != 0)
             return code;
 
-        ctx->enc->enctype = ENCTYPE_DES3_CBC_RAW;
-        ctx->seq->enctype = ENCTYPE_DES3_CBC_RAW;
+        ctx->enc->keyblock.enctype = ENCTYPE_DES3_CBC_RAW;
+        ctx->seq->keyblock.enctype = ENCTYPE_DES3_CBC_RAW;
         ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
         ctx->cksum_size = 20;
         ctx->sealalg = SEAL_ALG_DES3KD;
@@ -164,15 +182,15 @@
 int
 kg_confounder_size(context, key)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
 {
     krb5_error_code code;
     size_t blocksize;
     /* We special case rc4*/
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC ||
-        key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
+        key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
         return 8;
-    code = krb5_c_block_size(context, key->enctype, &blocksize);
+    code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
     if (code)
         return(-1); /* XXX */
 
@@ -182,7 +200,7 @@
 krb5_error_code
 kg_make_confounder(context, key, buf)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
     unsigned char *buf;
 {
     int confsize;
@@ -201,7 +219,7 @@
 krb5_error_code
 kg_encrypt(context, key, usage, iv, in, out, length)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
     int usage;
     krb5_pointer iv;
     krb5_const_pointer in;
@@ -214,7 +232,7 @@
     krb5_enc_data outputd;
 
     if (iv) {
-        code = krb5_c_block_size(context, key->enctype, &blocksize);
+        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
         if (code)
             return(code);
 
@@ -234,7 +252,7 @@
     outputd.ciphertext.length = length;
     outputd.ciphertext.data = out;
 
-    code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd);
+    code = krb5_k_encrypt(context, key, usage, pivd, &inputd, &outputd);
     if (pivd != NULL)
         free(pivd->data);
     return code;
@@ -245,7 +263,7 @@
 krb5_error_code
 kg_decrypt(context, key, usage, iv, in, out, length)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
     int usage;
     krb5_pointer iv;
     krb5_const_pointer in;
@@ -258,7 +276,7 @@
     krb5_enc_data inputd;
 
     if (iv) {
-        code = krb5_c_block_size(context, key->enctype, &blocksize);
+        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
         if (code)
             return(code);
 
@@ -279,7 +297,7 @@
     outputd.length = length;
     outputd.data = out;
 
-    code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd);
+    code = krb5_k_decrypt(context, key, usage, pivd, &inputd, &outputd);
     if (pivd != NULL)
         free(pivd->data);
     return code;
@@ -294,6 +312,7 @@
     krb5_error_code code;
     krb5_data input, output;
     krb5int_access kaccess;
+    krb5_key key;
     krb5_keyblock seq_enc_key, usage_key;
     unsigned char t[14];
     size_t i = 0;
@@ -341,9 +360,11 @@
     input.length = input_len;
     output.data = (void * ) output_buf;
     output.length = input_len;
-    code =  ((*kaccess.arcfour_enc_provider->encrypt)(
-                 &seq_enc_key, 0,
-                 &input, &output));
+    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);
@@ -356,7 +377,7 @@
 static krb5_error_code
 kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count)
     krb5_context context;
-    const krb5_keyblock *key;
+    krb5_key key;
     gss_iov_buffer_desc *iov;
     int iov_count;
     krb5_crypto_iov **pkiov;
@@ -372,7 +393,7 @@
     *pkiov = NULL;
     *pkiov_count = 0;
 
-    conf_len = kg_confounder_size(context, (krb5_keyblock *)key);
+    conf_len = kg_confounder_size(context, key);
 
     header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
     assert(header != NULL);
@@ -427,7 +448,7 @@
     int dce_style;              /* DCE_STYLE indicates actual RRC is EC + RRC */
     size_t ec;                  /* Extra rotate count for DCE_STYLE, pad length otherwise */
     size_t rrc;                 /* Rotate count */
-    const krb5_keyblock *key;
+    krb5_key key;
     gss_iov_buffer_desc *iov;
     int iov_count;
     krb5_crypto_iov **pkiov;
@@ -451,11 +472,13 @@
     trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
     assert(trailer == NULL || rrc == 0);
 
-    code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
+    code = krb5_c_crypto_length(context, key->keyblock.enctype,
+                                KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
     if (code != 0)
         return code;
 
-    code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
+    code = krb5_c_crypto_length(context, key->keyblock.enctype,
+                                KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
     if (code != 0)
         return code;
 
@@ -541,7 +564,7 @@
     int dce_style;
     size_t ec;
     size_t rrc;
-    const krb5_keyblock *key;
+    krb5_key key;
     gss_iov_buffer_desc *iov;
     int iov_count;
     krb5_crypto_iov **pkiov;
@@ -559,7 +582,7 @@
     int dce_style;
     size_t ec;
     size_t rrc;
-    krb5_keyblock *key;
+    krb5_key key;
     int usage;
     krb5_pointer iv;
     gss_iov_buffer_desc *iov;
@@ -572,7 +595,7 @@
     krb5_crypto_iov *kiov;
 
     if (iv) {
-        code = krb5_c_block_size(context, key->enctype, &blocksize);
+        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
         if (code)
             return(code);
 
@@ -589,7 +612,7 @@
     code = kg_translate_iov(context, proto, dce_style, ec, rrc, key,
                             iov, iov_count, &kiov, &kiov_count);
     if (code == 0) {
-        code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count);
+        code = krb5_k_encrypt_iov(context, key, usage, pivd, kiov, kiov_count);
         free(kiov);
     }
 
@@ -608,7 +631,7 @@
     int dce_style;
     size_t ec;
     size_t rrc;
-    krb5_keyblock *key;
+    krb5_key key;
     int usage;
     krb5_pointer iv;
     gss_iov_buffer_desc *iov;
@@ -621,7 +644,7 @@
     krb5_crypto_iov *kiov;
 
     if (iv) {
-        code = krb5_c_block_size(context, key->enctype, &blocksize);
+        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
         if (code)
             return(code);
 
@@ -638,7 +661,7 @@
     code = kg_translate_iov(context, proto, dce_style, ec, rrc, key,
                             iov, iov_count, &kiov, &kiov_count);
     if (code == 0) {
-        code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count);
+        code = krb5_k_decrypt_iov(context, key, usage, pivd, kiov, kiov_count);
         free(kiov);
     }
 
@@ -657,6 +680,7 @@
     krb5_error_code code;
     krb5_data input, output;
     krb5int_access kaccess;
+    krb5_key key;
     krb5_keyblock seq_enc_key, usage_key;
     unsigned char t[14];
     size_t i = 0;
@@ -709,9 +733,12 @@
     if (code)
         goto cleanup_arcfour;
 
-    code =  ((*kaccess.arcfour_enc_provider->encrypt_iov)(
-                 &seq_enc_key, 0,
-                 kiov, kiov_count));
+    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);

Modified: trunk/src/lib/gssapi/krb5/util_seed.c
===================================================================
--- trunk/src/lib/gssapi/krb5/util_seed.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/util_seed.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -31,25 +31,31 @@
 krb5_error_code
 kg_make_seed(context, key, seed)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
     unsigned char *seed;
 {
     krb5_error_code code;
-    krb5_keyblock *tmpkey;
+    krb5_key rkey = NULL;
+    krb5_keyblock *tmpkey, *kb;
     unsigned int i;
 
-    code = krb5_copy_keyblock(context, key, &tmpkey);
+    code = krb5_k_key_keyblock(context, key, &tmpkey);
     if (code)
         return(code);
 
     /* reverse the key bytes, as per spec */
-
+    kb = &key->keyblock;
     for (i=0; i<tmpkey->length; i++)
-        tmpkey->contents[i] = key->contents[key->length - 1 - i];
+        tmpkey->contents[i] = kb->contents[kb->length - 1 - i];
 
-    code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
+    code = krb5_k_create_key(context, tmpkey, &rkey);
+    if (code)
+        goto cleanup;
 
+    code = kg_encrypt(context, rkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
+
+cleanup:
     krb5_free_keyblock(context, tmpkey);
-
+    krb5_k_free_key(context, rkey);
     return(code);
 }

Modified: trunk/src/lib/gssapi/krb5/util_seqnum.c
===================================================================
--- trunk/src/lib/gssapi/krb5/util_seqnum.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/util_seqnum.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -32,7 +32,7 @@
 krb5_error_code
 kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
     int direction;
     krb5_ui_4 seqnum;
     unsigned char *cksum;
@@ -44,11 +44,11 @@
     plain[5] = direction;
     plain[6] = direction;
     plain[7] = direction;
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC ||
-        key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
+        key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
         /* Yes, Microsoft used big-endian sequence number.*/
         store_32_be(seqnum, plain);
-        return kg_arcfour_docrypt (key, 0,
+        return kg_arcfour_docrypt (&key->keyblock, 0,
                                    cksum, 8,
                                    &plain[0], 8,
                                    buf);
@@ -61,7 +61,7 @@
 
 krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
     krb5_context context;
-    krb5_keyblock *key;
+    krb5_key key;
     unsigned char *cksum;
     unsigned char *buf;
     int *direction;
@@ -70,9 +70,9 @@
     krb5_error_code code;
     unsigned char plain[8];
 
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC ||
-        key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
-        code = kg_arcfour_docrypt (key, 0,
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
+        key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+        code = kg_arcfour_docrypt (&key->keyblock, 0,
                                    cksum, 8,
                                    buf, 8,
                                    plain);
@@ -88,8 +88,8 @@
         return((krb5_error_code) KG_BAD_SEQ);
 
     *direction = plain[4];
-    if (key->enctype == ENCTYPE_ARCFOUR_HMAC ||
-        key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+    if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
+        key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
         *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24));
     } else {
         *seqnum = ((plain[0]) |

Modified: trunk/src/lib/gssapi/krb5/wrap_size_limit.c
===================================================================
--- trunk/src/lib/gssapi/krb5/wrap_size_limit.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/gssapi/krb5/wrap_size_limit.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -114,10 +114,12 @@
 
         /* Token header: 16 octets.  */
         if (conf_req_flag) {
+            krb5_key key;
             krb5_enctype enctype;
 
-            enctype = ctx->have_acceptor_subkey ? ctx->acceptor_subkey->enctype
-                                                : ctx->subkey->enctype;
+            key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey
+                                            : ctx->subkey;
+            enctype = key->keyblock.enctype;
 
             while (sz > 0 && krb5_encrypt_size(sz, enctype) + 16 > req_output_size)
                 sz--;

Modified: trunk/src/lib/krb5/krb/auth_con.c
===================================================================
--- trunk/src/lib/krb5/krb/auth_con.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/auth_con.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -56,12 +56,12 @@
 	krb5_free_address(context, auth_context->remote_port);
     if (auth_context->authentp) 
 	krb5_free_authenticator(context, auth_context->authentp);
-    if (auth_context->keyblock) 
-	krb5_free_keyblock(context, auth_context->keyblock);
+    if (auth_context->key)
+	krb5_k_free_key(context, auth_context->key);
     if (auth_context->send_subkey) 
-	krb5_free_keyblock(context, auth_context->send_subkey);
+	krb5_k_free_key(context, auth_context->send_subkey);
     if (auth_context->recv_subkey) 
-	krb5_free_keyblock(context, auth_context->recv_subkey);
+	krb5_k_free_key(context, auth_context->recv_subkey);
     if (auth_context->rcache)
 	krb5_rc_close(context, auth_context->rcache);
     if (auth_context->permitted_etypes)
@@ -160,16 +160,16 @@
 krb5_error_code KRB5_CALLCONV
 krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock)
 {
-    if (auth_context->keyblock)
-	krb5_free_keyblock(context, auth_context->keyblock);
-    return(krb5_copy_keyblock(context, keyblock, &(auth_context->keyblock)));
+    if (auth_context->key)
+	krb5_k_free_key(context, auth_context->key);
+    return(krb5_k_create_key(context, keyblock, &(auth_context->key)));
 }
 
 krb5_error_code KRB5_CALLCONV
 krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
 {
-    if (auth_context->keyblock)
-    	return krb5_copy_keyblock(context, auth_context->keyblock, keyblock);
+    if (auth_context->key)
+    	return krb5_k_key_keyblock(context, auth_context->key, keyblock);
     *keyblock = NULL;
     return 0;
 }
@@ -190,10 +190,10 @@
 krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
 {
     if (ac->send_subkey != NULL)
-	krb5_free_keyblock(ctx, ac->send_subkey);
+	krb5_k_free_key(ctx, ac->send_subkey);
     ac->send_subkey = NULL;
     if (keyblock !=NULL)
-	return krb5_copy_keyblock(ctx, keyblock, &ac->send_subkey);
+	return krb5_k_create_key(ctx, keyblock, &ac->send_subkey);
     else
 	return 0;
 }
@@ -202,10 +202,10 @@
 krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
 {
     if (ac->recv_subkey != NULL)
-	krb5_free_keyblock(ctx, ac->recv_subkey);
+	krb5_k_free_key(ctx, ac->recv_subkey);
     ac->recv_subkey = NULL;
     if (keyblock != NULL)
-	return krb5_copy_keyblock(ctx, keyblock, &ac->recv_subkey);
+	return krb5_k_create_key(ctx, keyblock, &ac->recv_subkey);
     else
 	return 0;
 }
@@ -214,7 +214,7 @@
 krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
 {
     if (ac->send_subkey != NULL)
-	return krb5_copy_keyblock(ctx, ac->send_subkey, keyblock);
+	return krb5_k_key_keyblock(ctx, ac->send_subkey, keyblock);
     *keyblock = NULL;
     return 0;
 }
@@ -223,7 +223,7 @@
 krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
 {
     if (ac->recv_subkey != NULL)
-	return krb5_copy_keyblock(ctx, ac->recv_subkey, keyblock);
+	return krb5_k_key_keyblock(ctx, ac->recv_subkey, keyblock);
     *keyblock = NULL;
     return 0;
 }
@@ -268,12 +268,13 @@
 krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
 {
     krb5_error_code ret;
+    krb5_enctype enctype;
 
-    if (auth_context->keyblock) {
+    if (auth_context->key) {
 	size_t blocksize;
 
-	if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype,
-				    &blocksize)))
+	enctype = krb5_k_key_enctype(context, auth_context->key);
+	if ((ret = krb5_c_block_size(context, enctype, &blocksize)))
 	    return(ret);
 	if ((auth_context->i_vector = (krb5_pointer)calloc(1,blocksize))) {
 	    return 0;

Modified: trunk/src/lib/krb5/krb/auth_con.h
===================================================================
--- trunk/src/lib/krb5/krb/auth_con.h	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/auth_con.h	2009-10-19 20:04:21 UTC (rev 22944)
@@ -8,9 +8,9 @@
     krb5_address      *	remote_port;
     krb5_address      *	local_addr;
     krb5_address      *	local_port;
-    krb5_keyblock     * keyblock;
-    krb5_keyblock     * send_subkey;
-    krb5_keyblock     * recv_subkey;
+    krb5_key            key;
+    krb5_key            send_subkey;
+    krb5_key            recv_subkey;
 
     krb5_int32		auth_context_flags;
     krb5_ui_4		remote_seq_number;

Modified: trunk/src/lib/krb5/krb/copy_key.c
===================================================================
--- trunk/src/lib/krb5/krb/copy_key.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/copy_key.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -35,16 +35,5 @@
 krb5_error_code KRB5_CALLCONV
 krb5_copy_keyblock(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to)
 {
-	krb5_keyblock	*new_key;
-
-	if (!(new_key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))))
-		return ENOMEM;
-	*new_key = *from;
-	if (!(new_key->contents = (krb5_octet *)malloc(new_key->length))) {
-		free(new_key);
-		return(ENOMEM);
-	}
-	memcpy(new_key->contents, from->contents, new_key->length);
-	*to = new_key;
-	return 0;
+    return krb5int_c_copy_keyblock(context, from, to);
 }

Modified: trunk/src/lib/krb5/krb/cp_key_cnt.c
===================================================================
--- trunk/src/lib/krb5/krb/cp_key_cnt.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/cp_key_cnt.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -35,13 +35,5 @@
 krb5_error_code KRB5_CALLCONV
 krb5_copy_keyblock_contents(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to)
 {
-    *to = *from;
-    if (to->length) {
-        to->contents = (krb5_octet *)malloc(to->length);
-        if (!to->contents)
-            return ENOMEM;
-        memcpy(to->contents, from->contents, to->length);
-    } else 
-        to->contents = 0;
-    return 0;
+    return krb5int_c_copy_keyblock_contents(context, from, to);
 }

Modified: trunk/src/lib/krb5/krb/enc_helper.c
===================================================================
--- trunk/src/lib/krb5/krb/enc_helper.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/enc_helper.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -48,3 +48,28 @@
     return(ret);
 }
 	
+krb5_error_code
+krb5_encrypt_keyhelper(krb5_context context, krb5_key key, krb5_keyusage usage,
+		       const krb5_data *plain, krb5_enc_data *cipher)
+{
+    krb5_enctype enctype;
+    krb5_error_code ret;
+    size_t enclen;
+
+    enctype = krb5_k_key_enctype(context, key);
+    ret = krb5_c_encrypt_length(context, enctype, plain->length, &enclen);
+    if (ret != 0)
+	return ret;
+
+    cipher->ciphertext.length = enclen;
+    cipher->ciphertext.data = malloc(enclen);
+    if (cipher->ciphertext.data == NULL)
+	return ENOMEM;
+    ret = krb5_k_encrypt(context, key, usage, 0, plain, cipher);
+    if (ret) {
+	free(cipher->ciphertext.data);
+	cipher->ciphertext.data = NULL;
+    }
+
+    return ret;
+}

Modified: trunk/src/lib/krb5/krb/mk_cred.c
===================================================================
--- trunk/src/lib/krb5/krb/mk_cred.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/mk_cred.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -22,7 +22,7 @@
  */
 static krb5_error_code 
 encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart,
-		    krb5_keyblock *pkeyblock, krb5_enc_data *pencdata)
+		    krb5_key pkey, krb5_enc_data *pencdata)
 {
     krb5_error_code 	  retval;
     krb5_data 		* scratch;
@@ -35,7 +35,7 @@
      * If the keyblock is NULL, just copy the data from the encoded
      * data to the ciphertext area.
      */
-    if (pkeyblock == NULL) {
+    if (pkey == NULL) {
 	    pencdata->ciphertext.data = scratch->data;
 	    pencdata->ciphertext.length = scratch->length;
 	    free(scratch);
@@ -43,9 +43,9 @@
     }
 
     /* call the encryption routine */
-    retval = krb5_encrypt_helper(context, pkeyblock,
-				 KRB5_KEYUSAGE_KRB_CRED_ENCPART,
-				 scratch, pencdata);
+    retval = krb5_encrypt_keyhelper(context, pkey,
+				    KRB5_KEYUSAGE_KRB_CRED_ENCPART,
+				    scratch, pencdata);
 
     if (retval) {
     	memset(pencdata->ciphertext.data, 0, pencdata->ciphertext.length);
@@ -65,7 +65,7 @@
 static krb5_error_code
 krb5_mk_ncred_basic(krb5_context context,
 		    krb5_creds **ppcreds, krb5_int32 nppcreds,
-		    krb5_keyblock *keyblock, krb5_replay_data *replaydata,
+		    krb5_key key, krb5_replay_data *replaydata,
 		    krb5_address *local_addr, krb5_address *remote_addr,
 		    krb5_cred *pcred)
 {
@@ -134,8 +134,7 @@
     pcred->tickets[i] = NULL;
 
     /* encrypt the credential encrypted part */
-    retval = encrypt_credencpart(context, &credenc, keyblock,
-				 &pcred->enc_part);
+    retval = encrypt_credencpart(context, &credenc, key, &pcred->enc_part);
 
 cleanup:
     krb5_free_cred_enc_part(context, &credenc);
@@ -158,7 +157,7 @@
     krb5_address remote_fulladdr;
     krb5_address local_fulladdr;
     krb5_error_code 	retval;
-    krb5_keyblock	 * keyblock;
+    krb5_key		key;
     krb5_replay_data    replaydata;
     krb5_cred 		 * pcred;
     krb5_int32		ncred;
@@ -188,8 +187,8 @@
     }
 
     /* Get keyblock */
-    if ((keyblock = auth_context->send_subkey) == NULL) 
-	keyblock = auth_context->keyblock;
+    if ((key = auth_context->send_subkey) == NULL)
+	key = auth_context->key;
 
     /* Get replay info */
     if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
@@ -246,7 +245,7 @@
     }
 
     /* Setup creds structure */
-    if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, keyblock,
+    if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, key,
 				      &replaydata, plocal_fulladdr, 
 				      premote_fulladdr, pcred))) {
 	goto error;

Modified: trunk/src/lib/krb5/krb/mk_priv.c
===================================================================
--- trunk/src/lib/krb5/krb/mk_priv.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/mk_priv.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -33,10 +33,11 @@
 
 static krb5_error_code
 krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata,
-		   const krb5_keyblock *keyblock, krb5_replay_data *replaydata,
+		   krb5_key key, krb5_replay_data *replaydata,
 		   krb5_address *local_addr, krb5_address *remote_addr,
 		   krb5_pointer i_vector, krb5_data *outbuf)
 {
+    krb5_enctype	enctype = krb5_k_key_enctype(context, key);
     krb5_error_code 	retval;
     krb5_priv 		privmsg;
     krb5_priv_enc_part 	privmsg_enc_part;
@@ -44,7 +45,7 @@
     size_t		blocksize, enclen;
 
     privmsg.enc_part.kvno = 0;	/* XXX allow user-set? */
-    privmsg.enc_part.enctype = keyblock->enctype; 
+    privmsg.enc_part.enctype = enctype;
 
     privmsg_enc_part.user_data = *userdata;
     privmsg_enc_part.s_address = local_addr;
@@ -60,7 +61,7 @@
 	return retval;
 
     /* put together an eblock for this encryption */
-    if ((retval = krb5_c_encrypt_length(context, keyblock->enctype,
+    if ((retval = krb5_c_encrypt_length(context, enctype,
 					scratch1->length, &enclen)))
 	goto clean_scratch;
 
@@ -73,15 +74,14 @@
 
     /* call the encryption routine */
     if (i_vector) {
-	if ((retval = krb5_c_block_size(context, keyblock->enctype,
-					&blocksize)))
+	if ((retval = krb5_c_block_size(context, enctype, &blocksize)))
 	    goto clean_encpart;
 
 	ivdata.length = blocksize;
 	ivdata.data = i_vector;
     }
 
-    if ((retval = krb5_c_encrypt(context, keyblock,
+    if ((retval = krb5_k_encrypt(context, key,
 				 KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
 				 i_vector?&ivdata:0,
 				 scratch1, &privmsg.enc_part)))
@@ -115,15 +115,15 @@
 	     krb5_replay_data *outdata)
 {
     krb5_error_code 	  retval;
-    krb5_keyblock       * keyblock;
+    krb5_key              key;
     krb5_replay_data      replaydata;
 
     /* Clear replaydata block */
     memset(&replaydata, 0, sizeof(krb5_replay_data));
 
     /* Get keyblock */
-    if ((keyblock = auth_context->send_subkey) == NULL)
-	keyblock = auth_context->keyblock;
+    if ((key = auth_context->send_subkey) == NULL)
+	key = auth_context->key;
 
     /* Get replay info */
     if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
@@ -192,7 +192,7 @@
 	}
     }
 
-    if ((retval = krb5_mk_priv_basic(context, userdata, keyblock, &replaydata, 
+    if ((retval = krb5_mk_priv_basic(context, userdata, key, &replaydata,
 				     plocal_fulladdr, premote_fulladdr,
 				     auth_context->i_vector, outbuf))) {
 	CLEANUP_DONE();

Modified: trunk/src/lib/krb5/krb/mk_rep.c
===================================================================
--- trunk/src/lib/krb5/krb/mk_rep.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/mk_rep.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -80,7 +80,8 @@
     if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
 	(auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
 	(auth_context->local_seq_number == 0)) {
-	if ((retval = krb5_generate_seq_number(context, auth_context->keyblock,
+	if ((retval = krb5_generate_seq_number(context,
+					       &auth_context->key->keyblock,
 					       &auth_context->local_seq_number)))
             return(retval);
     }
@@ -98,11 +99,11 @@
 	assert(auth_context->negotiated_etype != ENCTYPE_NULL);
 
 	retval = krb5int_generate_and_save_subkey (context, auth_context,
-						   auth_context->keyblock,
+						   &auth_context->key->keyblock,
 						   auth_context->negotiated_etype);
 	if (retval)
 	    return retval;
-	repl.subkey = auth_context->send_subkey;
+	repl.subkey = &auth_context->send_subkey->keyblock;
     } else
 	repl.subkey = auth_context->authentp->subkey;
 
@@ -115,9 +116,9 @@
     if ((retval = encode_krb5_ap_rep_enc_part(&repl, &scratch)))
 	return retval;
 
-    if ((retval = krb5_encrypt_helper(context, auth_context->keyblock,
-				      KRB5_KEYUSAGE_AP_REP_ENCPART,
-				      scratch, &reply.enc_part)))
+    if ((retval = krb5_encrypt_keyhelper(context, auth_context->key,
+					 KRB5_KEYUSAGE_AP_REP_ENCPART,
+					 scratch, &reply.enc_part)))
 	goto cleanup_scratch;
 
     if (!(retval = encode_krb5_ap_rep(&reply, &toutbuf))) {

Modified: trunk/src/lib/krb5/krb/mk_req_ext.c
===================================================================
--- trunk/src/lib/krb5/krb/mk_req_ext.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/mk_req_ext.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -73,7 +73,7 @@
 static krb5_error_code 
 krb5_generate_authenticator (krb5_context,
 				       krb5_authenticator *, krb5_principal,
-				       krb5_checksum *, krb5_keyblock *,
+				       krb5_checksum *, krb5_key,
 				       krb5_ui_4, krb5_authdata **,
 				       krb5_authdata_context ad_context,
 				       krb5_enctype *desired_etypes,
@@ -94,6 +94,7 @@
     } rnd_data;
     krb5_data d;
     krb5_error_code retval;
+    krb5_keyblock *kb = NULL;
 
     if (krb5_crypto_us_timeofday(&rnd_data.sec, &rnd_data.usec) == 0) {
 	d.length = sizeof(rnd_data);
@@ -101,22 +102,23 @@
 	krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_TIMING, &d);
     }
 
-    if (auth_context->send_subkey)
-	krb5_free_keyblock(context, auth_context->send_subkey);
-    if ((retval = krb5_generate_subkey_extended(context, keyblock, enctype,
-						&auth_context->send_subkey)))
+    retval = krb5_generate_subkey_extended(context, keyblock, enctype, &kb);
+    if (retval)
 	return retval;
+    retval = krb5_auth_con_setsendsubkey(context, auth_context, kb);
+    if (retval)
+	goto cleanup;
+    retval = krb5_auth_con_setrecvsubkey(context, auth_context, kb);
+    if (retval)
+	goto cleanup;
 
-    if (auth_context->recv_subkey)
-	krb5_free_keyblock(context, auth_context->recv_subkey);
-    retval = krb5_copy_keyblock(context, auth_context->send_subkey,
-				&auth_context->recv_subkey);
+cleanup:
     if (retval) {
-	krb5_free_keyblock(context, auth_context->send_subkey);
-	auth_context->send_subkey = NULL;
-	return retval;
+	(void) krb5_auth_con_setsendsubkey(context, auth_context, NULL);
+	(void) krb5_auth_con_setrecvsubkey(context, auth_context, NULL);
     }
-    return 0;
+    krb5_free_keyblock(context, kb);
+    return retval;
 }
 
 krb5_error_code KRB5_CALLCONV
@@ -160,14 +162,14 @@
 	*auth_context = new_auth_context;
     }
 
-    if ((*auth_context)->keyblock != NULL) {
-	krb5_free_keyblock(context, (*auth_context)->keyblock);
-	(*auth_context)->keyblock = NULL;
+    if ((*auth_context)->key != NULL) {
+	krb5_k_free_key(context, (*auth_context)->key);
+	(*auth_context)->key = NULL;
     }
 
     /* set auth context keyblock */
-    if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock, 
-				     &((*auth_context)->keyblock))))
+    if ((retval = krb5_k_create_key(context, &in_creds->keyblock,
+				    &((*auth_context)->key))))
 	goto cleanup;
 
     /* generate seq number if needed */
@@ -206,16 +208,18 @@
 	    checksum.length = in_data->length;
 	    checksum.contents = (krb5_octet *) in_data->data;
 	} else {
+	    krb5_enctype enctype = krb5_k_key_enctype(context,
+						      (*auth_context)->key);
 	    krb5_cksumtype cksumtype;
-	    retval = krb5int_c_mandatory_cksumtype(context, (*auth_context)->keyblock->enctype,
+	    retval = krb5int_c_mandatory_cksumtype(context, enctype,
 						   &cksumtype);
 	    if (retval)
 		goto cleanup_cksum;
 	    if ((*auth_context)->req_cksumtype)
 		cksumtype = (*auth_context)->req_cksumtype;
-	    if ((retval = krb5_c_make_checksum(context, 
+	    if ((retval = krb5_k_make_checksum(context,
 					       cksumtype,
-					       (*auth_context)->keyblock,
+					       (*auth_context)->key,
 					       KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
 					       in_data, &checksum)))
 		goto cleanup_cksum;
@@ -300,7 +304,7 @@
 static krb5_error_code
 krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent,
 			    krb5_principal client, krb5_checksum *cksum,
-			    krb5_keyblock *key, krb5_ui_4 seq_number,
+			    krb5_key key, krb5_ui_4 seq_number,
 			    krb5_authdata **authorization,
 			    krb5_authdata_context ad_context,
 			    krb5_enctype *desired_etypes,
@@ -312,7 +316,7 @@
     authent->client = client;
     authent->checksum = cksum;
     if (key) {
-	retval = krb5_copy_keyblock(context, key, &authent->subkey);
+	retval = krb5_k_key_keyblock(context, key, &authent->subkey);
 	if (retval)
 	    return retval;
     } else

Modified: trunk/src/lib/krb5/krb/mk_safe.c
===================================================================
--- trunk/src/lib/krb5/krb/mk_safe.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/mk_safe.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -48,7 +48,7 @@
 */
 static krb5_error_code
 krb5_mk_safe_basic(krb5_context context, const krb5_data *userdata,
-		   const krb5_keyblock *keyblock, krb5_replay_data *replaydata,
+		   krb5_key key, krb5_replay_data *replaydata,
 		   krb5_address *local_addr, krb5_address *remote_addr,
 		   krb5_cksumtype sumtype, krb5_data *outbuf)
 {
@@ -88,7 +88,7 @@
     if ((retval = encode_krb5_safe(&safemsg, &scratch1)))
 	return retval;
 
-    if ((retval = krb5_c_make_checksum(context, sumtype, keyblock,
+    if ((retval = krb5_k_make_checksum(context, sumtype, key,
 				       KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
 				       scratch1, &safe_checksum)))
 	goto cleanup_checksum;
@@ -115,15 +115,15 @@
 	     krb5_replay_data *outdata)
 {
     krb5_error_code 	  retval;
-    krb5_keyblock       * keyblock;
+    krb5_key              key;
     krb5_replay_data      replaydata;
 
     /* Clear replaydata block */
     memset(&replaydata, 0, sizeof(krb5_replay_data));
 
-    /* Get keyblock */
-    if ((keyblock = auth_context->send_subkey) == NULL)
-	keyblock = auth_context->keyblock;
+    /* Get key */
+    if ((key = auth_context->send_subkey) == NULL)
+	key = auth_context->key;
 
     /* Get replay info */
     if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
@@ -195,10 +195,11 @@
     }
 
     {
+	krb5_enctype enctype = krb5_k_key_enctype(context, key);
 	unsigned int nsumtypes;
 	unsigned int i;
 	krb5_cksumtype *sumtypes;
-	retval = krb5_c_keyed_checksum_types (context, keyblock->enctype,
+	retval = krb5_c_keyed_checksum_types (context, enctype,
 					      &nsumtypes, &sumtypes);
 	if (retval) {
 	    CLEANUP_DONE ();
@@ -218,7 +219,7 @@
 	sumtype = sumtypes[i];
 	krb5_free_cksumtypes (context, sumtypes);
     }
-    if ((retval = krb5_mk_safe_basic(context, userdata, keyblock, &replaydata, 
+    if ((retval = krb5_mk_safe_basic(context, userdata, key, &replaydata,
 				     plocal_fulladdr, premote_fulladdr,
 				     sumtype, outbuf))) {
 	CLEANUP_DONE();

Modified: trunk/src/lib/krb5/krb/rd_cred.c
===================================================================
--- trunk/src/lib/krb5/krb/rd_cred.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/rd_cred.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -13,7 +13,7 @@
  */
 static krb5_error_code 
 decrypt_credencdata(krb5_context context, krb5_cred *pcred,
-		    krb5_keyblock *pkeyblock, krb5_cred_enc_part *pcredenc)
+		    krb5_key pkey, krb5_cred_enc_part *pcredenc)
 {
     krb5_cred_enc_part  * ppart = NULL;
     krb5_error_code 	  retval;
@@ -23,8 +23,8 @@
     if (!(scratch.data = (char *)malloc(scratch.length))) 
 	return ENOMEM;
 
-    if (pkeyblock != NULL) {
-	if ((retval = krb5_c_decrypt(context, pkeyblock,
+    if (pkey != NULL) {
+	if ((retval = krb5_k_decrypt(context, pkey,
 				     KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0,
 				     &pcred->enc_part, &scratch)))
 	    goto cleanup;
@@ -53,7 +53,7 @@
 
 static krb5_error_code 
 krb5_rd_cred_basic(krb5_context context, krb5_data *pcreddata,
-		   krb5_keyblock *pkeyblock, krb5_replay_data *replaydata,
+		   krb5_key pkey, krb5_replay_data *replaydata,
 		   krb5_creds ***pppcreds)
 {
     krb5_error_code       retval;
@@ -68,7 +68,7 @@
 
     memset(&encpart, 0, sizeof(encpart));
 
-    if ((retval = decrypt_credencdata(context, pcred, pkeyblock, &encpart)))
+    if ((retval = decrypt_credencdata(context, pcred, pkey, &encpart)))
 	goto cleanup_cred;
 
 
@@ -167,12 +167,12 @@
 	     krb5_replay_data *outdata)
 {
     krb5_error_code       retval;
-    krb5_keyblock       * keyblock;
+    krb5_key              key;
     krb5_replay_data      replaydata;
 
-    /* Get keyblock */
-    if ((keyblock = auth_context->recv_subkey) == NULL)
-	keyblock = auth_context->keyblock;
+    /* Get key */
+    if ((key = auth_context->recv_subkey) == NULL)
+	key = auth_context->key;
 
     if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
       (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
@@ -186,14 +186,14 @@
 
 
     /*
-     * If decrypting with the first keyblock we try fails, perhaps the
+     * If decrypting with the first key we try fails, perhaps the
      * credentials are stored in the session key so try decrypting with
      * that.
      */
-    if ((retval = krb5_rd_cred_basic(context, pcreddata, keyblock,
+    if ((retval = krb5_rd_cred_basic(context, pcreddata, key,
 				     &replaydata, pppcreds))) {
 	if ((retval = krb5_rd_cred_basic(context, pcreddata,
-					 auth_context->keyblock,
+					 auth_context->key,
 					 &replaydata, pppcreds))) {
 	    return retval;
 	}

Modified: trunk/src/lib/krb5/krb/rd_priv.c
===================================================================
--- trunk/src/lib/krb5/krb/rd_priv.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/rd_priv.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -54,8 +54,7 @@
 
 static krb5_error_code
 krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf,
-		   const krb5_keyblock *keyblock,
-		   const krb5_address *local_addr,
+		   const krb5_key key, const krb5_address *local_addr,
 		   const krb5_address *remote_addr, krb5_pointer i_vector,
 		   krb5_replay_data *replaydata, krb5_data *outbuf)
 {
@@ -65,6 +64,7 @@
     krb5_priv_enc_part  * privmsg_enc_part;
     size_t		  blocksize;
     krb5_data		  ivdata;
+    krb5_enctype	  enctype;
 
     if (!krb5_is_krb_priv(inbuf))
 	return KRB5KRB_AP_ERR_MSG_TYPE;
@@ -74,8 +74,8 @@
 	return retval;
     
     if (i_vector) {
-	if ((retval = krb5_c_block_size(context, keyblock->enctype,
-					&blocksize)))
+	enctype = krb5_k_key_enctype(context, key);
+	if ((retval = krb5_c_block_size(context, enctype, &blocksize)))
 	    goto cleanup_privmsg;
 
 	ivdata.length = blocksize;
@@ -88,7 +88,7 @@
 	goto cleanup_privmsg;
     }
 
-    if ((retval = krb5_c_decrypt(context, keyblock,
+    if ((retval = krb5_k_decrypt(context, key,
 				 KRB5_KEYUSAGE_KRB_PRIV_ENCPART, 
 				 i_vector?&ivdata:0,
 				 &privmsg->enc_part, &scratch)))
@@ -156,12 +156,12 @@
 	     krb5_replay_data *outdata)
 {
     krb5_error_code 	  retval;
-    krb5_keyblock       * keyblock;
+    krb5_key              key;
     krb5_replay_data	  replaydata;
 
-    /* Get keyblock */
-    if ((keyblock = auth_context->recv_subkey) == NULL)
-	keyblock = auth_context->keyblock;
+    /* Get key */
+    if ((key = auth_context->recv_subkey) == NULL)
+	key = auth_context->key;
 
     if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
       (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
@@ -213,7 +213,7 @@
     }
 
     memset(&replaydata, 0, sizeof(replaydata));
-    if ((retval = krb5_rd_priv_basic(context, inbuf, keyblock,
+    if ((retval = krb5_rd_priv_basic(context, inbuf, key,
 				     plocal_fulladdr,
 				     premote_fulladdr,
 				     auth_context->i_vector,

Modified: trunk/src/lib/krb5/krb/rd_rep.c
===================================================================
--- trunk/src/lib/krb5/krb/rd_rep.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/rd_rep.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -95,7 +95,7 @@
 	goto clean_scratch;
     }
 
-    retval = krb5_c_decrypt(context, auth_context->keyblock,
+    retval = krb5_k_decrypt(context, auth_context->key,
 			    KRB5_KEYUSAGE_AP_REP_ENCPART, 0,
 			    &reply->enc_part, &scratch);
     if (retval)
@@ -115,23 +115,14 @@
 
     /* Set auth subkey. */
     if (enc->subkey) {
-	if (auth_context->recv_subkey) {
-	    krb5_free_keyblock(context, auth_context->recv_subkey);
-	    auth_context->recv_subkey = NULL;
-	}
-	retval = krb5_copy_keyblock(context, enc->subkey,
-				    &auth_context->recv_subkey);
+	retval = krb5_auth_con_setrecvsubkey(context, auth_context,
+					     enc->subkey);
 	if (retval)
 	    goto clean_scratch;
-	if (auth_context->send_subkey) {
-	    krb5_free_keyblock(context, auth_context->send_subkey);
-	    auth_context->send_subkey = NULL;
-	}
-	retval = krb5_copy_keyblock(context, enc->subkey,
-				    &auth_context->send_subkey);
+	retval = krb5_auth_con_setsendsubkey(context, auth_context,
+					     enc->subkey);
 	if (retval) {
-	    krb5_free_keyblock(context, auth_context->send_subkey);
-	    auth_context->send_subkey = NULL;
+	    (void) krb5_auth_con_setrecvsubkey(context, auth_context, NULL);
 	    goto clean_scratch;
 	}
 	/* Not used for anything yet. */
@@ -178,7 +169,7 @@
 	return(ENOMEM);
     }
 
-    if ((retval = krb5_c_decrypt(context, auth_context->keyblock,
+    if ((retval = krb5_k_decrypt(context, auth_context->key,
 				 KRB5_KEYUSAGE_AP_REP_ENCPART, 0,
 				 &reply->enc_part, &scratch)))
 	goto clean_scratch;

Modified: trunk/src/lib/krb5/krb/rd_req_dec.c
===================================================================
--- trunk/src/lib/krb5/krb/rd_req_dec.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/rd_req_dec.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -238,16 +238,17 @@
        do we need special processing here ?	*/
 
     /* decrypt the ticket */
-    if ((*auth_context)->keyblock) { /* User to User authentication */
-    	if ((retval = krb5_decrypt_tkt_part(context, (*auth_context)->keyblock,
+    if ((*auth_context)->key) { /* User to User authentication */
+    	if ((retval = krb5_decrypt_tkt_part(context,
+					    &(*auth_context)->key->keyblock,
 					    req->ticket)))
 	    goto cleanup;
 	if (check_valid_flag) {
-	    decrypt_key = *((*auth_context)->keyblock);
-	    free((*auth_context)->keyblock);
-	} else
-	    krb5_free_keyblock(context, (*auth_context)->keyblock);
-	(*auth_context)->keyblock = NULL;
+	    decrypt_key = (*auth_context)->key->keyblock;
+	    (*auth_context)->key->keyblock.contents = NULL;
+	}
+	krb5_k_free_key(context, (*auth_context)->key);
+	(*auth_context)->key = NULL;
     } else {
     	if ((retval = krb5_rd_req_decrypt_tkt_part(context, req,
 						   server, keytab,
@@ -487,14 +488,14 @@
 
     (*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number;
     if ((*auth_context)->authentp->subkey) {
-	if ((retval = krb5_copy_keyblock(context,
-					 (*auth_context)->authentp->subkey,
-					 &((*auth_context)->recv_subkey))))
+	if ((retval = krb5_k_create_key(context,
+					(*auth_context)->authentp->subkey,
+					&((*auth_context)->recv_subkey))))
 	    goto cleanup;
-	retval = krb5_copy_keyblock(context, (*auth_context)->authentp->subkey,
-				    &((*auth_context)->send_subkey));
+	retval = krb5_k_create_key(context, (*auth_context)->authentp->subkey,
+				   &((*auth_context)->send_subkey));
 	if (retval) {
-	    krb5_free_keyblock(context, (*auth_context)->recv_subkey);
+	    krb5_k_free_key(context, (*auth_context)->recv_subkey);
 	    (*auth_context)->recv_subkey = NULL;
 	    goto cleanup;
 	}
@@ -503,8 +504,8 @@
 	(*auth_context)->send_subkey = 0;
     }
 
-    if ((retval = krb5_copy_keyblock(context, req->ticket->enc_part2->session,
-				     &((*auth_context)->keyblock))))
+    if ((retval = krb5_k_create_key(context, req->ticket->enc_part2->session,
+				    &((*auth_context)->key))))
 	goto cleanup;
 
     debug_log_authz_data("ticket", req->ticket->enc_part2->authorization_data);
@@ -527,7 +528,8 @@
     	*ap_req_options = req->ap_options & AP_OPTS_WIRE_MASK;
 	if (rfc4537_etypes_len != 0)
 	    *ap_req_options |= AP_OPTS_ETYPE_NEGOTIATION;
-	if ((*auth_context)->negotiated_etype != (*auth_context)->keyblock->enctype)
+	if ((*auth_context)->negotiated_etype !=
+	    krb5_k_key_enctype(context, (*auth_context)->key))
 	    *ap_req_options |= AP_OPTS_USE_SUBKEY;
     }
 

Modified: trunk/src/lib/krb5/krb/rd_safe.c
===================================================================
--- trunk/src/lib/krb5/krb/rd_safe.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/rd_safe.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -46,7 +46,7 @@
  */
 static krb5_error_code
 krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf,
-		   const krb5_keyblock *keyblock,
+		   krb5_key key,
 		   const krb5_address *recv_addr,
 		   const krb5_address *sender_addr,
 		   krb5_replay_data *replaydata, krb5_data *outbuf)
@@ -124,7 +124,7 @@
     if (retval)
 	goto cleanup;
 
-    retval = krb5_c_verify_checksum(context, keyblock,
+    retval = krb5_k_verify_checksum(context, key,
 				    KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
 				    scratch, his_cksum, &valid);
 
@@ -136,7 +136,7 @@
 	 * Checksum over only the KRB-SAFE-BODY, like RFC 1510 says, in
 	 * case someone actually implements it correctly.
 	 */
-	retval = krb5_c_verify_checksum(context, keyblock,
+	retval = krb5_k_verify_checksum(context, key,
 					KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
 					&safe_body, his_cksum, &valid);
 	if (!valid) {
@@ -164,7 +164,7 @@
 	     krb5_replay_data *outdata)
 {
     krb5_error_code 	  retval;
-    krb5_keyblock	* keyblock;
+    krb5_key		  key;
     krb5_replay_data	  replaydata;
 
     if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
@@ -180,9 +180,9 @@
     if (!auth_context->remote_addr)
 	return KRB5_REMOTE_ADDR_REQUIRED;
 
-    /* Get keyblock */
-    if ((keyblock = auth_context->recv_subkey) == NULL)
-	keyblock = auth_context->keyblock;
+    /* Get key */
+    if ((key = auth_context->recv_subkey) == NULL)
+	key = auth_context->key;
 
 {
     krb5_address * premote_fulladdr;
@@ -220,7 +220,7 @@
     }
 
     memset(&replaydata, 0, sizeof(replaydata));
-    if ((retval = krb5_rd_safe_basic(context, inbuf, keyblock,
+    if ((retval = krb5_rd_safe_basic(context, inbuf, key,
 				     plocal_fulladdr, premote_fulladdr,
 				     &replaydata, outbuf))) {
 	CLEANUP_DONE();

Modified: trunk/src/lib/krb5/krb/ser_actx.c
===================================================================
--- trunk/src/lib/krb5/krb/ser_actx.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/krb/ser_actx.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -75,6 +75,7 @@
     krb5_error_code	kret;
     krb5_auth_context	auth_context;
     size_t		required;
+    krb5_enctype	enctype;
 
     /*
      * krb5_auth_context requires at minimum:
@@ -92,9 +93,9 @@
 	kret = 0;
 
 	/* Calculate size required by i_vector - ptooey */
-	if (auth_context->i_vector && auth_context->keyblock) {
-	    kret = krb5_c_block_size(kcontext, auth_context->keyblock->enctype,
-				     &required);
+	if (auth_context->i_vector && auth_context->key) {
+	    enctype = krb5_k_key_enctype(kcontext, auth_context->key);
+	    kret = krb5_c_block_size(kcontext, enctype, &required);
 	} else {
 	    required = 0;
 	}
@@ -141,11 +142,11 @@
 		required += sizeof(krb5_int32);
 	}
 
-	/* Calculate size required by keyblock, if appropriate */
-	if (!kret && auth_context->keyblock) {
+	/* Calculate size required by key, if appropriate */
+	if (!kret && auth_context->key) {
 	    kret = krb5_size_opaque(kcontext,
-				    KV5M_KEYBLOCK,
-				    (krb5_pointer) auth_context->keyblock,
+				    KV5M_KEYBLOCK, (krb5_pointer)
+				    &auth_context->key->keyblock,
 				    &required);
 	    if (!kret)
 		required += sizeof(krb5_int32);
@@ -154,8 +155,8 @@
 	/* Calculate size required by send_subkey, if appropriate */
 	if (!kret && auth_context->send_subkey) {
 	    kret = krb5_size_opaque(kcontext,
-				    KV5M_KEYBLOCK,
-				    (krb5_pointer) auth_context->send_subkey,
+				    KV5M_KEYBLOCK, (krb5_pointer)
+				    &auth_context->send_subkey->keyblock,
 				    &required);
 	    if (!kret)
 		required += sizeof(krb5_int32);
@@ -164,8 +165,8 @@
 	/* Calculate size required by recv_subkey, if appropriate */
 	if (!kret && auth_context->recv_subkey) {
 	    kret = krb5_size_opaque(kcontext,
-				    KV5M_KEYBLOCK,
-				    (krb5_pointer) auth_context->recv_subkey,
+				    KV5M_KEYBLOCK, (krb5_pointer)
+				    &auth_context->recv_subkey->keyblock,
 				    &required);
 	    if (!kret)
 		required += sizeof(krb5_int32);
@@ -197,6 +198,7 @@
     size_t		remain;
     size_t              obuf;
     krb5_int32		obuf32;
+    krb5_enctype	enctype;
 
     required = 0;
     bp = *buffer;
@@ -224,9 +226,8 @@
 
 	    /* Now figure out the number of bytes for i_vector and write it */
 	    if (auth_context->i_vector) {
-		kret = krb5_c_block_size(kcontext,
-					 auth_context->keyblock->enctype,
-					 &obuf);
+		enctype = krb5_k_key_enctype(kcontext, auth_context->key);
+		kret = krb5_c_block_size(kcontext, enctype, &obuf);
 	    } else {
 		obuf = 0;
 	    }
@@ -289,12 +290,12 @@
 	    }
 
 	    /* Now handle keyblock, if appropriate */
-	    if (!kret && auth_context->keyblock) {
+	    if (!kret && auth_context->key) {
 		(void) krb5_ser_pack_int32(TOKEN_KEYBLOCK, &bp, &remain);
 		kret = krb5_externalize_opaque(kcontext,
 					       KV5M_KEYBLOCK,
 					       (krb5_pointer)
-					       auth_context->keyblock,
+					       &auth_context->key->keyblock,
 					       &bp,
 					       &remain);
 	    }
@@ -304,8 +305,8 @@
 		(void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain);
 		kret = krb5_externalize_opaque(kcontext,
 					       KV5M_KEYBLOCK,
-					       (krb5_pointer)
-					       auth_context->send_subkey,
+					       (krb5_pointer) &auth_context->
+					       send_subkey->keyblock,
 					       &bp,
 					       &remain);
 	    }
@@ -315,8 +316,8 @@
 		(void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain);
 		kret = krb5_externalize_opaque(kcontext,
 					       KV5M_KEYBLOCK,
-					       (krb5_pointer)
-					       auth_context->recv_subkey,
+					       (krb5_pointer) &auth_context->
+					       recv_subkey->keyblock,
 					       &bp,
 					       &remain);
 	    }
@@ -345,6 +346,22 @@
     return(kret);
 }
 
+/* Internalize a keyblock and convert it to a key. */
+static krb5_error_code
+intern_key(krb5_context ctx, krb5_key *key, krb5_octet **bp, size_t *sp)
+{
+    krb5_keyblock *keyblock;
+    krb5_error_code ret;
+
+    ret = krb5_internalize_opaque(ctx, KV5M_KEYBLOCK,
+				  (krb5_pointer *) &keyblock, bp, sp);
+    if (ret != 0)
+	return ret;
+    ret = krb5_k_create_key(ctx, keyblock, key);
+    krb5_free_keyblock(ctx, keyblock);
+    return ret;
+}
+
 /*
  * krb5_auth_context_internalize()	- Internalize the krb5_auth_context.
  */
@@ -464,37 +481,29 @@
 
 	    /* This is the keyblock */
 	    if (!kret && (tag == TOKEN_KEYBLOCK)) {
-		if (!(kret = krb5_internalize_opaque(kcontext,
-						     KV5M_KEYBLOCK,
-						     (krb5_pointer *)
-						     &auth_context->keyblock,
-						     &bp,
-						     &remain)))
+		if (!(kret = intern_key(kcontext,
+					&auth_context->key,
+					&bp,
+					&remain)))
 		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
 	    }
 
 	    /* This is the send_subkey */
 	    if (!kret && (tag == TOKEN_LSKBLOCK)) {
-		if (!(kret = krb5_internalize_opaque(kcontext,
-						     KV5M_KEYBLOCK,
-						     (krb5_pointer *)
-						     &auth_context->
-						     send_subkey,
-						     &bp,
-						     &remain)))
+		if (!(kret = intern_key(kcontext,
+					&auth_context->send_subkey,
+					&bp,
+					&remain)))
 		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
 	    }
 
 	    /* This is the recv_subkey */
 	    if (!kret) {
 		if (tag == TOKEN_RSKBLOCK) {
-		    kret = krb5_internalize_opaque(kcontext,
-						   KV5M_KEYBLOCK,
-						   (krb5_pointer *)
-						   &auth_context->
-						   recv_subkey,
-						   &bp,
-						   &remain);
+		    kret = intern_key(kcontext,
+				      &auth_context->recv_subkey,
+				      &bp,
+				      &remain);
 		}
 		else {
 		    /*

Modified: trunk/src/lib/krb5/os/accessor.c
===================================================================
--- trunk/src/lib/krb5/os/accessor.c	2009-10-19 20:02:18 UTC (rev 22943)
+++ trunk/src/lib/krb5/os/accessor.c	2009-10-19 20:04:21 UTC (rev 22944)
@@ -52,7 +52,7 @@
 	    krb5int_access internals_temp;
 #endif
 	    S (free_addrlist, krb5int_free_addrlist),
-	    S (krb5_hmac, krb5_hmac),
+	    S (krb5_hmac, krb5int_hmac_keyblock),
 	    S (krb5_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),




More information about the cvs-krb5 mailing list