aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto/krb/dk
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-10-19 20:04:21 +0000
committerGreg Hudson <ghudson@mit.edu>2009-10-19 20:04:21 +0000
commite6b93b7dd43bb765900b2db71641479b597844da (patch)
tree2b6da09e37da6ca699a8cb43c87e8a4218132254 /src/lib/crypto/krb/dk
parent04a5d19e61bedbb1da4db52334c00f7a54a9d5a8 (diff)
downloadkrb5-e6b93b7dd43bb765900b2db71641479b597844da.zip
krb5-e6b93b7dd43bb765900b2db71641479b597844da.tar.gz
krb5-e6b93b7dd43bb765900b2db71641479b597844da.tar.bz2
Implement new APIs to allow improved crypto performance
Merge branches/enc-perf to trunk. Adds the krb5_key opaque type, the krb5_k_* APIs to use them, and caching of derived keys when krb5_k_* functions are used. Updates the krb5 auth context and GSS id-rec to use krb5_keys. ticket: 6576 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22944 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto/krb/dk')
-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
7 files changed, 189 insertions, 169 deletions
diff --git a/src/lib/crypto/krb/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c
index fb5622a..31e7de9 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 8c8214c..c2638e8 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 9ddeb40..6566ce8 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 13eb007..5c9c1ad 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 1c0358a..abb7a39 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 b06079c..bb045fa 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 3265657..48b053a 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;
}