diff options
author | Greg Hudson <ghudson@mit.edu> | 2009-10-19 20:04:21 +0000 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2009-10-19 20:04:21 +0000 |
commit | e6b93b7dd43bb765900b2db71641479b597844da (patch) | |
tree | 2b6da09e37da6ca699a8cb43c87e8a4218132254 /src/lib/crypto/krb/dk | |
parent | 04a5d19e61bedbb1da4db52334c00f7a54a9d5a8 (diff) | |
download | krb5-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.c | 53 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/derive.c | 108 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk.h | 23 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk_aead.c | 47 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk_decrypt.c | 35 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/dk_encrypt.c | 70 | ||||
-rw-r--r-- | src/lib/crypto/krb/dk/stringtokey.c | 22 |
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; } |