summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/k5-int.h62
-rw-r--r--src/include/krb5/krb5.hin69
-rw-r--r--src/lib/crypto/builtin/aes/aes_s2k.c29
-rw-r--r--src/lib/crypto/builtin/arcfour/arcfour.c50
-rw-r--r--src/lib/crypto/builtin/arcfour/arcfour.h4
-rw-r--r--src/lib/crypto/builtin/arcfour/arcfour_aead.c48
-rw-r--r--src/lib/crypto/builtin/enc_provider/aes.c20
-rw-r--r--src/lib/crypto/builtin/enc_provider/des.c24
-rw-r--r--src/lib/crypto/builtin/enc_provider/des3.c22
-rw-r--r--src/lib/crypto/builtin/enc_provider/rc4.c22
-rw-r--r--src/lib/crypto/builtin/hmac.c39
-rw-r--r--src/lib/crypto/builtin/pbkdf2.c135
-rw-r--r--src/lib/crypto/crypto_tests/Makefile.in4
-rw-r--r--src/lib/crypto/crypto_tests/aes-test.c6
-rw-r--r--src/lib/crypto/crypto_tests/t_cksum.c9
-rw-r--r--src/lib/crypto/crypto_tests/t_cts.c23
-rw-r--r--src/lib/crypto/crypto_tests/t_encrypt.c128
-rw-r--r--src/lib/crypto/crypto_tests/t_hmac.c5
-rw-r--r--src/lib/crypto/crypto_tests/t_kperf.c119
-rw-r--r--src/lib/crypto/krb/Makefile.in3
-rw-r--r--src/lib/crypto/krb/aead.c10
-rw-r--r--src/lib/crypto/krb/aead.h8
-rw-r--r--src/lib/crypto/krb/combine_keys.c23
-rw-r--r--src/lib/crypto/krb/decrypt.c20
-rw-r--r--src/lib/crypto/krb/decrypt_iov.c25
-rw-r--r--src/lib/crypto/krb/dk/checksum.c53
-rw-r--r--src/lib/crypto/krb/dk/derive.c108
-rw-r--r--src/lib/crypto/krb/dk/dk.h23
-rw-r--r--src/lib/crypto/krb/dk/dk_aead.c47
-rw-r--r--src/lib/crypto/krb/dk/dk_decrypt.c35
-rw-r--r--src/lib/crypto/krb/dk/dk_encrypt.c70
-rw-r--r--src/lib/crypto/krb/dk/stringtokey.c22
-rw-r--r--src/lib/crypto/krb/encrypt.c22
-rw-r--r--src/lib/crypto/krb/encrypt_iov.c25
-rw-r--r--src/lib/crypto/krb/etypes.h4
-rw-r--r--src/lib/crypto/krb/key.c99
-rw-r--r--src/lib/crypto/krb/keyblocks.c36
-rw-r--r--src/lib/crypto/krb/keyhash_provider/descbc.c6
-rw-r--r--src/lib/crypto/krb/keyhash_provider/hmac_md5.c43
-rw-r--r--src/lib/crypto/krb/keyhash_provider/k5_md4des.c14
-rw-r--r--src/lib/crypto/krb/keyhash_provider/k5_md5des.c14
-rw-r--r--src/lib/crypto/krb/keyhash_provider/md5_hmac.c2
-rw-r--r--src/lib/crypto/krb/make_checksum.c24
-rw-r--r--src/lib/crypto/krb/make_checksum_iov.c24
-rw-r--r--src/lib/crypto/krb/old/old.h4
-rw-r--r--src/lib/crypto/krb/old/old_decrypt.c8
-rw-r--r--src/lib/crypto/krb/old/old_encrypt.c8
-rw-r--r--src/lib/crypto/krb/prf.c13
-rw-r--r--src/lib/crypto/krb/prf/des_prf.c3
-rw-r--r--src/lib/crypto/krb/prf/dk_prf.c15
-rw-r--r--src/lib/crypto/krb/prf/prf_int.h8
-rw-r--r--src/lib/crypto/krb/prf/rc4_prf.c3
-rw-r--r--src/lib/crypto/krb/raw/raw.h4
-rw-r--r--src/lib/crypto/krb/raw/raw_aead.c4
-rw-r--r--src/lib/crypto/krb/raw/raw_decrypt.c2
-rw-r--r--src/lib/crypto/krb/raw/raw_encrypt.c2
-rw-r--r--src/lib/crypto/krb/verify_checksum.c22
-rw-r--r--src/lib/crypto/krb/verify_checksum_iov.c25
-rw-r--r--src/lib/crypto/krb/yarrow/ycipher.c41
-rw-r--r--src/lib/crypto/krb/yarrow/ycipher.h2
-rw-r--r--src/lib/crypto/libk5crypto.exports15
-rw-r--r--src/lib/crypto/openssl/aes/aes_s2k.c29
-rw-r--r--src/lib/crypto/openssl/arcfour/arcfour.c50
-rw-r--r--src/lib/crypto/openssl/arcfour/arcfour.h9
-rw-r--r--src/lib/crypto/openssl/arcfour/arcfour_aead.c48
-rw-r--r--src/lib/crypto/openssl/enc_provider/aes.c60
-rw-r--r--src/lib/crypto/openssl/enc_provider/des.c36
-rw-r--r--src/lib/crypto/openssl/enc_provider/des3.c34
-rw-r--r--src/lib/crypto/openssl/enc_provider/rc4.c16
-rw-r--r--src/lib/crypto/openssl/hmac.c28
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c27
-rw-r--r--src/lib/gssapi/krb5/delete_sec_context.c8
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h41
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c21
-rw-r--r--src/lib/gssapi/krb5/inq_context.c8
-rw-r--r--src/lib/gssapi/krb5/k5seal.c10
-rw-r--r--src/lib/gssapi/krb5/k5sealiov.c11
-rw-r--r--src/lib/gssapi/krb5/k5sealv3.c20
-rw-r--r--src/lib/gssapi/krb5/k5sealv3iov.c20
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c10
-rw-r--r--src/lib/gssapi/krb5/k5unsealiov.c6
-rw-r--r--src/lib/gssapi/krb5/lucid_context.c6
-rw-r--r--src/lib/gssapi/krb5/ser_sctx.c69
-rw-r--r--src/lib/gssapi/krb5/util_cksum.c20
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c133
-rw-r--r--src/lib/gssapi/krb5/util_seed.c20
-rw-r--r--src/lib/gssapi/krb5/util_seqnum.c20
-rw-r--r--src/lib/gssapi/krb5/wrap_size_limit.c6
-rw-r--r--src/lib/krb5/krb/auth_con.c37
-rw-r--r--src/lib/krb5/krb/auth_con.h6
-rw-r--r--src/lib/krb5/krb/copy_key.c13
-rw-r--r--src/lib/krb5/krb/cp_key_cnt.c10
-rw-r--r--src/lib/krb5/krb/enc_helper.c25
-rw-r--r--src/lib/krb5/krb/mk_cred.c23
-rw-r--r--src/lib/krb5/krb/mk_priv.c20
-rw-r--r--src/lib/krb5/krb/mk_rep.c13
-rw-r--r--src/lib/krb5/krb/mk_req_ext.c50
-rw-r--r--src/lib/krb5/krb/mk_safe.c17
-rw-r--r--src/lib/krb5/krb/rd_cred.c24
-rw-r--r--src/lib/krb5/krb/rd_priv.c20
-rw-r--r--src/lib/krb5/krb/rd_rep.c23
-rw-r--r--src/lib/krb5/krb/rd_req_dec.c34
-rw-r--r--src/lib/krb5/krb/rd_safe.c16
-rw-r--r--src/lib/krb5/krb/ser_actx.c89
-rw-r--r--src/lib/krb5/os/accessor.c2
105 files changed, 1876 insertions, 1069 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 77221724ca..858b9bd6db 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -635,6 +635,19 @@ krb5int_locate_server (krb5_context, const krb5_data *realm,
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 @@ struct krb5_enc_provider {
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 @@ struct krb5_enc_provider {
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_hash_provider {
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 @@ struct krb5_aead_provider {
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 @@ struct krb5_aead_provider {
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 @@ void krb5_nfold
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_error_code krb5int_c_combine_keys
(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_error_code krb5_encrypt_helper
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_error_code krb5_decrypt_data
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 */
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 81bc1cf6e5..e0128d0586 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -341,6 +341,7 @@ struct _krb5_cryptosystem_entry;
* begin "encryption.h"
*/
+/* Exposed contents of a key. */
typedef struct _krb5_keyblock {
krb5_magic magic;
krb5_enctype enctype;
@@ -348,6 +349,16 @@ typedef struct _krb5_keyblock {
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_error_code KRB5_CALLCONV
(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
diff --git a/src/lib/crypto/builtin/aes/aes_s2k.c b/src/lib/crypto/builtin/aes/aes_s2k.c
index 36045edc0d..76d73c6357 100644
--- a/src/lib/crypto/builtin/aes/aes_s2k.c
+++ b/src/lib/crypto/builtin/aes/aes_s2k.c
@@ -44,6 +44,7 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc,
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 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc,
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;
}
diff --git a/src/lib/crypto/builtin/arcfour/arcfour.c b/src/lib/crypto/builtin/arcfour/arcfour.c
index e5cdfdc8c2..150a7aa067 100644
--- a/src/lib/crypto/builtin/arcfour/arcfour.c
+++ b/src/lib/crypto/builtin/arcfour/arcfour.c
@@ -64,11 +64,12 @@ case 7: /* tgs-req authenticator */
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 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
free(d1.data);
return (ENOMEM);
}
- k2 = *key;
+ k2 = key->keyblock;
k2.length=d2.length;
k2.contents=(void *) d2.data;
@@ -104,7 +105,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
free(d2.data);
return (ENOMEM);
}
- k3 = *key;
+ k3 = key->keyblock;
k3.length=d3.length;
k3.contents= (void *) d3.data;
@@ -140,7 +141,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
/* 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 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
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,11 +160,19 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
if (ret)
goto cleanup;
- krb5_hmac(hash, &k2, 1, &plaintext, &checksum);
+ ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum);
+ if (ret)
+ goto cleanup;
+
+ ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
+ if (ret)
+ goto cleanup;
- krb5_hmac(hash, &k1, 1, &checksum, &d3);
+ ret = krb5_k_create_key(NULL, &k3, &k3key);
+ if (ret)
+ goto cleanup;
- ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext);
+ ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext);
cleanup:
memset(d1.data, 0, d1.length);
@@ -184,11 +193,12 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
free(d1.data);
return (ENOMEM);
}
- k2 = *key;
+ k2 = key->keyblock;
k2.length=d2.length;
k2.contents= (void *) d2.data;
@@ -224,7 +234,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
free(d2.data);
return (ENOMEM);
}
- k3 = *key;
+ k3 = key->keyblock;
k3.length=d3.length;
k3.contents= (void *) d3.data;
@@ -257,7 +267,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
/* 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 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
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;
diff --git a/src/lib/crypto/builtin/arcfour/arcfour.h b/src/lib/crypto/builtin/arcfour/arcfour.h
index e8ff203ca1..1a2876437d 100644
--- a/src/lib/crypto/builtin/arcfour/arcfour.h
+++ b/src/lib/crypto/builtin/arcfour/arcfour.h
@@ -10,7 +10,7 @@ krb5_arcfour_encrypt_length(const struct krb5_enc_provider *,
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 @@ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *,
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 *,
diff --git a/src/lib/crypto/builtin/arcfour/arcfour_aead.c b/src/lib/crypto/builtin/arcfour/arcfour_aead.c
index cff7d66d65..4896afaaf4 100644
--- a/src/lib/crypto/builtin/arcfour/arcfour_aead.c
+++ b/src/lib/crypto/builtin/arcfour/arcfour_aead.c
@@ -82,7 +82,7 @@ static krb5_error_code
krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
const struct krb5_enc_provider *enc,
const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
+ krb5_key key,
krb5_keyusage usage,
const krb5_data *ivec,
krb5_crypto_iov *data,
@@ -91,6 +91,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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,15 +177,19 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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;
@@ -204,6 +209,7 @@ cleanup:
free(d3.data);
}
+ krb5_k_free_key(NULL, k3key);
return ret;
}
@@ -211,7 +217,7 @@ static krb5_error_code
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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,15 +288,19 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 = krb5_k_create_key(NULL, &k3, &k3key);
if (ret != 0)
goto cleanup;
- ret = enc->decrypt_iov(&k3, ivec, data, num_data);
+ ret = enc->decrypt_iov(k3key, ivec, data, num_data);
if (ret != 0)
goto cleanup;
- ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1);
+ ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1);
if (ret != 0)
goto cleanup;
@@ -314,6 +325,7 @@ cleanup:
free(d3.data);
}
+ krb5_k_free_key(NULL, k3key);
return ret;
}
diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c
index 934bc63a2c..52fb2259d8 100644
--- a/src/lib/crypto/builtin/enc_provider/aes.c
+++ b/src/lib/crypto/builtin/enc_provider/aes.c
@@ -86,7 +86,7 @@ static void xorblock(char *out, const char *in)
}
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 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
/* 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 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key,
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 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key,
}
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 @@ krb5int_aes_decrypt_iov(const krb5_keyblock *key,
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)
diff --git a/src/lib/crypto/builtin/enc_provider/des.c b/src/lib/crypto/builtin/enc_provider/des.c
index 433032dd31..d73a1d2901 100644
--- a/src/lib/crypto/builtin/enc_provider/des.c
+++ b/src/lib/crypto/builtin/enc_provider/des.c
@@ -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 @@ k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des_encrypt_iov(const krb5_keyblock *key,
}
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)
diff --git a/src/lib/crypto/builtin/enc_provider/des3.c b/src/lib/crypto/builtin/enc_provider/des3.c
index 7dba292ae0..eae504b8c3 100644
--- a/src/lib/crypto/builtin/enc_provider/des3.c
+++ b/src/lib/crypto/builtin/enc_provider/des3.c
@@ -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 @@ validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des3_encrypt_iov(const krb5_keyblock *key,
}
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)
diff --git a/src/lib/crypto/builtin/enc_provider/rc4.c b/src/lib/crypto/builtin/enc_provider/rc4.c
index df2c914f88..47c131da4d 100644
--- a/src/lib/crypto/builtin/enc_provider/rc4.c
+++ b/src/lib/crypto/builtin/enc_provider/rc4.c
@@ -29,7 +29,7 @@ static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest,
/* 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 @@ k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key,
/* 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 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
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 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
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 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
/* 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 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key,
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 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key,
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 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key,
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;
diff --git a/src/lib/crypto/builtin/hmac.c b/src/lib/crypto/builtin/hmac.c
index 3bff3cf957..6726a08262 100644
--- a/src/lib/crypto/builtin/hmac.c
+++ b/src/lib/crypto/builtin/hmac.c
@@ -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 @@ cleanup:
}
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 @@ krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key
}
/* 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);
+}
diff --git a/src/lib/crypto/builtin/pbkdf2.c b/src/lib/crypto/builtin/pbkdf2.c
index d897e9a718..9201e23b09 100644
--- a/src/lib/crypto/builtin/pbkdf2.c
+++ b/src/lib/crypto/builtin/pbkdf2.c
@@ -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 @@ static void printd (const char *descr, krb5_data *d) {
}
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 @@ F(char *output, char *u_tmp1, char *u_tmp2,
#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 @@ F(char *output, char *u_tmp1, char *u_tmp2,
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 @@ F(char *output, char *u_tmp1, char *u_tmp2,
}
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 @@ krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,
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 err;
-
- memset(out->data, 0, out->length);
- err = hmac1 (&krb5int_hash_sha1, pass, salt, out);
- 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);
+ 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;
+
+ 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;
}
diff --git a/src/lib/crypto/crypto_tests/Makefile.in b/src/lib/crypto/crypto_tests/Makefile.in
index ab6ebfa4c6..7b240d5783 100644
--- a/src/lib/crypto/crypto_tests/Makefile.in
+++ b/src/lib/crypto/crypto_tests/Makefile.in
@@ -33,6 +33,7 @@ EXTRADEPSRCS=\
$(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_shs: t_shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
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)
diff --git a/src/lib/crypto/crypto_tests/aes-test.c b/src/lib/crypto/crypto_tests/aes-test.c
index c05fd26e3c..8999bd7578 100644
--- a/src/lib/crypto/crypto_tests/aes-test.c
+++ b/src/lib/crypto/crypto_tests/aes-test.c
@@ -50,7 +50,11 @@ static void init()
}
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)
diff --git a/src/lib/crypto/crypto_tests/t_cksum.c b/src/lib/crypto/crypto_tests/t_cksum.c
index 98187f7f16..2b53651197 100644
--- a/src/lib/crypto/crypto_tests/t_cksum.c
+++ b/src/lib/crypto/crypto_tests/t_cksum.c
@@ -75,6 +75,7 @@ main(argc, argv)
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 @@ main(argc, argv)
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 @@ main(argc, argv)
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 @@ main(argc, argv)
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;
diff --git a/src/lib/crypto/crypto_tests/t_cts.c b/src/lib/crypto/crypto_tests/t_cts.c
index aef813273f..fab5b27071 100644
--- a/src/lib/crypto/crypto_tests/t_cts.c
+++ b/src/lib/crypto/crypto_tests/t_cts.c
@@ -114,15 +114,12 @@ static void test_cts()
"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 @@ static void test_cts()
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 @@ static void test_cts()
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 @@ static void test_cts()
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);
diff --git a/src/lib/crypto/crypto_tests/t_encrypt.c b/src/lib/crypto/crypto_tests/t_encrypt.c
index 739c6d3e0b..aac31fb21f 100644
--- a/src/lib/crypto/crypto_tests/t_encrypt.c
+++ b/src/lib/crypto/crypto_tests/t_encrypt.c
@@ -78,12 +78,14 @@ int
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 @@ main ()
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 @@ main ()
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 @@ main ()
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 @@ main ()
}
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);
diff --git a/src/lib/crypto/crypto_tests/t_hmac.c b/src/lib/crypto/crypto_tests/t_hmac.c
index bf629c359f..30830d6173 100644
--- a/src/lib/crypto/crypto_tests/t_hmac.c
+++ b/src/lib/crypto/crypto_tests/t_hmac.c
@@ -98,6 +98,7 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h,
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 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h,
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;
diff --git a/src/lib/crypto/crypto_tests/t_kperf.c b/src/lib/crypto/crypto_tests/t_kperf.c
new file mode 100644
index 0000000000..f56aa3cd15
--- /dev/null
+++ b/src/lib/crypto/crypto_tests/t_kperf.c
@@ -0,0 +1,119 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/crypto_tests/t_kperf.c
+ *
+ * Copyright (C) 2009 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * This file contains a harness to measure the performance improvement
+ * of using the the krb5_k functions (which cache derived keys) over
+ * the equivalent krb5_c functions which do not. Sample usages:
+ *
+ * ./t_kperf ce aes128-cts 10 100000
+ * ./t_kperf kv aes256-cts 1024 10000
+ *
+ * The first usage encrypts ('e') a hundred thousand ten-byte blobs
+ * with aes128-cts, using the non-caching APIs ('c'). The second
+ * usage verifies ('v') ten thousand checksums over 1K blobs with the
+ * first available keyed checksum type for aes256-cts, using the
+ * caching APIs ('k'). Run commands under "time" to measure how much
+ * time is used by the operations.
+ */
+
+#include "k5-int.h"
+
+int
+main(int argc, char **argv)
+{
+ krb5_keyblock kblock;
+ krb5_key key;
+ krb5_enctype enctype;
+ krb5_cksumtype cktype, *cktypelist;
+ int blocksize, num_blocks, intf, op, i;
+ unsigned int count;
+ size_t outlen, cklen;
+ krb5_data block;
+ krb5_enc_data outblock;
+ krb5_checksum sum;
+ krb5_boolean val;
+
+ if (argc != 5) {
+ fprintf(stderr, "Usage: t_kperf {c|k}{e|d|m|v} type size nblocks\n");
+ exit(1);
+ }
+ intf = argv[1][0];
+ assert(intf == 'c' || intf =='k');
+ op = argv[1][1];
+ assert(krb5_string_to_enctype(argv[2], &enctype) == 0);
+ blocksize = atoi(argv[3]);
+ num_blocks = atoi(argv[4]);
+
+ /* Pick the first available keyed checksum type. */
+ krb5_c_keyed_checksum_types(NULL, enctype, &count, &cktypelist);
+ assert(count > 0);
+ cktype = cktypelist[0];
+
+ block.data = "notrandom";
+ block.length = 9;
+ krb5_c_random_seed(NULL, &block);
+
+ krb5_c_make_random_key(NULL, enctype, &kblock);
+ krb5_k_create_key(NULL, &kblock, &key);
+
+ block.length = blocksize;
+ block.data = calloc(1, blocksize);
+
+ krb5_c_encrypt_length(NULL, enctype, blocksize, &outlen);
+ outblock.enctype = enctype;
+ outblock.ciphertext.length = outlen;
+ outblock.ciphertext.data = calloc(1, outlen);
+
+ krb5_c_checksum_length(NULL, cktype, &cklen);
+ sum.checksum_type = cktype;
+ sum.length = cklen;
+ sum.contents = calloc(1, cklen);
+
+ for (i = 0; i < num_blocks; i++) {
+ if (intf == 'c') {
+ if (op == 'e')
+ krb5_c_encrypt(NULL, &kblock, 0, NULL, &block, &outblock);
+ else if (op == 'd')
+ krb5_c_decrypt(NULL, &kblock, 0, NULL, &outblock, &block);
+ else if (op == 'm')
+ krb5_c_make_checksum(NULL, cktype, &kblock, 0, &block, &sum);
+ else if (op == 'v')
+ krb5_c_verify_checksum(NULL, &kblock, 0, &block, &sum, &val);
+ } else {
+ if (op == 'e')
+ krb5_k_encrypt(NULL, key, 0, NULL, &block, &outblock);
+ else if (op == 'd')
+ krb5_k_decrypt(NULL, key, 0, NULL, &outblock, &block);
+ else if (op == 'm')
+ krb5_k_make_checksum(NULL, cktype, key, 0, &block, &sum);
+ else if (op == 'v')
+ krb5_k_verify_checksum(NULL, key, 0, &block, &sum, &val);
+ }
+ }
+ return 0;
+}
diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in
index e64ef8f310..fe96eba852 100644
--- a/src/lib/crypto/krb/Makefile.in
+++ b/src/lib/crypto/krb/Makefile.in
@@ -44,6 +44,7 @@ STLIBOBJS=\
enctype_compare.o \
enctype_to_string.o \
etypes.o \
+ key.o \
keyblocks.o \
keyed_cksum.o \
keyed_checksum_types.o \
@@ -86,6 +87,7 @@ OBJS=\
$(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 @@ SRCS=\
$(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\
diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c
index ac5e7e87c7..3b11da5dc2 100644
--- a/src/lib/crypto/krb/aead.c
+++ b/src/lib/crypto/krb/aead.c
@@ -93,7 +93,7 @@ make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider,
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 @@ krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type,
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 @@ krb5_error_code
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 @@ krb5_error_code
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 @@ krb5_error_code
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)
{
diff --git a/src/lib/crypto/krb/aead.h b/src/lib/crypto/krb/aead.h
index 2c99eb868c..cc43875e25 100644
--- a/src/lib/crypto/krb/aead.h
+++ b/src/lib/crypto/krb/aead.h
@@ -36,7 +36,7 @@ krb5int_c_locate_iov(krb5_crypto_iov *data,
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 @@ krb5_error_code
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 @@ krb5_error_code
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 @@ krb5_error_code
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);
diff --git a/src/lib/crypto/krb/combine_keys.c b/src/lib/crypto/krb/combine_keys.c
index 8c3ea1936e..acfb99bbdb 100644
--- a/src/lib/crypto/krb/combine_keys.c
+++ b/src/lib/crypto/krb/combine_keys.c
@@ -79,7 +79,8 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1,
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,10 +153,14 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1,
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;
@@ -185,7 +190,7 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1,
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 @@ cleanup:
zapfree(rnd, keybytes);
zapfree(combined, keybytes * 2);
zapfree(output, keylength);
+ krb5_k_free_key(NULL, tkey);
return ret;
}
@@ -215,6 +221,7 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
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 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
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 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
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 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
cleanup:
zapfree(inblockdata, blocksize);
zapfree(outblockdata, blocksize);
+ krb5_k_free_key(NULL, key);
return ret;
}
diff --git a/src/lib/crypto/krb/decrypt.c b/src/lib/crypto/krb/decrypt.c
index 29b6ef75ca..36c3bf0ab8 100644
--- a/src/lib/crypto/krb/decrypt.c
+++ b/src/lib/crypto/krb/decrypt.c
@@ -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 @@ krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
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;
+}
diff --git a/src/lib/crypto/krb/decrypt_iov.c b/src/lib/crypto/krb/decrypt_iov.c
index c2f2c0b61c..fcc9973776 100644
--- a/src/lib/crypto/krb/decrypt_iov.c
+++ b/src/lib/crypto/krb/decrypt_iov.c
@@ -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 @@ krb5_c_decrypt_iov(krb5_context context,
{
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 @@ krb5_c_decrypt_iov(krb5_context context,
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;
+}
diff --git a/src/lib/crypto/krb/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c
index fb5622a735..31e7de90ef 100644
--- a/src/lib/crypto/krb/dk/checksum.c
+++ b/src/lib/crypto/krb/dk/checksum.c
@@ -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 @@ krb5_dk_make_checksum(const struct krb5_hash_provider *hash,
* 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 @@ krb5_dk_make_checksum(const struct krb5_hash_provider *hash,
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 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash,
* 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 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash,
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;
}
-
diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c
index 8c8214c125..c2638e804e 100644
--- a/src/lib/crypto/krb/dk/derive.c
+++ b/src/lib/crypto/krb/dk/derive.c
@@ -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 @@ krb5_derive_key(const struct krb5_enc_provider *enc,
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 @@ cleanup:
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 @@ krb5_derive_random(const struct krb5_enc_provider *enc,
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. */
diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h
index 9ddeb408c8..6566ce8d5a 100644
--- a/src/lib/crypto/krb/dk/dk.h
+++ b/src/lib/crypto/krb/dk/dk.h
@@ -32,7 +32,7 @@ void krb5_dk_encrypt_length(const struct krb5_enc_provider *enc,
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 @@ void krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc,
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 krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_error_code krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
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 */
diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c
index 13eb007cdb..5c9c1ad5c7 100644
--- a/src/lib/crypto/krb/dk/dk_aead.c
+++ b/src/lib/crypto/krb/dk/dk_aead.c
@@ -61,7 +61,7 @@ static krb5_error_code
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 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ static krb5_error_code
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 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
/* 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 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
}
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;
}
diff --git a/src/lib/crypto/krb/dk/dk_decrypt.c b/src/lib/crypto/krb/dk/dk_decrypt.c
index 1c0358a2d3..abb7a39b06 100644
--- a/src/lib/crypto/krb/dk/dk_decrypt.c
+++ b/src/lib/crypto/krb/dk/dk_decrypt.c
@@ -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_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
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_dk_decrypt(const struct krb5_enc_provider *enc,
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 @@ krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
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;
diff --git a/src/lib/crypto/krb/dk/dk_encrypt.c b/src/lib/crypto/krb/dk/dk_encrypt.c
index b06079c636..bb045fa6b0 100644
--- a/src/lib/crypto/krb/dk/dk_encrypt.c
+++ b/src/lib/crypto/krb/dk/dk_encrypt.c
@@ -53,20 +53,19 @@ krb5_dk_encrypt_length(const struct krb5_enc_provider *enc,
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,20 +77,9 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc,
/* 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;
-
- ke.contents = kedata;
- ke.length = keylength;
- ki.contents = kidata;
- ki.length = keylength;
+ plaintext = malloc(plainlen);
+ if (plaintext == NULL)
+ return ENOMEM;
/* Derive the keys. */
@@ -134,7 +122,7 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc,
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 @@ trunc_hmac (const struct krb5_hash_provider *hash,
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,20 +224,9 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
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;
-
- ke.contents = kedata;
- ke.length = keylength;
- ki.contents = kidata;
- ki.length = keylength;
+ plaintext = malloc(plainlen);
+ if (plaintext == NULL)
+ return ENOMEM;
/* Derive the keys. */
@@ -294,7 +270,7 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
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;
}
diff --git a/src/lib/crypto/krb/dk/stringtokey.c b/src/lib/crypto/krb/dk/stringtokey.c
index 3265657583..48b053ad9c 100644
--- a/src/lib/crypto/krb/dk/stringtokey.c
+++ b/src/lib/crypto/krb/dk/stringtokey.c
@@ -32,15 +32,16 @@ static const unsigned char kerberos[] = "kerberos";
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,10 +68,14 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
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;
@@ -79,13 +84,14 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
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;
}
diff --git a/src/lib/crypto/krb/encrypt.c b/src/lib/crypto/krb/encrypt.c
index 741485a314..3c39838cf5 100644
--- a/src/lib/crypto/krb/encrypt.c
+++ b/src/lib/crypto/krb/encrypt.c
@@ -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 @@ krb5_c_encrypt(krb5_context context, const krb5_keyblock *key,
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;
+}
diff --git a/src/lib/crypto/krb/encrypt_iov.c b/src/lib/crypto/krb/encrypt_iov.c
index 21242bca2c..b7b2f58145 100644
--- a/src/lib/crypto/krb/encrypt_iov.c
+++ b/src/lib/crypto/krb/encrypt_iov.c
@@ -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 @@ krb5_c_encrypt_iov(krb5_context context,
{
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 @@ krb5_c_encrypt_iov(krb5_context context,
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;
+}
diff --git a/src/lib/crypto/krb/etypes.h b/src/lib/crypto/krb/etypes.h
index 8d83b4200f..edaa00caea 100644
--- a/src/lib/crypto/krb/etypes.h
+++ b/src/lib/crypto/krb/etypes.h
@@ -33,7 +33,7 @@ typedef void (*krb5_encrypt_length_func)(const struct krb5_enc_provider *enc,
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_str2key_func)(const struct
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 {
diff --git a/src/lib/crypto/krb/key.c b/src/lib/crypto/krb/key.c
new file mode 100644
index 0000000000..4ea72b478f
--- /dev/null
+++ b/src/lib/crypto/krb/key.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2009 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * Functions for manipulating krb5_key structures
+ */
+
+#include "k5-int.h"
+
+/*
+ * The krb5_key data type wraps an exposed keyblock in an opaque data
+ * structure, to allow for internal optimizations such as caching of
+ * derived keys.
+ */
+
+/* Create a krb5_key from the enctype and key data in a keyblock. */
+krb5_error_code KRB5_CALLCONV
+krb5_k_create_key(krb5_context context, const krb5_keyblock *key_data,
+ krb5_key *out)
+{
+ krb5_key key = NULL;
+ krb5_error_code code;
+
+ *out = NULL;
+
+ key = malloc(sizeof(*key));
+ if (key == NULL)
+ return ENOMEM;
+ code = krb5int_c_copy_keyblock_contents(context, key_data, &key->keyblock);
+ if (code)
+ goto cleanup;
+
+ key->refcount = 1;
+ key->derived = NULL;
+ *out = key;
+ return 0;
+
+cleanup:
+ free(key);
+ return code;
+}
+
+void KRB5_CALLCONV
+krb5_k_reference_key(krb5_context context, krb5_key key)
+{
+ key->refcount++;
+}
+
+/* Free the memory used by a krb5_key. */
+void KRB5_CALLCONV
+krb5_k_free_key(krb5_context context, krb5_key key)
+{
+ struct derived_key *dk;
+
+ if (key == NULL || --key->refcount > 0)
+ return;
+
+ /* Free the derived key cache. */
+ while ((dk = key->derived) != NULL) {
+ key->derived = dk->next;
+ krb5_k_free_key(context, dk->dkey);
+ free(dk);
+ }
+ krb5int_c_free_keyblock_contents(context, &key->keyblock);
+}
+
+/* Retrieve a copy of the keyblock from a krb5_key. */
+krb5_error_code KRB5_CALLCONV
+krb5_k_key_keyblock(krb5_context context, krb5_key key,
+ krb5_keyblock **key_data)
+{
+ return krb5int_c_copy_keyblock(context, &key->keyblock, key_data);
+}
+
+/* Retrieve the enctype of a krb5_key. */
+krb5_enctype KRB5_CALLCONV
+krb5_k_key_enctype(krb5_context context, krb5_key key)
+{
+ return key->keyblock.enctype;
+}
diff --git a/src/lib/crypto/krb/keyblocks.c b/src/lib/crypto/krb/keyblocks.c
index ee88f9a8a9..51e31d3015 100644
--- a/src/lib/crypto/krb/keyblocks.c
+++ b/src/lib/crypto/krb/keyblocks.c
@@ -62,7 +62,6 @@ krb5int_c_init_keyblock(krb5_context context, krb5_enctype enctype,
return 0;
}
-
void
krb5int_c_free_keyblock(krb5_context context, register krb5_keyblock *val)
{
@@ -78,3 +77,38 @@ krb5int_c_free_keyblock_contents(krb5_context context, krb5_keyblock *key)
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;
+}
diff --git a/src/lib/crypto/krb/keyhash_provider/descbc.c b/src/lib/crypto/krb/keyhash_provider/descbc.c
index bf68e324ce..b08e30b7c6 100644
--- a/src/lib/crypto/krb/keyhash_provider/descbc.c
+++ b/src/lib/crypto/krb/keyhash_provider/descbc.c
@@ -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 @@ k5_descbc_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i
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:
diff --git a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c
index 34ce67169e..61c6d8c21d 100644
--- a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c
+++ b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c
@@ -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 @@ k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage,
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 @@ k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage,
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 @@ k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage,
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 @@ k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage,
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;
}
diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
index 49700a89d4..1514dccc67 100644
--- a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
+++ b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c
@@ -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 @@ k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i
}
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 @@ k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage,
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 @@ k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage,
}
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 */
diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
index 24d6317060..e7a84e2a85 100644
--- a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
+++ b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c
@@ -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 @@ k5_md5des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i
}
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 @@ k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data
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 @@ k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data
}
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 */
diff --git a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c
index d05b97f00d..589c3475ed 100644
--- a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c
+++ b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c
@@ -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)
{
diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c
index ca4ca58056..dd34df3770 100644
--- a/src/lib/crypto/krb/make_checksum.c
+++ b/src/lib/crypto/krb/make_checksum.c
@@ -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 @@ krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
/* 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 @@ cleanup:
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;
+}
diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c
index a16b849c05..32c9a4cb4f 100644
--- a/src/lib/crypto/krb/make_checksum_iov.c
+++ b/src/lib/crypto/krb/make_checksum_iov.c
@@ -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 @@ krb5_c_make_checksum_iov(krb5_context context,
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;
+}
diff --git a/src/lib/crypto/krb/old/old.h b/src/lib/crypto/krb/old/old.h
index 94ee6421e8..6cfb0c97ad 100644
--- a/src/lib/crypto/krb/old/old.h
+++ b/src/lib/crypto/krb/old/old.h
@@ -34,14 +34,14 @@ void krb5_old_encrypt_length
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);
diff --git a/src/lib/crypto/krb/old/old_decrypt.c b/src/lib/crypto/krb/old/old_decrypt.c
index cfbbd7272a..dd9ad19cb3 100644
--- a/src/lib/crypto/krb/old/old_decrypt.c
+++ b/src/lib/crypto/krb/old/old_decrypt.c
@@ -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 @@ krb5_old_decrypt(const struct krb5_enc_provider *enc,
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;
}
diff --git a/src/lib/crypto/krb/old/old_encrypt.c b/src/lib/crypto/krb/old/old_encrypt.c
index 98bd109e0e..1121dc935e 100644
--- a/src/lib/crypto/krb/old/old_encrypt.c
+++ b/src/lib/crypto/krb/old/old_encrypt.c
@@ -44,7 +44,7 @@ krb5_old_encrypt_length(const struct krb5_enc_provider *enc,
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 @@ krb5_old_encrypt(const struct krb5_enc_provider *enc,
/* 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
diff --git a/src/lib/crypto/krb/prf.c b/src/lib/crypto/krb/prf.c
index d2c633e757..12ec22b65b 100644
--- a/src/lib/crypto/krb/prf.c
+++ b/src/lib/crypto/krb/prf.c
@@ -50,15 +50,17 @@ krb5_c_prf_length(krb5_context context, krb5_enctype enctype, size_t *len)
}
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 @@ krb5_c_prf(krb5_context context, const krb5_keyblock *key,
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;
}
diff --git a/src/lib/crypto/krb/prf/des_prf.c b/src/lib/crypto/krb/prf/des_prf.c
index 869f2e0bf6..dd9907bda4 100644
--- a/src/lib/crypto/krb/prf/des_prf.c
+++ b/src/lib/crypto/krb/prf/des_prf.c
@@ -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;
diff --git a/src/lib/crypto/krb/prf/dk_prf.c b/src/lib/crypto/krb/prf/dk_prf.c
index cc3e2d9341..cc203875cb 100644
--- a/src/lib/crypto/krb/prf/dk_prf.c
+++ b/src/lib/crypto/krb/prf/dk_prf.c
@@ -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 @@ krb5int_dk_prf (const struct krb5_enc_provider *enc,
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;
}
diff --git a/src/lib/crypto/krb/prf/prf_int.h b/src/lib/crypto/krb/prf/prf_int.h
index 180ce027d9..97bbf049d0 100644
--- a/src/lib/crypto/krb/prf/prf_int.h
+++ b/src/lib/crypto/krb/prf/prf_int.h
@@ -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*/
diff --git a/src/lib/crypto/krb/prf/rc4_prf.c b/src/lib/crypto/krb/prf/rc4_prf.c
index 2b1b73f914..3affaa5398 100644
--- a/src/lib/crypto/krb/prf/rc4_prf.c
+++ b/src/lib/crypto/krb/prf/rc4_prf.c
@@ -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);
diff --git a/src/lib/crypto/krb/raw/raw.h b/src/lib/crypto/krb/raw/raw.h
index f4b7d5f0b7..84ae730238 100644
--- a/src/lib/crypto/krb/raw/raw.h
+++ b/src/lib/crypto/krb/raw/raw.h
@@ -34,14 +34,14 @@ void krb5_raw_encrypt_length
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);
diff --git a/src/lib/crypto/krb/raw/raw_aead.c b/src/lib/crypto/krb/raw/raw_aead.c
index f52fe000d1..68070d1daa 100644
--- a/src/lib/crypto/krb/raw/raw_aead.c
+++ b/src/lib/crypto/krb/raw/raw_aead.c
@@ -54,7 +54,7 @@ static krb5_error_code
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 @@ static krb5_error_code
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,
diff --git a/src/lib/crypto/krb/raw/raw_decrypt.c b/src/lib/crypto/krb/raw/raw_decrypt.c
index 767da1f9fa..dd62806e4e 100644
--- a/src/lib/crypto/krb/raw/raw_decrypt.c
+++ b/src/lib/crypto/krb/raw/raw_decrypt.c
@@ -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)
{
diff --git a/src/lib/crypto/krb/raw/raw_encrypt.c b/src/lib/crypto/krb/raw/raw_encrypt.c
index 68b819c016..462239ee59 100644
--- a/src/lib/crypto/krb/raw/raw_encrypt.c
+++ b/src/lib/crypto/krb/raw/raw_encrypt.c
@@ -42,7 +42,7 @@ krb5_raw_encrypt_length(const struct krb5_enc_provider *enc,
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)
{
diff --git a/src/lib/crypto/krb/verify_checksum.c b/src/lib/crypto/krb/verify_checksum.c
index 4466c7dadf..82f4fb11f1 100644
--- a/src/lib/crypto/krb/verify_checksum.c
+++ b/src/lib/crypto/krb/verify_checksum.c
@@ -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 @@ krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key,
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 @@ krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key,
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;
+}
diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c
index 341c89684f..f322dc386c 100644
--- a/src/lib/crypto/krb/verify_checksum_iov.c
+++ b/src/lib/crypto/krb/verify_checksum_iov.c
@@ -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 @@ krb5_c_verify_checksum_iov(krb5_context context,
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;
+}
diff --git a/src/lib/crypto/krb/yarrow/ycipher.c b/src/lib/crypto/krb/yarrow/ycipher.c
index 2af410440d..84cadd13fb 100644
--- a/src/lib/crypto/krb/yarrow/ycipher.c
+++ b/src/lib/crypto/krb/yarrow/ycipher.c
@@ -42,27 +42,28 @@ krb5int_yarrow_cipher_init
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 @@ int krb5int_yarrow_cipher_encrypt_block
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 @@ krb5int_yarrow_cipher_final
(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;
}
diff --git a/src/lib/crypto/krb/yarrow/ycipher.h b/src/lib/crypto/krb/yarrow/ycipher.h
index 96999c0dbb..ad0d307fcb 100644
--- a/src/lib/crypto/krb/yarrow/ycipher.h
+++ b/src/lib/crypto/krb/yarrow/ycipher.h
@@ -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.
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 4ea46fa193..953497e176 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -72,6 +72,18 @@ krb5_finish_random_key
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_aes_string_to_key
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_crc32
krb5int_hash_md4
krb5int_hash_md5
krb5int_hash_sha1
+krb5int_hmac_keyblock
krb5int_keyhash_descbc
krb5int_keyhash_hmac_md5
krb5int_keyhash_md4des
diff --git a/src/lib/crypto/openssl/aes/aes_s2k.c b/src/lib/crypto/openssl/aes/aes_s2k.c
index 1383be11a2..db6553e25a 100644
--- a/src/lib/crypto/openssl/aes/aes_s2k.c
+++ b/src/lib/crypto/openssl/aes/aes_s2k.c
@@ -44,6 +44,7 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc,
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 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc,
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;
}
diff --git a/src/lib/crypto/openssl/arcfour/arcfour.c b/src/lib/crypto/openssl/arcfour/arcfour.c
index 687f276b01..2c89b99b82 100644
--- a/src/lib/crypto/openssl/arcfour/arcfour.c
+++ b/src/lib/crypto/openssl/arcfour/arcfour.c
@@ -65,11 +65,12 @@ case 7: /* tgs-req authenticator */
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 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
free(d1.data);
return (ENOMEM);
}
- k2 = *key;
+ k2 = key->keyblock;
k2.length=d2.length;
k2.contents=(void *) d2.data;
@@ -105,7 +106,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
free(d2.data);
return (ENOMEM);
}
- k3 = *key;
+ k3 = key->keyblock;
k3.length=d3.length;
k3.contents= (void *) d3.data;
@@ -141,7 +142,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
/* 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 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
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,11 +161,19 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
if (ret)
goto cleanup;
- krb5_hmac(hash, &k2, 1, &plaintext, &checksum);
+ ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum);
+ if (ret)
+ goto cleanup;
+
+ ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3);
+ if (ret)
+ goto cleanup;
- krb5_hmac(hash, &k1, 1, &checksum, &d3);
+ ret = krb5_k_create_key(NULL, &k3, &k3key);
+ if (ret)
+ goto cleanup;
- ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext);
+ ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext);
cleanup:
memset(d1.data, 0, d1.length);
@@ -185,11 +194,12 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
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 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
free(d1.data);
return (ENOMEM);
}
- k2 = *key;
+ k2 = key->keyblock;
k2.length=d2.length;
k2.contents= (void *) d2.data;
@@ -225,7 +235,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
free(d2.data);
return (ENOMEM);
}
- k3 = *key;
+ k3 = key->keyblock;
k3.length=d3.length;
k3.contents= (void *) d3.data;
@@ -258,7 +268,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
/* 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 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
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;
diff --git a/src/lib/crypto/openssl/arcfour/arcfour.h b/src/lib/crypto/openssl/arcfour/arcfour.h
index be408febc6..1a2876437d 100644
--- a/src/lib/crypto/openssl/arcfour/arcfour.h
+++ b/src/lib/crypto/openssl/arcfour/arcfour.h
@@ -10,7 +10,7 @@ krb5_arcfour_encrypt_length(const struct krb5_enc_provider *,
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 @@ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *,
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 krb5_error_code krb5int_arcfour_string_to_key(
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 */
diff --git a/src/lib/crypto/openssl/arcfour/arcfour_aead.c b/src/lib/crypto/openssl/arcfour/arcfour_aead.c
index cff7d66d65..4896afaaf4 100644
--- a/src/lib/crypto/openssl/arcfour/arcfour_aead.c
+++ b/src/lib/crypto/openssl/arcfour/arcfour_aead.c
@@ -82,7 +82,7 @@ static krb5_error_code
krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
const struct krb5_enc_provider *enc,
const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
+ krb5_key key,
krb5_keyusage usage,
const krb5_data *ivec,
krb5_crypto_iov *data,
@@ -91,6 +91,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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,15 +177,19 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead,
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;
@@ -204,6 +209,7 @@ cleanup:
free(d3.data);
}
+ krb5_k_free_key(NULL, k3key);
return ret;
}
@@ -211,7 +217,7 @@ static krb5_error_code
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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,15 +288,19 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead,
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 = krb5_k_create_key(NULL, &k3, &k3key);
if (ret != 0)
goto cleanup;
- ret = enc->decrypt_iov(&k3, ivec, data, num_data);
+ ret = enc->decrypt_iov(k3key, ivec, data, num_data);
if (ret != 0)
goto cleanup;
- ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1);
+ ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1);
if (ret != 0)
goto cleanup;
@@ -314,6 +325,7 @@ cleanup:
free(d3.data);
}
+ krb5_k_free_key(NULL, k3key);
return ret;
}
diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c
index 81d3063003..76f81d41e1 100644
--- a/src/lib/crypto/openssl/enc_provider/aes.c
+++ b/src/lib/crypto/openssl/enc_provider/aes.c
@@ -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 @@ map_mode(unsigned int len)
}
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 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ cts_enc(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cts_enc(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ cts_decr(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ cts_decr(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ cts_encr_iov(const krb5_keyblock *key,
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 @@ cts_encr_iov(const krb5_keyblock *key,
}
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 @@ cts_decr_iov(const krb5_keyblock *key,
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 @@ cts_decr_iov(const krb5_keyblock *key,
}
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 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key,
}
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)
diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
index 4965c6e6fa..a4208eefcb 100644
--- a/src/lib/crypto/openssl/enc_provider/des.c
+++ b/src/lib/crypto/openssl/enc_provider/des.c
@@ -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 @@ validate(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des_encrypt_iov(const krb5_keyblock *key,
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 @@ k5_des_encrypt_iov(const krb5_keyblock *key,
}
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 @@ k5_des_decrypt_iov(const krb5_keyblock *key,
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)
diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
index 1dec8e27e2..e20e42e23d 100644
--- a/src/lib/crypto/openssl/enc_provider/des3.c
+++ b/src/lib/crypto/openssl/enc_provider/des3.c
@@ -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 @@ validate(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
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 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
}
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 @@ k5_des3_encrypt_iov(const krb5_keyblock *key,
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 @@ k5_des3_encrypt_iov(const krb5_keyblock *key,
}
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 @@ k5_des3_decrypt_iov(const krb5_keyblock *key,
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);
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index ae2f58f406..fd1c7238d6 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -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 @@ k5_arcfour_init_state (const krb5_keyblock *key,
/* 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 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
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 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
/* 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 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key,
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);
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index e0c8dec796..658bc28f10 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -32,8 +32,9 @@ map_digest(const struct krb5_hash_provider *hash)
}
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_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key,
}
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 @@ krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key
}
/* 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);
+}
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 934302cffd..6c141ae99e 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -437,6 +437,7 @@ kg_accept_krb5(minor_status, context_handle,
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 @@ kg_accept_krb5(minor_status, context_handle,
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 @@ kg_accept_krb5(minor_status, context_handle,
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 @@ kg_accept_krb5(minor_status, context_handle,
/* 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 @@ fail:
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;
diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c
index e2da3dc986..2032d5585e 100644
--- a/src/lib/gssapi/krb5/delete_sec_context.c
+++ b/src/lib/gssapi/krb5/delete_sec_context.c
@@ -82,19 +82,19 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token)
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)
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index e05c5bc81f..541a745545 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -190,15 +190,14 @@ typedef struct _krb5_gss_ctx_id_rec {
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 @@ typedef struct _krb5_gss_ctx_id_rec {
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 @@ krb5_error_code kg_checksum_channel_bindings
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 (krb5_context context,
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 @@ kg_arcfour_docrypt_iov (krb5_context context,
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 (krb5_context context,
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 @@ void kg_release_iov(gss_iov_buffer_desc *iov,
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_v1(krb5_context context,
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_make_checksum_iov_v3(krb5_context context,
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,
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 62e7d6ed73..e04818f760 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -482,6 +482,7 @@ kg_new_connection(
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 @@ kg_new_connection(
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 @@ fail:
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 @@ mutual_auth(
* 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 @@ mutual_auth(
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;
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
index fbc389245c..eaf1c4d02b 100644
--- a/src/lib/gssapi/krb5/inq_context.c
+++ b/src/lib/gssapi/krb5/inq_context.c
@@ -187,7 +187,7 @@ gss_krb5int_inq_session_key(
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 @@ gss_krb5int_inq_session_key(
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 @@ gss_krb5int_inq_session_key(
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;
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index 1949020ab1..7a6e5aae8f 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -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 @@ make_seal_token_v1 (krb5_context context,
(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 @@ make_seal_token_v1 (krb5_context context,
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 @@ make_seal_token_v1 (krb5_context context,
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);
diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c
index f4354a9f3d..1a9eac994a 100644
--- a/src/lib/gssapi/krb5/k5sealiov.c
+++ b/src/lib/gssapi/krb5/k5sealiov.c
@@ -193,7 +193,7 @@ make_seal_token_v1_iov(krb5_context context,
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 @@ make_seal_token_v1_iov(krb5_context context,
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 @@ kg_seal_iov_length(OM_uint32 *minor_status,
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 ?
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
index 26e20d73b4..ad5c03a398 100644
--- a/src/lib/gssapi/krb5/k5sealv3.c
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -81,7 +81,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
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 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
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 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
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 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
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 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
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 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
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 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
}
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 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
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;
diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c
index c30352b0a5..b5b979310f 100644
--- a/src/lib/gssapi/krb5/k5sealv3iov.c
+++ b/src/lib/gssapi/krb5/k5sealv3iov.c
@@ -53,7 +53,7 @@ gss_krb5int_make_seal_token_v3_iov(krb5_context context,
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 @@ gss_krb5int_make_seal_token_v3_iov(krb5_context context,
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_krb5int_make_seal_token_v3_iov(krb5_context context,
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 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
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 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
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);
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index f55180af86..2ef59a7224 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -176,7 +176,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
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 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
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 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
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 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
(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 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
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);
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
index 5d2bd1afa5..d09bf89a45 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -153,7 +153,7 @@ kg_unseal_v1_iov(krb5_context context,
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 @@ kg_unseal_v1_iov(krb5_context context,
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 @@ kg_unseal_stream_iov(OM_uint32 *minor_status,
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;
diff --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c
index cefac261ed..fb5a8e7877 100644
--- a/src/lib/gssapi/krb5/lucid_context.c
+++ b/src/lib/gssapi/krb5/lucid_context.c
@@ -213,7 +213,7 @@ make_external_lucid_ctx_v1(
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 @@ make_external_lucid_ctx_v1(
/* 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;
diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 9b55a65077..bdcd7685ef 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -304,19 +304,19 @@ kg_ctx_size(kcontext, arg, sizep)
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 @@ kg_ctx_size(kcontext, arg, sizep)
&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 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
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 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
&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 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
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 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
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 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
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 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
*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)
diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c
index fc6c849c95..9d4e08ff81 100644
--- a/src/lib/gssapi/krb5/util_cksum.c
+++ b/src/lib/gssapi/krb5/util_cksum.c
@@ -112,8 +112,8 @@ krb5_error_code
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 @@ kg_make_checksum_iov_v1(krb5_context context,
/* 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 @@ kg_make_checksum_iov_v1(krb5_context context,
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 @@ static krb5_error_code
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 @@ checksum_iov_v3(krb5_context context,
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 @@ checksum_iov_v3(krb5_context context,
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 @@ 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)
@@ -284,7 +284,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,
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index 87e04065fa..53e420d9fa 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -59,39 +59,53 @@ static const char kg_arcfour_l40[] = "fortybits";
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;
+}
+
+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_copy_keyblock(context, subkey, &ctx->seq);
+ 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 @@ kg_setup_keys(krb5_context context,
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;
+
+ krb5_k_free_key(context, ctx->enc);
+ code = kg_derive_des_enc_key(context, subkey, &ctx->enc);
if (code != 0)
return code;
- ctx->enc->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->seq->enctype = ENCTYPE_DES_CBC_RAW;
+ 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 @@ kg_setup_keys(krb5_context context,
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 @@ kg_confounder_size(context, key)
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 @@ kg_make_confounder(context, key, buf)
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 @@ kg_encrypt(context, key, usage, iv, in, out, length)
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 @@ kg_encrypt(context, key, usage, iv, in, out, length)
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 @@ kg_encrypt(context, key, usage, iv, in, out, length)
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 @@ kg_decrypt(context, key, usage, iv, in, out, length)
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 @@ kg_decrypt(context, key, usage, iv, in, out, length)
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 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage,
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 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage,
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 @@ cleanup_arcfour:
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 @@ kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count)
*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 @@ kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pki
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 @@ kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pki
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 @@ kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, pkiov,
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 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun
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 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun
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 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun
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 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun
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 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun
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 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun
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 @@ kg_arcfour_docrypt_iov (krb5_context context,
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 @@ kg_arcfour_docrypt_iov (krb5_context context,
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);
diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c
index b559f5e088..5c696ea3b5 100644
--- a/src/lib/gssapi/krb5/util_seed.c
+++ b/src/lib/gssapi/krb5/util_seed.c
@@ -31,25 +31,31 @@ static const unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
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 = krb5_k_create_key(context, tmpkey, &rkey);
+ if (code)
+ goto cleanup;
- code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
+ 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);
}
diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c
index b91dd658c0..388990a30c 100644
--- a/src/lib/gssapi/krb5/util_seqnum.c
+++ b/src/lib/gssapi/krb5/util_seqnum.c
@@ -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 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
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 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
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 kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
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 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
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]) |
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
index 7fa9c44d66..0b90bba00b 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -114,10 +114,12 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
/* 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--;
diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c
index b88219cdb1..ee31fb82b5 100644
--- a/src/lib/krb5/krb/auth_con.c
+++ b/src/lib/krb5/krb/auth_con.c
@@ -56,12 +56,12 @@ krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
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_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb
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_error_code KRB5_CALLCONV
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_error_code KRB5_CALLCONV
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_error_code KRB5_CALLCONV
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_error_code KRB5_CALLCONV
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_error_code KRB5_CALLCONV
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;
diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h
index 6254ac67c2..684eb4e407 100644
--- a/src/lib/krb5/krb/auth_con.h
+++ b/src/lib/krb5/krb/auth_con.h
@@ -8,9 +8,9 @@ struct _krb5_auth_context {
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;
diff --git a/src/lib/krb5/krb/copy_key.c b/src/lib/krb5/krb/copy_key.c
index f926b4f369..4772c58c16 100644
--- a/src/lib/krb5/krb/copy_key.c
+++ b/src/lib/krb5/krb/copy_key.c
@@ -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);
}
diff --git a/src/lib/krb5/krb/cp_key_cnt.c b/src/lib/krb5/krb/cp_key_cnt.c
index fb90bfac13..74efb5ef1d 100644
--- a/src/lib/krb5/krb/cp_key_cnt.c
+++ b/src/lib/krb5/krb/cp_key_cnt.c
@@ -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);
}
diff --git a/src/lib/krb5/krb/enc_helper.c b/src/lib/krb5/krb/enc_helper.c
index 34aa612d6c..01324d0147 100644
--- a/src/lib/krb5/krb/enc_helper.c
+++ b/src/lib/krb5/krb/enc_helper.c
@@ -48,3 +48,28 @@ krb5_encrypt_helper(krb5_context context, const krb5_keyblock *key, krb5_keyusag
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;
+}
diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c
index f17a148583..6ce0e354e5 100644
--- a/src/lib/krb5/krb/mk_cred.c
+++ b/src/lib/krb5/krb/mk_cred.c
@@ -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 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart,
* 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 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart,
}
/* 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 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart,
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 @@ krb5_mk_ncred_basic(krb5_context context,
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_mk_ncred(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context,
}
/* 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 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context,
}
/* 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;
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 30ffec3e19..824bfd507c 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -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 @@ krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata,
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 @@ krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata,
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 @@ krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata,
/* 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_mk_priv(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_mk_priv(krb5_context context, krb5_auth_context auth_context,
}
}
- 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();
diff --git a/src/lib/krb5/krb/mk_rep.c b/src/lib/krb5/krb/mk_rep.c
index 29155b6e11..a4dbc467f4 100644
--- a/src/lib/krb5/krb/mk_rep.c
+++ b/src/lib/krb5/krb/mk_rep.c
@@ -80,7 +80,8 @@ k5_mk_rep(krb5_context context, krb5_auth_context auth_context,
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 @@ k5_mk_rep(krb5_context context, krb5_auth_context auth_context,
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 @@ k5_mk_rep(krb5_context context, krb5_auth_context auth_context,
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))) {
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index df5ac28724..4277f1eec8 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -73,7 +73,7 @@ make_etype_list(krb5_context context,
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 @@ krb5int_generate_and_save_subkey (krb5_context context,
} 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 @@ krb5int_generate_and_save_subkey (krb5_context context,
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 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
*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 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
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 @@ cleanup:
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 @@ krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent,
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
diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c
index 23358b957f..f3bfde390e 100644
--- a/src/lib/krb5/krb/mk_safe.c
+++ b/src/lib/krb5/krb/mk_safe.c
@@ -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 @@ krb5_mk_safe_basic(krb5_context context, const krb5_data *userdata,
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_mk_safe(krb5_context context, krb5_auth_context auth_context,
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_mk_safe(krb5_context context, krb5_auth_context auth_context,
}
{
+ 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 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context,
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();
diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c
index 48637450dc..a5d00dc4ea 100644
--- a/src/lib/krb5/krb/rd_cred.c
+++ b/src/lib/krb5/krb/rd_cred.c
@@ -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 @@ decrypt_credencdata(krb5_context context, krb5_cred *pcred,
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 @@ cleanup:
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 @@ krb5_rd_cred_basic(krb5_context context, krb5_data *pcreddata,
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_rd_cred(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context,
/*
- * 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;
}
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index eaeaed894b..9b84ad87ae 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -54,8 +54,7 @@ Returns system errors, integrity errors.
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_rd_priv_basic(krb5_context context, const krb5_data *inbuf,
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 @@ krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf,
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 @@ krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf,
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_rd_priv(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_rd_priv(krb5_context context, krb5_auth_context auth_context,
}
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,
diff --git a/src/lib/krb5/krb/rd_rep.c b/src/lib/krb5/krb/rd_rep.c
index 1e3c145263..6e9cb08088 100644
--- a/src/lib/krb5/krb/rd_rep.c
+++ b/src/lib/krb5/krb/rd_rep.c
@@ -95,7 +95,7 @@ krb5_rd_rep(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_rd_rep(krb5_context context, krb5_auth_context auth_context,
/* 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 @@ krb5_rd_rep_dce(krb5_context context, krb5_auth_context auth_context,
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;
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index 6edf6d7600..48503d333f 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -238,16 +238,17 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
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 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
(*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 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
(*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 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
*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;
}
diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c
index 989c222427..68c13317c5 100644
--- a/src/lib/krb5/krb/rd_safe.c
+++ b/src/lib/krb5/krb/rd_safe.c
@@ -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 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf,
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 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf,
* 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_rd_safe(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context,
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 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context,
}
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();
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
index 487455b9d6..65b7e27291 100644
--- a/src/lib/krb5/krb/ser_actx.c
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -75,6 +75,7 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
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 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
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 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
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 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
/* 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 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
/* 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 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
size_t remain;
size_t obuf;
krb5_int32 obuf32;
+ krb5_enctype enctype;
required = 0;
bp = *buffer;
@@ -224,9 +226,8 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
/* 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 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
}
/* 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 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
(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 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
(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 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
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 @@ krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_oc
/* 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 {
/*
diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c
index bb66568db0..5575687dd4 100644
--- a/src/lib/krb5/os/accessor.c
+++ b/src/lib/krb5/os/accessor.c
@@ -52,7 +52,7 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)
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),