diff options
Diffstat (limited to 'src/lib/crypto/krb')
41 files changed, 622 insertions, 302 deletions
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. |