From e6b93b7dd43bb765900b2db71641479b597844da Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Mon, 19 Oct 2009 20:04:21 +0000 Subject: [PATCH] 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 --- src/include/k5-int.h | 62 ++++++-- src/include/krb5/krb5.hin | 69 +++++++++ src/lib/crypto/builtin/aes/aes_s2k.c | 29 ++-- src/lib/crypto/builtin/arcfour/arcfour.c | 50 ++++--- src/lib/crypto/builtin/arcfour/arcfour.h | 4 +- src/lib/crypto/builtin/arcfour/arcfour_aead.c | 48 ++++--- src/lib/crypto/builtin/enc_provider/aes.c | 20 +-- src/lib/crypto/builtin/enc_provider/des.c | 24 ++-- src/lib/crypto/builtin/enc_provider/des3.c | 22 +-- src/lib/crypto/builtin/enc_provider/rc4.c | 22 +-- src/lib/crypto/builtin/hmac.c | 39 ++++- src/lib/crypto/builtin/pbkdf2.c | 135 +++++++++--------- src/lib/crypto/crypto_tests/Makefile.in | 4 + src/lib/crypto/crypto_tests/aes-test.c | 6 +- src/lib/crypto/crypto_tests/t_cksum.c | 9 +- src/lib/crypto/crypto_tests/t_cts.c | 23 +-- src/lib/crypto/crypto_tests/t_encrypt.c | 128 +++++++++++------ src/lib/crypto/crypto_tests/t_hmac.c | 5 +- src/lib/crypto/crypto_tests/t_kperf.c | 119 +++++++++++++++ src/lib/crypto/krb/Makefile.in | 3 + src/lib/crypto/krb/aead.c | 10 +- src/lib/crypto/krb/aead.h | 8 +- src/lib/crypto/krb/combine_keys.c | 23 ++- src/lib/crypto/krb/decrypt.c | 20 ++- src/lib/crypto/krb/decrypt_iov.c | 25 +++- src/lib/crypto/krb/dk/checksum.c | 53 ++----- src/lib/crypto/krb/dk/derive.c | 108 +++++++++++++- src/lib/crypto/krb/dk/dk.h | 23 +-- src/lib/crypto/krb/dk/dk_aead.c | 47 ++---- src/lib/crypto/krb/dk/dk_decrypt.c | 35 ++--- src/lib/crypto/krb/dk/dk_encrypt.c | 70 +++------ src/lib/crypto/krb/dk/stringtokey.c | 22 +-- src/lib/crypto/krb/encrypt.c | 22 ++- src/lib/crypto/krb/encrypt_iov.c | 25 +++- src/lib/crypto/krb/etypes.h | 4 +- src/lib/crypto/krb/key.c | 99 +++++++++++++ src/lib/crypto/krb/keyblocks.c | 36 ++++- src/lib/crypto/krb/keyhash_provider/descbc.c | 6 +- .../crypto/krb/keyhash_provider/hmac_md5.c | 43 +++--- .../crypto/krb/keyhash_provider/k5_md4des.c | 14 +- .../crypto/krb/keyhash_provider/k5_md5des.c | 14 +- .../crypto/krb/keyhash_provider/md5_hmac.c | 2 +- src/lib/crypto/krb/make_checksum.c | 24 +++- src/lib/crypto/krb/make_checksum_iov.c | 24 +++- src/lib/crypto/krb/old/old.h | 4 +- src/lib/crypto/krb/old/old_decrypt.c | 8 +- src/lib/crypto/krb/old/old_encrypt.c | 8 +- src/lib/crypto/krb/prf.c | 13 +- src/lib/crypto/krb/prf/des_prf.c | 3 +- src/lib/crypto/krb/prf/dk_prf.c | 15 +- src/lib/crypto/krb/prf/prf_int.h | 8 +- src/lib/crypto/krb/prf/rc4_prf.c | 3 +- src/lib/crypto/krb/raw/raw.h | 4 +- src/lib/crypto/krb/raw/raw_aead.c | 4 +- src/lib/crypto/krb/raw/raw_decrypt.c | 2 +- src/lib/crypto/krb/raw/raw_encrypt.c | 2 +- src/lib/crypto/krb/verify_checksum.c | 22 ++- src/lib/crypto/krb/verify_checksum_iov.c | 25 +++- src/lib/crypto/krb/yarrow/ycipher.c | 41 +++--- src/lib/crypto/krb/yarrow/ycipher.h | 2 +- src/lib/crypto/libk5crypto.exports | 15 ++ src/lib/crypto/openssl/aes/aes_s2k.c | 29 ++-- src/lib/crypto/openssl/arcfour/arcfour.c | 50 ++++--- src/lib/crypto/openssl/arcfour/arcfour.h | 9 +- src/lib/crypto/openssl/arcfour/arcfour_aead.c | 48 ++++--- src/lib/crypto/openssl/enc_provider/aes.c | 60 ++++---- src/lib/crypto/openssl/enc_provider/des.c | 36 ++--- src/lib/crypto/openssl/enc_provider/des3.c | 34 ++--- src/lib/crypto/openssl/enc_provider/rc4.c | 16 +-- src/lib/crypto/openssl/hmac.c | 28 +++- src/lib/gssapi/krb5/accept_sec_context.c | 27 +++- src/lib/gssapi/krb5/delete_sec_context.c | 8 +- src/lib/gssapi/krb5/gssapiP_krb5.h | 41 +++--- src/lib/gssapi/krb5/init_sec_context.c | 21 ++- src/lib/gssapi/krb5/inq_context.c | 8 +- src/lib/gssapi/krb5/k5seal.c | 10 +- src/lib/gssapi/krb5/k5sealiov.c | 11 +- src/lib/gssapi/krb5/k5sealv3.c | 20 +-- src/lib/gssapi/krb5/k5sealv3iov.c | 20 +-- src/lib/gssapi/krb5/k5unseal.c | 10 +- src/lib/gssapi/krb5/k5unsealiov.c | 6 +- src/lib/gssapi/krb5/lucid_context.c | 6 +- src/lib/gssapi/krb5/ser_sctx.c | 69 ++++----- src/lib/gssapi/krb5/util_cksum.c | 20 +-- src/lib/gssapi/krb5/util_crypt.c | 133 ++++++++++------- src/lib/gssapi/krb5/util_seed.c | 20 ++- src/lib/gssapi/krb5/util_seqnum.c | 20 +-- src/lib/gssapi/krb5/wrap_size_limit.c | 6 +- src/lib/krb5/krb/auth_con.c | 37 ++--- src/lib/krb5/krb/auth_con.h | 6 +- src/lib/krb5/krb/copy_key.c | 13 +- src/lib/krb5/krb/cp_key_cnt.c | 10 +- src/lib/krb5/krb/enc_helper.c | 25 ++++ src/lib/krb5/krb/mk_cred.c | 23 ++- src/lib/krb5/krb/mk_priv.c | 20 +-- src/lib/krb5/krb/mk_rep.c | 13 +- src/lib/krb5/krb/mk_req_ext.c | 50 ++++--- src/lib/krb5/krb/mk_safe.c | 17 +-- src/lib/krb5/krb/rd_cred.c | 24 ++-- src/lib/krb5/krb/rd_priv.c | 20 +-- src/lib/krb5/krb/rd_rep.c | 23 +-- src/lib/krb5/krb/rd_req_dec.c | 34 ++--- src/lib/krb5/krb/rd_safe.c | 16 +-- src/lib/krb5/krb/ser_actx.c | 89 ++++++------ src/lib/krb5/os/accessor.c | 2 +- 105 files changed, 1876 insertions(+), 1069 deletions(-) create mode 100644 src/lib/crypto/crypto_tests/t_kperf.c create mode 100644 src/lib/crypto/krb/key.c diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 77221724c..858b9bd6d 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -635,6 +635,19 @@ krb5int_locate_server (krb5_context, const krb5_data *realm, struct addrlist *, enum locate_service_type svc, int sockettype, int family); +struct derived_key { + krb5_data constant; + krb5_key dkey; + struct derived_key *next; +}; + +/* Internal structure of an opaque key identifier */ +struct krb5_key_st { + krb5_keyblock keyblock; + int refcount; + struct derived_key *derived; +}; + /* new encryption provider api */ struct krb5_enc_provider { @@ -643,12 +656,12 @@ struct krb5_enc_provider { size_t block_size, keybytes, keylength; /* cipher-state == 0 fresh state thrown away at end */ - krb5_error_code (*encrypt) (const krb5_keyblock *key, + krb5_error_code (*encrypt) (krb5_key key, const krb5_data *cipher_state, const krb5_data *input, krb5_data *output); - krb5_error_code (*decrypt) (const krb5_keyblock *key, + krb5_error_code (*decrypt) (krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); @@ -661,13 +674,13 @@ struct krb5_enc_provider { krb5_error_code (*free_state) (krb5_data *state); /* In-place encryption/decryption of multiple buffers */ - krb5_error_code (*encrypt_iov) (const krb5_keyblock *key, + krb5_error_code (*encrypt_iov) (krb5_key key, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); - krb5_error_code (*decrypt_iov) (const krb5_keyblock *key, + krb5_error_code (*decrypt_iov) (krb5_key key, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); @@ -686,27 +699,27 @@ struct krb5_hash_provider { struct krb5_keyhash_provider { size_t hashsize; - krb5_error_code (*hash) (const krb5_keyblock *key, + krb5_error_code (*hash) (krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, const krb5_data *input, krb5_data *output); - krb5_error_code (*verify) (const krb5_keyblock *key, + krb5_error_code (*verify) (krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, const krb5_data *input, const krb5_data *hash, krb5_boolean *valid); - krb5_error_code (*hash_iov) (const krb5_keyblock *key, + krb5_error_code (*hash_iov) (krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); - krb5_error_code (*verify_iov) (const krb5_keyblock *key, + krb5_error_code (*verify_iov) (krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, const krb5_crypto_iov *data, @@ -724,7 +737,7 @@ struct krb5_aead_provider { krb5_error_code (*encrypt_iov) (const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -732,7 +745,7 @@ struct krb5_aead_provider { krb5_error_code (*decrypt_iov) (const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -749,10 +762,21 @@ void krb5_nfold krb5_error_code krb5_hmac (const struct krb5_hash_provider *hash, - const krb5_keyblock *key, unsigned int icount, + krb5_key key, unsigned int icount, const krb5_data *input, krb5_data *output); krb5_error_code krb5int_hmac_iov +(const struct krb5_hash_provider *hash, + krb5_key key, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output); + +krb5_error_code krb5int_hmac_keyblock +(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, unsigned int icount, + const krb5_data *input, krb5_data *output); + +krb5_error_code krb5int_hmac_iov_keyblock (const struct krb5_hash_provider *hash, const krb5_keyblock *key, const krb5_crypto_iov *data, size_t num_data, @@ -808,13 +832,18 @@ krb5_error_code krb5int_c_combine_keys (krb5_context context, krb5_keyblock *key1, krb5_keyblock *key2, krb5_keyblock *outkey); + void krb5int_c_free_keyblock (krb5_context, krb5_keyblock *key); void krb5int_c_free_keyblock_contents (krb5_context, krb5_keyblock *); -krb5_error_code krb5int_c_init_keyblock +krb5_error_code krb5int_c_init_keyblock (krb5_context, krb5_enctype enctype, size_t length, krb5_keyblock **out); +krb5_error_code krb5int_c_copy_keyblock +(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to); +krb5_error_code krb5int_c_copy_keyblock_contents +(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to); /* * Internal - for cleanup. @@ -850,6 +879,11 @@ krb5_error_code krb5_encrypt_helper krb5_keyusage keyusage, const krb5_data *plain, krb5_enc_data *cipher); +krb5_error_code krb5_encrypt_keyhelper +(krb5_context context, krb5_key key, + krb5_keyusage keyusage, const krb5_data *plain, + krb5_enc_data *cipher); + /* * End "los-proto.h" */ @@ -2566,10 +2600,10 @@ krb5_error_code krb5_decrypt_data krb5_data *enc_data); krb5_error_code -krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); krb5_error_code -krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); struct _krb5_kt { /* should move into k5-int.h */ diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index 81bc1cf6e..e0128d058 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -341,6 +341,7 @@ struct _krb5_cryptosystem_entry; * begin "encryption.h" */ +/* Exposed contents of a key. */ typedef struct _krb5_keyblock { krb5_magic magic; krb5_enctype enctype; @@ -348,6 +349,16 @@ typedef struct _krb5_keyblock { krb5_octet *contents; } krb5_keyblock; +/* + * Opaque identifier for a key. Use with the krb5_k APIs for better + * performance for repeated operations with the same key usage. Key + * identifiers must not be used simultaneously within multiple + * threads, as they may contain mutable internal state and are not + * mutex-protected. + */ +struct krb5_key_st; +typedef struct krb5_key_st *krb5_key; + #ifdef KRB5_OLD_CRYPTO typedef struct _krb5_encrypt_block { krb5_magic magic; @@ -705,6 +716,64 @@ krb5_error_code KRB5_CALLCONV (krb5_context context, krb5_enctype enctype, size_t data_length, unsigned int *size); +krb5_error_code KRB5_CALLCONV +krb5_k_create_key(krb5_context context, const krb5_keyblock *key_data, + krb5_key *out); + +/* Keys are logically immutable and can be "copied" by reference count. */ +void KRB5_CALLCONV krb5_k_reference_key(krb5_context context, krb5_key key); + +/* Decrement the reference count on a key and free it if it hits zero. */ +void KRB5_CALLCONV krb5_k_free_key(krb5_context context, krb5_key key); + +krb5_error_code KRB5_CALLCONV +krb5_k_key_keyblock(krb5_context context, krb5_key key, + krb5_keyblock **key_data); + +krb5_enctype KRB5_CALLCONV +krb5_k_key_enctype(krb5_context context, krb5_key key); + +krb5_error_code KRB5_CALLCONV +krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage, + const krb5_data *cipher_state, const krb5_data *input, + krb5_enc_data *output); + +krb5_error_code KRB5_CALLCONV +krb5_k_encrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, + const krb5_data *cipher_state, krb5_crypto_iov *data, + size_t num_data); + +krb5_error_code KRB5_CALLCONV +krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage, + const krb5_data *cipher_state, const krb5_enc_data *input, + krb5_data *output); + +krb5_error_code KRB5_CALLCONV +krb5_k_decrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, + const krb5_data *cipher_state, krb5_crypto_iov *data, + size_t num_data); + +krb5_error_code KRB5_CALLCONV +krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, + krb5_key key, krb5_keyusage usage, const krb5_data *input, + krb5_checksum *cksum); + +krb5_error_code KRB5_CALLCONV +krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, + krb5_key key, krb5_keyusage usage, + krb5_crypto_iov *data, size_t num_data); + +krb5_error_code KRB5_CALLCONV +krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage, + const krb5_data *data, const krb5_checksum *cksum, + krb5_boolean *valid); + +krb5_error_code KRB5_CALLCONV +krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_boolean *valid); + #ifdef KRB5_OLD_CRYPTO /* * old cryptosystem routine prototypes. These are now layered diff --git a/src/lib/crypto/builtin/aes/aes_s2k.c b/src/lib/crypto/builtin/aes/aes_s2k.c index 36045edc0..76d73c635 100644 --- a/src/lib/crypto/builtin/aes/aes_s2k.c +++ b/src/lib/crypto/builtin/aes/aes_s2k.c @@ -44,6 +44,7 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc, unsigned long iter_count; krb5_data out; static const krb5_data usage = { KV5M_DATA, 8, "kerberos" }; + krb5_key tempkey = NULL; krb5_error_code err; if (params) { @@ -66,25 +67,25 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc, if (iter_count >= MAX_ITERATION_COUNT) return KRB5_ERR_BAD_S2K_PARAMS; - /* - * Dense key space, no parity bits or anything, so take a shortcut - * and use the key contents buffer for the generated bytes. - */ + /* Use the output keyblock contents for temporary space. */ out.data = (char *) key->contents; out.length = key->length; if (out.length != 16 && out.length != 32) return KRB5_CRYPTO_INTERNAL; err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt); - if (err) { - memset(out.data, 0, out.length); - return err; - } + if (err) + goto cleanup; - err = krb5_derive_key (enc, key, key, &usage); - if (err) { - memset(out.data, 0, out.length); - return err; - } - return 0; + err = krb5_k_create_key (NULL, key, &tempkey); + if (err) + goto cleanup; + + err = krb5_derive_keyblock (enc, tempkey, key, &usage); + +cleanup: + if (err) + memset (out.data, 0, out.length); + krb5_k_free_key (NULL, tempkey); + return err; } diff --git a/src/lib/crypto/builtin/arcfour/arcfour.c b/src/lib/crypto/builtin/arcfour/arcfour.c index e5cdfdc8c..150a7aa06 100644 --- a/src/lib/crypto/builtin/arcfour/arcfour.c +++ b/src/lib/crypto/builtin/arcfour/arcfour.c @@ -64,11 +64,12 @@ case 7: /* tgs-req authenticator */ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3, salt, plaintext, checksum, ciphertext, confounder; krb5_keyusage ms_usage; size_t keylength, keybytes, blocksize, hashsize; @@ -83,7 +84,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, d1.data=malloc(d1.length); if (d1.data == NULL) return (ENOMEM); - k1 = *key; + k1 = key->keyblock; k1.length=d1.length; k1.contents= (void *) d1.data; @@ -93,7 +94,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, free(d1.data); return (ENOMEM); } - k2 = *key; + k2 = key->keyblock; k2.length=d2.length; k2.contents=(void *) d2.data; @@ -104,7 +105,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, free(d2.data); return (ENOMEM); } - k3 = *key; + k3 = key->keyblock; k3.length=d3.length; k3.contents= (void *) d3.data; @@ -140,7 +141,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, /* begin the encryption, computer K1 */ ms_usage=krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data+10); } else { @@ -151,7 +152,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype==ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype==ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents+7, 0xab, 9); ret=krb5_c_random_make_octets(/* XXX */ 0, &confounder); @@ -159,11 +160,19 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, if (ret) goto cleanup; - krb5_hmac(hash, &k2, 1, &plaintext, &checksum); + ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum); + if (ret) + goto cleanup; + + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); + if (ret) + goto cleanup; - krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret) + goto cleanup; - ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext); + ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext); cleanup: memset(d1.data, 0, d1.length); @@ -184,11 +193,12 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_keyblock k1,k2,k3; + krb5_key k3key; krb5_data d1,d2,d3,salt,ciphertext,plaintext,checksum; krb5_keyusage ms_usage; size_t keybytes, keylength, hashsize, blocksize; @@ -203,7 +213,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, d1.data=malloc(d1.length); if (d1.data == NULL) return (ENOMEM); - k1 = *key; + k1 = key->keyblock; k1.length=d1.length; k1.contents= (void *) d1.data; @@ -213,7 +223,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, free(d1.data); return (ENOMEM); } - k2 = *key; + k2 = key->keyblock; k2.length=d2.length; k2.contents= (void *) d2.data; @@ -224,7 +234,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, free(d2.data); return (ENOMEM); } - k3 = *key; + k3 = key->keyblock; k3.length=d3.length; k3.contents= (void *) d3.data; @@ -257,7 +267,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, /* We may have to try two ms_usage values; see below. */ do { /* compute the salt */ - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data + 10); } else { @@ -270,18 +280,22 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xab, 9); - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); if (ret) goto cleanup; - ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret) + goto cleanup; + ret = (*(enc->decrypt))(k3key, ivec, &ciphertext, &plaintext); + krb5_k_free_key(NULL, k3key); if (ret) goto cleanup; - ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1); + ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &d1); if (ret) goto cleanup; diff --git a/src/lib/crypto/builtin/arcfour/arcfour.h b/src/lib/crypto/builtin/arcfour/arcfour.h index e8ff203ca..1a2876437 100644 --- a/src/lib/crypto/builtin/arcfour/arcfour.h +++ b/src/lib/crypto/builtin/arcfour/arcfour.h @@ -10,7 +10,7 @@ krb5_arcfour_encrypt_length(const struct krb5_enc_provider *, extern krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *, const struct krb5_hash_provider *, - const krb5_keyblock *, + krb5_key, krb5_keyusage, const krb5_data *, const krb5_data *, @@ -19,7 +19,7 @@ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *, extern krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *, const struct krb5_hash_provider *, - const krb5_keyblock *, + krb5_key, krb5_keyusage, const krb5_data *, const krb5_data *, diff --git a/src/lib/crypto/builtin/arcfour/arcfour_aead.c b/src/lib/crypto/builtin/arcfour/arcfour_aead.c index cff7d66d6..4896afaaf 100644 --- a/src/lib/crypto/builtin/arcfour/arcfour_aead.c +++ b/src/lib/crypto/builtin/arcfour/arcfour_aead.c @@ -82,7 +82,7 @@ static krb5_error_code krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -91,6 +91,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3; krb5_data checksum, confounder, header_data; krb5_keyusage ms_usage; @@ -126,15 +127,15 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, data[i].data.length = 0; } - ret = alloc_derived_key(enc, &k1, &d1, key); + ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k2, &d2, key); + ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k3, &d3, key); + ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock); if (ret != 0) goto cleanup; @@ -144,7 +145,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, ms_usage = krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data + 10); } else { @@ -157,7 +158,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xAB, 9); header->data.length = hash->hashsize + CONFOUNDERLENGTH; @@ -176,15 +177,19 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, header->data.length -= hash->hashsize; header->data.data += hash->hashsize; - ret = krb5int_hmac_iov(hash, &k2, data, num_data, &checksum); + ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &checksum); if (ret != 0) goto cleanup; - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); if (ret != 0) goto cleanup; - ret = enc->encrypt_iov(&k3, ivec, data, num_data); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret != 0) + goto cleanup; + + ret = enc->encrypt_iov(k3key, ivec, data, num_data); if (ret != 0) goto cleanup; @@ -204,6 +209,7 @@ cleanup: free(d3.data); } + krb5_k_free_key(NULL, k3key); return ret; } @@ -211,7 +217,7 @@ static krb5_error_code krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -220,6 +226,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3; krb5_data checksum, header_data; krb5_keyusage ms_usage; @@ -240,15 +247,15 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, if (trailer != NULL && trailer->data.length != 0) return KRB5_BAD_MSIZE; - ret = alloc_derived_key(enc, &k1, &d1, key); + ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k2, &d2, key); + ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k3, &d3, key); + ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock); if (ret != 0) goto cleanup; @@ -258,7 +265,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, ms_usage = krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, (unsigned char *)salt.data + 10); } else { @@ -271,7 +278,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xAB, 9); checksum.data = header->data.data; @@ -281,15 +288,19 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, header->data.length -= hash->hashsize; header->data.data += hash->hashsize; - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); + if (ret != 0) + goto cleanup; + + ret = krb5_k_create_key(NULL, &k3, &k3key); if (ret != 0) goto cleanup; - ret = enc->decrypt_iov(&k3, ivec, data, num_data); + ret = enc->decrypt_iov(k3key, ivec, data, num_data); if (ret != 0) goto cleanup; - ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1); + ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1); if (ret != 0) goto cleanup; @@ -314,6 +325,7 @@ cleanup: free(d3.data); } + krb5_k_free_key(NULL, k3key); return ret; } diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c index 934bc63a2..52fb2259d 100644 --- a/src/lib/crypto/builtin/enc_provider/aes.c +++ b/src/lib/crypto/builtin/enc_provider/aes.c @@ -86,7 +86,7 @@ static void xorblock(char *out, const char *in) } krb5_error_code -krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { aes_ctx ctx; @@ -95,7 +95,8 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, /* CHECK_SIZES; */ - if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) + if (aes_enc_key(key->keyblock.contents, key->keyblock.length, + &ctx) != aes_good) abort(); if (ivec) @@ -140,7 +141,7 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, } krb5_error_code -krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { aes_ctx ctx; @@ -149,7 +150,8 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, CHECK_SIZES; - if (aes_dec_key(key->contents, key->length, &ctx) != aes_good) + if (aes_dec_key(key->keyblock.contents, key->keyblock.length, + &ctx) != aes_good) abort(); if (ivec) @@ -200,7 +202,7 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -krb5int_aes_encrypt_iov(const krb5_keyblock *key, +krb5int_aes_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -210,7 +212,8 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key, int nblocks = 0, blockno; size_t input_length, i; - if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) + if (aes_enc_key(key->keyblock.contents, key->keyblock.length, &ctx) + != aes_good) abort(); if (ivec != NULL) @@ -280,7 +283,7 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -krb5int_aes_decrypt_iov(const krb5_keyblock *key, +krb5int_aes_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -293,7 +296,8 @@ krb5int_aes_decrypt_iov(const krb5_keyblock *key, CHECK_SIZES; - if (aes_dec_key(key->contents, key->length, &ctx) != aes_good) + if (aes_dec_key(key->keyblock.contents, key->keyblock.length, + &ctx) != aes_good) abort(); if (ivec != NULL) diff --git a/src/lib/crypto/builtin/enc_provider/des.c b/src/lib/crypto/builtin/enc_provider/des.c index 433032dd3..d73a1d290 100644 --- a/src/lib/crypto/builtin/enc_provider/des.c +++ b/src/lib/crypto/builtin/enc_provider/des.c @@ -32,14 +32,14 @@ static krb5_error_code -k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_docrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output, int enc) { mit_des_key_schedule schedule; - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); @@ -48,7 +48,7 @@ k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, if (input->length != output->length) return(KRB5_BAD_MSIZE); - switch (mit_des_key_sched(key->contents, schedule)) { + switch (mit_des_key_sched(key->keyblock.contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: @@ -71,30 +71,30 @@ k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { return(k5_des_docrypt(key, ivec, input, output, 1)); } static krb5_error_code -k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { return(k5_des_docrypt(key, ivec, input, output, 0)); } static krb5_error_code -k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_docrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, int enc) { mit_des_key_schedule schedule; size_t input_length = 0; unsigned int i; - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); for (i = 0; i < num_data; i++) { @@ -109,7 +109,7 @@ k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); - switch (mit_des_key_sched(key->contents, schedule)) { + switch (mit_des_key_sched(key->keyblock.contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: @@ -128,7 +128,7 @@ k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des_encrypt_iov(const krb5_keyblock *key, +k5_des_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -137,7 +137,7 @@ k5_des_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -k5_des_decrypt_iov(const krb5_keyblock *key, +k5_des_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) diff --git a/src/lib/crypto/builtin/enc_provider/des3.c b/src/lib/crypto/builtin/enc_provider/des3.c index 7dba292ae..eae504b8c 100644 --- a/src/lib/crypto/builtin/enc_provider/des3.c +++ b/src/lib/crypto/builtin/enc_provider/des3.c @@ -30,13 +30,13 @@ #include static krb5_error_code -validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, +validate_and_schedule(krb5_key key, const krb5_data *ivec, const krb5_data *input, const krb5_data *output, mit_des3_key_schedule *schedule) { - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != 24) + if (key->keyblock.length != 24) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); @@ -45,7 +45,7 @@ validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, if (input->length != output->length) return(KRB5_BAD_MSIZE); - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents, *schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); @@ -56,7 +56,7 @@ validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, +validate_and_schedule_iov(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, mit_des3_key_schedule *schedule) { @@ -69,14 +69,14 @@ validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, input_length += iov->data.length; } - if (key->length != 24) + if (key->keyblock.length != 24) return(KRB5_BAD_KEYSIZE); if ((input_length%8) != 0) return(KRB5_BAD_MSIZE); if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents, *schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); @@ -87,7 +87,7 @@ validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des3_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { mit_des3_key_schedule schedule; @@ -109,7 +109,7 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des3_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { mit_des3_key_schedule schedule; @@ -131,7 +131,7 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_encrypt_iov(const krb5_keyblock *key, +k5_des3_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -154,7 +154,7 @@ k5_des3_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -k5_des3_decrypt_iov(const krb5_keyblock *key, +k5_des3_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) diff --git a/src/lib/crypto/builtin/enc_provider/rc4.c b/src/lib/crypto/builtin/enc_provider/rc4.c index df2c914f8..47c131da4 100644 --- a/src/lib/crypto/builtin/enc_provider/rc4.c +++ b/src/lib/crypto/builtin/enc_provider/rc4.c @@ -29,7 +29,7 @@ static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest, /* Interface layer to kerb5 crypto layer */ static krb5_error_code -k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *, +k5_arcfour_docrypt(krb5_key, const krb5_data *, const krb5_data *, krb5_data *); static const unsigned char arcfour_weakkey1[] = {0x00, 0x00, 0xfd}; @@ -113,14 +113,14 @@ k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key, /* The workhorse of the arcfour system, this impliments the cipher */ static krb5_error_code -k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, +k5_arcfour_docrypt(krb5_key key, const krb5_data *state, const krb5_data *input, krb5_data *output) { ArcfourContext *arcfour_ctx; ArcFourCipherState *cipher_state; int ret; - if (key->length != 16) + if (key->keyblock.length != 16) return(KRB5_BAD_KEYSIZE); if (state && (state->length != sizeof (ArcFourCipherState))) return(KRB5_BAD_MSIZE); @@ -131,7 +131,8 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, cipher_state = (ArcFourCipherState *) state->data; arcfour_ctx=&cipher_state->ctx; if (cipher_state->initialized == 0) { - if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) { + if ((ret=k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length))) { return ret; } cipher_state->initialized = 1; @@ -142,7 +143,8 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, arcfour_ctx=malloc(sizeof (ArcfourContext)); if (arcfour_ctx == NULL) return ENOMEM; - if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) { + if ((ret=k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length))) { free(arcfour_ctx); return (ret); } @@ -157,7 +159,7 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, /* In-place encryption */ static krb5_error_code -k5_arcfour_docrypt_iov(const krb5_keyblock *key, +k5_arcfour_docrypt_iov(krb5_key key, const krb5_data *state, krb5_crypto_iov *data, size_t num_data) @@ -167,7 +169,7 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, krb5_error_code ret; size_t i; - if (key->length != 16) + if (key->keyblock.length != 16) return KRB5_BAD_KEYSIZE; if (state != NULL && (state->length != sizeof(ArcFourCipherState))) return KRB5_BAD_MSIZE; @@ -176,7 +178,8 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, cipher_state = (ArcFourCipherState *)state->data; arcfour_ctx = &cipher_state->ctx; if (cipher_state->initialized == 0) { - ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length); + ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length); if (ret != 0) return ret; @@ -187,7 +190,8 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, if (arcfour_ctx == NULL) return ENOMEM; - ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length); + ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length); if (ret != 0) { free(arcfour_ctx); return ret; diff --git a/src/lib/crypto/builtin/hmac.c b/src/lib/crypto/builtin/hmac.c index 3bff3cf95..6726a0826 100644 --- a/src/lib/crypto/builtin/hmac.c +++ b/src/lib/crypto/builtin/hmac.c @@ -27,6 +27,17 @@ #include "k5-int.h" #include "aead.h" +/* + * Because our built-in HMAC implementation doesn't need to invoke any + * encryption or keyed hash functions, it is simplest to define it in + * terms of keyblocks, and then supply a simple wrapper for the + * "normal" krb5_key-using interfaces. The keyblock interfaces are + * useful for the built-in arcfour code which constructs a lot of + * intermediate HMAC keys. For other back ends, it should not be + * necessary to supply the _keyblock versions of the hmac functions if + * the back end code doesn't make use of them. + */ + /* * the HMAC transform looks like: * @@ -40,8 +51,9 @@ */ krb5_error_code -krb5_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key, - unsigned int icount, const krb5_data *input, krb5_data *output) +krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, unsigned int icount, + const krb5_data *input, krb5_data *output) { size_t hashsize, blocksize; unsigned char *xorkey, *ihash; @@ -127,8 +139,10 @@ cleanup: } krb5_error_code -krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key, - const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +krb5int_hmac_iov_keyblock(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { krb5_data *sign_data; size_t num_sign_data; @@ -156,10 +170,25 @@ krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key } /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */ - ret = krb5_hmac(hash, key, num_sign_data, sign_data, output); + ret = krb5int_hmac_keyblock(hash, key, num_sign_data, sign_data, output); free(sign_data); return ret; } +krb5_error_code +krb5_hmac(const struct krb5_hash_provider *hash, krb5_key key, + unsigned int icount, const krb5_data *input, krb5_data *output) +{ + return krb5int_hmac_keyblock(hash, &key->keyblock, icount, input, output); +} + +krb5_error_code +krb5int_hmac_iov(const struct krb5_hash_provider *hash, krb5_key key, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + return krb5int_hmac_iov_keyblock(hash, &key->keyblock, data, num_data, + output); +} diff --git a/src/lib/crypto/builtin/pbkdf2.c b/src/lib/crypto/builtin/pbkdf2.c index d897e9a71..9201e23b0 100644 --- a/src/lib/crypto/builtin/pbkdf2.c +++ b/src/lib/crypto/builtin/pbkdf2.c @@ -25,19 +25,36 @@ * * * Implementation of PBKDF2 from RFC 2898. - * Not currently used; likely to be used when we get around to AES support. */ #include #include "k5-int.h" #include "hash_provider.h" +/* + * RFC 2898 specifies PBKDF2 in terms of an underlying pseudo-random + * function with two arguments (password and salt||blockindex). Right + * now we only use PBKDF2 with the hmac-sha1 PRF, also specified in + * RFC 2898, which invokes HMAC with the password as the key and the + * second argument as the text. (HMAC accepts any key size up to the + * block size; the password is pre-hashed with unkeyed SHA1 if it is + * longer than the block size.) + * + * For efficiency, it is better to generate the key from the password + * once at the beginning, so we specify prf_func in terms of a + * krb5_key first argument. That might not be convenient for a PRF + * which uses the password in some other way, so this might need to be + * adjusted in the future. + */ + +typedef krb5_error_code (*prf_func)(krb5_key pass, krb5_data *salt, + krb5_data *out); + /* Not exported, for now. */ static krb5_error_code -krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *, - krb5_data *), - size_t hlen, const krb5_data *pass, const krb5_data *salt, - unsigned long count, const krb5_data *output); +krb5int_pbkdf2 (prf_func prf, size_t hlen, krb5_key pass, + const krb5_data *salt, unsigned long count, + const krb5_data *output); static int debug_hmac = 0; @@ -61,35 +78,21 @@ static void printd (const char *descr, krb5_data *d) { } printf("\n"); } -static void printk(const char *descr, krb5_keyblock *k) { - krb5_data d; - d.data = (char *) k->contents; - d.length = k->length; - printd(descr, &d); -} static krb5_error_code -F(char *output, char *u_tmp1, char *u_tmp2, - krb5_error_code (*prf)(krb5_keyblock *, krb5_data *, krb5_data *), - size_t hlen, - const krb5_data *pass, const krb5_data *salt, - unsigned long count, int i) +F(char *output, char *u_tmp1, char *u_tmp2, prf_func prf, size_t hlen, + krb5_key pass, const krb5_data *salt, unsigned long count, int i) { unsigned char ibytes[4]; size_t tlen; unsigned int j, k; - krb5_keyblock pdata; krb5_data sdata; krb5_data out; krb5_error_code err; - pdata.contents = pass->data; - pdata.length = pass->length; - #if 0 printf("F(i=%d, count=%lu, pass=%d:%s)\n", i, count, pass->length, pass->data); - printk("F password", &pdata); #endif /* Compute U_1. */ @@ -112,7 +115,7 @@ F(char *output, char *u_tmp1, char *u_tmp2, #if 0 printf("F: computing hmac #1 (U_1) with %s\n", pdata.contents); #endif - err = (*prf)(&pdata, &sdata, &out); + err = (*prf)(pass, &sdata, &out); if (err) return err; #if 0 @@ -127,7 +130,7 @@ F(char *output, char *u_tmp1, char *u_tmp2, printf("F: computing hmac #%d (U_%d)\n", j, j); #endif memcpy(u_tmp2, u_tmp1, hlen); - err = (*prf)(&pdata, &sdata, &out); + err = (*prf)(pass, &sdata, &out); if (err) return err; #if 0 @@ -147,11 +150,9 @@ F(char *output, char *u_tmp1, char *u_tmp2, } static krb5_error_code -krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *, - krb5_data *), - size_t hlen, - const krb5_data *pass, const krb5_data *salt, - unsigned long count, const krb5_data *output) +krb5int_pbkdf2 (prf_func prf, size_t hlen, krb5_key pass, + const krb5_data *salt, unsigned long count, + const krb5_data *output) { int l, r, i; char *utmp1, *utmp2; @@ -209,57 +210,55 @@ krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *, return 0; } -static krb5_error_code hmac1(const struct krb5_hash_provider *h, - krb5_keyblock *key, krb5_data *in, krb5_data *out) +/* + * Implements the hmac-sha1 PRF. pass has been pre-hashed (if + * necessary) and converted to a key already; salt has had the block + * index appended to the original salt. + */ +static krb5_error_code +hmac_sha1(krb5_key pass, krb5_data *salt, krb5_data *out) { - char tmp[40]; - size_t blocksize, hashsize; + const struct krb5_hash_provider *h = &krb5int_hash_sha1; krb5_error_code err; - krb5_keyblock k; - k = *key; - key = &k; if (debug_hmac) - printk(" test key", key); - blocksize = h->blocksize; - hashsize = h->hashsize; - if (hashsize > sizeof(tmp)) - abort(); - if (key->length > blocksize) { - krb5_data d, d2; - d.data = (char *) key->contents; - d.length = key->length; - d2.data = tmp; - d2.length = hashsize; - err = h->hash (1, &d, &d2); - if (err) - return err; - key->length = d2.length; - key->contents = (krb5_octet *) d2.data; - if (debug_hmac) - printk(" pre-hashed key", key); - } - if (debug_hmac) - printd(" hmac input", in); - err = krb5_hmac(h, key, 1, in, out); + printd(" hmac input", salt); + err = krb5_hmac(h, pass, 1, salt, out); if (err == 0 && debug_hmac) printd(" hmac output", out); return err; } -static krb5_error_code -foo(krb5_keyblock *pass, krb5_data *salt, krb5_data *out) -{ - krb5_error_code err; - - memset(out->data, 0, out->length); - err = hmac1 (&krb5int_hash_sha1, pass, salt, out); - return err; -} - krb5_error_code krb5int_pbkdf2_hmac_sha1 (const krb5_data *out, unsigned long count, const krb5_data *pass, const krb5_data *salt) { - return krb5int_pbkdf2 (foo, 20, pass, salt, count, out); + const struct krb5_hash_provider *h = &krb5int_hash_sha1; + krb5_keyblock keyblock; + krb5_key key; + char tmp[40]; + krb5_data d; + krb5_error_code err; + + assert(h->hashsize <= sizeof(tmp)); + if (pass->length > h->blocksize) { + d.data = tmp; + d.length = h->hashsize; + err = h->hash (1, pass, &d); + if (err) + return err; + keyblock.length = d.length; + keyblock.contents = (krb5_octet *) d.data; + } else { + keyblock.length = pass->length; + keyblock.contents = (krb5_octet *) pass->data; + } + + err = krb5_k_create_key(NULL, &keyblock, &key); + if (err) + return err; + + err = krb5int_pbkdf2(hmac_sha1, 20, key, salt, count, out); + krb5_k_free_key(NULL, key); + return err; } diff --git a/src/lib/crypto/crypto_tests/Makefile.in b/src/lib/crypto/crypto_tests/Makefile.in index ab6ebfa4c..7b240d578 100644 --- a/src/lib/crypto/crypto_tests/Makefile.in +++ b/src/lib/crypto/crypto_tests/Makefile.in @@ -33,6 +33,7 @@ EXTRADEPSRCS=\ $(srcdir)/t_shs3.c \ $(srcdir)/t_shs.c \ $(srcdir)/t_verify.c \ + $(srcdir)/t_kperf.c \ $(srcdir)/ytest.c ##DOSBUILDTOP = ..\..\.. @@ -149,6 +150,9 @@ t_shs: t_shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB) t_shs3: t_shs3.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB) $(CC_LINK) -o t_shs3 t_shs3.o $(SUPPORT_LIB) $(CRYPTO_DEPLIB) +t_kperf: t_kperf.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB) + $(CC_LINK) -o t_kperf t_kperf.o $(SUPPORT_LIB) $(CRYPTO_DEPLIB) + ytest: ytest.o shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB) $(CC_LINK) -o ytest ytest.o $(SUPPORT_LIB) $(CRYPTO_DEPLIB) diff --git a/src/lib/crypto/crypto_tests/aes-test.c b/src/lib/crypto/crypto_tests/aes-test.c index c05fd26e3..8999bd757 100644 --- a/src/lib/crypto/crypto_tests/aes-test.c +++ b/src/lib/crypto/crypto_tests/aes-test.c @@ -50,7 +50,11 @@ static void init() } static void enc() { - krb5int_aes_encrypt(&enc_key, &ivec, &in, &out); + krb5_key key; + + krb5_k_create_key(NULL, &enc_key, &key); + krb5int_aes_encrypt(key, &ivec, &in, &out); + krb5_k_free_key(NULL, key); } static void hexdump(const char *label, const char *cp, int len) diff --git a/src/lib/crypto/crypto_tests/t_cksum.c b/src/lib/crypto/crypto_tests/t_cksum.c index 98187f7f1..2b5365119 100644 --- a/src/lib/crypto/crypto_tests/t_cksum.c +++ b/src/lib/crypto/crypto_tests/t_cksum.c @@ -75,6 +75,7 @@ main(argc, argv) krb5_boolean valid; size_t length; krb5_keyblock keyblock; + krb5_key key; krb5_error_code kret=0; krb5_data plaintext, newstyle_checksum; @@ -89,6 +90,8 @@ main(argc, argv) keyblock.length = sizeof(testkey); keyblock.contents = testkey; + krb5_k_create_key(NULL, &keyblock, &key); + length = khp.hashsize; newstyle_checksum.length = length; @@ -102,13 +105,13 @@ main(argc, argv) plaintext.length = strlen(argv[msgindex]); plaintext.data = argv[msgindex]; - if ((kret = (*(khp.hash))(&keyblock, 0, 0, &plaintext, &newstyle_checksum))) { + if ((kret = (*(khp.hash))(key, 0, 0, &plaintext, &newstyle_checksum))) { printf("krb5_calculate_checksum choked with %d\n", kret); break; } print_checksum("correct", MD, argv[msgindex], &newstyle_checksum); - if ((kret = (*(khp.verify))(&keyblock, 0, 0, &plaintext, &newstyle_checksum, + if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &newstyle_checksum, &valid))) { printf("verify on new checksum choked with %d\n", kret); break; @@ -120,7 +123,7 @@ main(argc, argv) printf("Verify succeeded for \"%s\"\n", argv[msgindex]); newstyle_checksum.data[0]++; - if ((kret = (*(khp.verify))(&keyblock, 0, 0, &plaintext, &newstyle_checksum, + if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &newstyle_checksum, &valid))) { printf("verify on new checksum choked with %d\n", kret); break; diff --git a/src/lib/crypto/crypto_tests/t_cts.c b/src/lib/crypto/crypto_tests/t_cts.c index aef813273..fab5b2707 100644 --- a/src/lib/crypto/crypto_tests/t_cts.c +++ b/src/lib/crypto/crypto_tests/t_cts.c @@ -114,15 +114,12 @@ static void test_cts() "I would like the General Gau's Chicken, please, and wonton soup."; static const unsigned char aeskey[16] = "chicken teriyaki"; static const int lengths[] = { 17, 31, 32, 47, 48, 64 }; - extern krb5_error_code krb5int_aes_encrypt(const krb5_keyblock *, - const krb5_data *, - const krb5_data *, - krb5_data *); int i; char outbuf[64], encivbuf[16], decivbuf[16], outbuf2[64]; krb5_data in, out, enciv, deciv, out2; - krb5_keyblock key; + krb5_keyblock keyblock; + krb5_key key; krb5_error_code err; in.data = input; @@ -131,11 +128,17 @@ static void test_cts() enciv.length = deciv.length = 16; enciv.data = encivbuf; deciv.data = decivbuf; - key.contents = aeskey; - key.length = 16; + keyblock.contents = aeskey; + keyblock.length = 16; + + err = krb5_k_create_key(NULL, &keyblock, &key); + if (err) { + printf("error %ld from krb5_k_create_key\n", (long)err); + exit(1); + } memset(enciv.data, 0, 16); - printk("AES 128-bit key", &key); + printk("AES 128-bit key", &keyblock); for (i = 0; i < sizeof(lengths)/sizeof(lengths[0]); i++) { memset(enciv.data, 0, 16); memset(deciv.data, 0, 16); @@ -143,7 +146,7 @@ static void test_cts() printf("\n"); in.length = out.length = lengths[i]; printd("IV", &enciv); - err = krb5int_aes_encrypt(&key, &enciv, &in, &out); + err = krb5int_aes_encrypt(key, &enciv, &in, &out); if (err) { printf("error %ld from krb5int_aes_encrypt\n", (long)err); exit(1); @@ -152,7 +155,7 @@ static void test_cts() printd("Output", &out); printd("Next IV", &enciv); out2.length = out.length; - err = krb5int_aes_decrypt(&key, &deciv, &out, &out2); + err = krb5int_aes_decrypt(key, &deciv, &out, &out2); if (err) { printf("error %ld from krb5int_aes_decrypt\n", (long)err); exit(1); diff --git a/src/lib/crypto/crypto_tests/t_encrypt.c b/src/lib/crypto/crypto_tests/t_encrypt.c index 739c6d3e0..aac31fb21 100644 --- a/src/lib/crypto/crypto_tests/t_encrypt.c +++ b/src/lib/crypto/crypto_tests/t_encrypt.c @@ -78,12 +78,14 @@ int main () { krb5_context context = 0; - krb5_data in, in2, out, out2, check, check2, state; + krb5_data in, in2, out, out2, check, check2, state, signdata; krb5_crypto_iov iov[5]; - int i; + int i, j, pos; + unsigned int dummy; size_t len; krb5_enc_data enc_out, enc_out2; - krb5_keyblock *key; + krb5_keyblock *keyblock; + krb5_key key; memset(iov, 0, sizeof(iov)); @@ -94,6 +96,8 @@ main () test ("Seeding random number generator", krb5_c_random_seed (context, &in)); + + /* Set up output buffers. */ out.data = malloc(2048); out2.data = malloc(2048); check.data = malloc(2048); @@ -107,39 +111,67 @@ main () out2.length = 2048; check.length = 2048; check2.length = 2048; + for (i = 0; interesting_enctypes[i]; i++) { krb5_enctype enctype = interesting_enctypes [i]; + printf ("Testing enctype %d\n", enctype); test ("Initializing a keyblock", - krb5_init_keyblock (context, enctype, 0, &key)); - test ("Generating random key", - krb5_c_make_random_key (context, enctype, key)); + krb5_init_keyblock (context, enctype, 0, &keyblock)); + test ("Generating random keyblock", + krb5_c_make_random_key (context, enctype, keyblock)); + test ("Creating opaque key from keyblock", + krb5_k_create_key (context, keyblock, &key)); + enc_out.ciphertext = out; enc_out2.ciphertext = out2; /* We use an intermediate `len' because size_t may be different size than `int' */ - krb5_c_encrypt_length (context, key->enctype, in.length, &len); + krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len); enc_out.ciphertext.length = len; - test ("Encrypting", - krb5_c_encrypt (context, key, 7, 0, &in, &enc_out)); + + /* Encrypt, decrypt, and see if we got the plaintext back again. */ + test ("Encrypting (c)", + krb5_c_encrypt (context, keyblock, 7, 0, &in, &enc_out)); test ("Decrypting", - krb5_c_decrypt (context, key, 7, 0, &enc_out, &check)); + krb5_c_decrypt (context, keyblock, 7, 0, &enc_out, &check)); test ("Comparing", compare_results (&in, &check)); - if ( krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &len) == 0 ){ - /* We support iov/aead*/ - int j, pos; - krb5_data signdata; - signdata.magic = KV5M_DATA; - signdata.data = (char *) "This should be signed"; - signdata.length = strlen(signdata.data); + + /* Try again with the opaque-key-using variants. */ + memset(out.data, 0, out.length); + test ("Encrypting (k)", + krb5_k_encrypt (context, key, 7, 0, &in, &enc_out)); + test ("Decrypting", + krb5_k_decrypt (context, key, 7, 0, &enc_out, &check)); + test ("Comparing", compare_results (&in, &check)); + + /* Check if this enctype supports IOV encryption. */ + if ( krb5_c_crypto_length(context, keyblock->enctype, + KRB5_CRYPTO_TYPE_HEADER, &dummy) == 0 ){ + /* Set up iovecs for stream decryption. */ + memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length); iov[0].flags= KRB5_CRYPTO_TYPE_STREAM; + iov[0].data.data = out2.data; + iov[0].data.length = enc_out.ciphertext.length; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; - iov[0].data = enc_out.ciphertext; - iov[1].data = out; - test("IOV stream decrypting", - krb5_c_decrypt_iov( context, key, 7, 0, iov, 2)); + + /* Decrypt the encrypted data from above and check it. */ + test("IOV stream decrypting (c)", + krb5_c_decrypt_iov( context, keyblock, 7, 0, iov, 2)); test("Comparing results", compare_results(&in, &iov[1].data)); + + /* Try again with the opaque-key-using variant. */ + memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length); + test("IOV stream decrypting (k)", + krb5_k_decrypt_iov( context, key, 7, 0, iov, 2)); + test("Comparing results", + compare_results(&in, &iov[1].data)); + + /* Set up iovecs for AEAD encryption. */ + signdata.magic = KV5M_DATA; + signdata.data = (char *) "This should be signed"; + signdata.length = strlen(signdata.data); iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = in; /*We'll need to copy memory before encrypt*/ @@ -147,8 +179,10 @@ main () iov[2].data = signdata; iov[3].flags = KRB5_CRYPTO_TYPE_PADDING; iov[4].flags = KRB5_CRYPTO_TYPE_TRAILER; + + /* "Allocate" data for the iovec buffers from the "out" buffer. */ test("Setting up iov lengths", - krb5_c_crypto_length_iov(context, key->enctype, iov, 5)); + krb5_c_crypto_length_iov(context, keyblock->enctype, iov, 5)); for (j=0,pos=0; j <= 4; j++ ){ if (iov[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) continue; @@ -157,56 +191,70 @@ main () } assert (iov[1].data.length == in.length); memcpy(iov[1].data.data, in.data, in.length); - test("iov encrypting", - krb5_c_encrypt_iov(context, key, 7, 0, iov, 5)); + + /* Encrypt and decrypt in place, and check the result. */ + test("iov encrypting (c)", + krb5_c_encrypt_iov(context, keyblock, 7, 0, iov, 5)); assert(iov[1].data.length == in.length); test("iov decrypting", - krb5_c_decrypt_iov(context, key, 7, 0, iov, 5)); + krb5_c_decrypt_iov(context, keyblock, 7, 0, iov, 5)); test("Comparing results", compare_results(&in, &iov[1].data)); + /* Try again with opaque-key-using variants. */ + test("iov encrypting (k)", + krb5_k_encrypt_iov(context, key, 7, 0, iov, 5)); + assert(iov[1].data.length == in.length); + test("iov decrypting", + krb5_k_decrypt_iov(context, key, 7, 0, iov, 5)); + test("Comparing results", + compare_results(&in, &iov[1].data)); } + enc_out.ciphertext.length = out.length; check.length = 2048; + test ("init_state", - krb5_c_init_state (context, key, 7, &state)); + krb5_c_init_state (context, keyblock, 7, &state)); test ("Encrypting with state", - krb5_c_encrypt (context, key, 7, &state, &in, &enc_out)); + krb5_c_encrypt (context, keyblock, 7, &state, &in, &enc_out)); test ("Encrypting again with state", - krb5_c_encrypt (context, key, 7, &state, &in2, &enc_out2)); + krb5_c_encrypt (context, keyblock, 7, &state, &in2, &enc_out2)); test ("free_state", - krb5_c_free_state (context, key, &state)); + krb5_c_free_state (context, keyblock, &state)); test ("init_state", - krb5_c_init_state (context, key, 7, &state)); + krb5_c_init_state (context, keyblock, 7, &state)); test ("Decrypting with state", - krb5_c_decrypt (context, key, 7, &state, &enc_out, &check)); + krb5_c_decrypt (context, keyblock, 7, &state, &enc_out, &check)); test ("Decrypting again with state", - krb5_c_decrypt (context, key, 7, &state, &enc_out2, &check2)); + krb5_c_decrypt (context, keyblock, 7, &state, &enc_out2, &check2)); test ("free_state", - krb5_c_free_state (context, key, &state)); + krb5_c_free_state (context, keyblock, &state)); test ("Comparing", compare_results (&in, &check)); test ("Comparing", compare_results (&in2, &check2)); - krb5_free_keyblock (context, key); + + krb5_free_keyblock (context, keyblock); + krb5_k_free_key (context, key); } /* Test the RC4 decrypt fallback from key usage 9 to 8. */ test ("Initializing an RC4 keyblock", - krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &key)); + krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &keyblock)); test ("Generating random RC4 key", - krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, key)); + krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, keyblock)); enc_out.ciphertext = out; - krb5_c_encrypt_length (context, key->enctype, in.length, &len); + krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len); enc_out.ciphertext.length = len; check.length = 2048; test ("Encrypting with RC4 key usage 8", - krb5_c_encrypt (context, key, 8, 0, &in, &enc_out)); + krb5_c_encrypt (context, keyblock, 8, 0, &in, &enc_out)); test ("Decrypting with RC4 key usage 9", - krb5_c_decrypt (context, key, 9, 0, &enc_out, &check)); + krb5_c_decrypt (context, keyblock, 9, 0, &enc_out, &check)); test ("Comparing", compare_results (&in, &check)); - krb5_free_keyblock (context, key); + krb5_free_keyblock (context, keyblock); free(out.data); free(out2.data); free(check.data); diff --git a/src/lib/crypto/crypto_tests/t_hmac.c b/src/lib/crypto/crypto_tests/t_hmac.c index bf629c359..30830d617 100644 --- a/src/lib/crypto/crypto_tests/t_hmac.c +++ b/src/lib/crypto/crypto_tests/t_hmac.c @@ -98,6 +98,7 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h, char tmp[40]; size_t blocksize, hashsize; krb5_error_code err; + krb5_key k; printk(" test key", key); blocksize = h->blocksize; @@ -120,7 +121,9 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h, printk(" pre-hashed key", key); } printd(" hmac input", in); - err = krb5_hmac(h, key, 1, in, out); + krb5_k_create_key(NULL, key, &k); + err = krb5_hmac(h, k, 1, in, out); + krb5_k_free_key(NULL, k); if (err == 0) printd(" hmac output", out); return err; diff --git a/src/lib/crypto/crypto_tests/t_kperf.c b/src/lib/crypto/crypto_tests/t_kperf.c new file mode 100644 index 000000000..f56aa3cd1 --- /dev/null +++ b/src/lib/crypto/crypto_tests/t_kperf.c @@ -0,0 +1,119 @@ +/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* + * lib/crypto/crypto_tests/t_kperf.c + * + * Copyright (C) 2009 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * This file contains a harness to measure the performance improvement + * of using the the krb5_k functions (which cache derived keys) over + * the equivalent krb5_c functions which do not. Sample usages: + * + * ./t_kperf ce aes128-cts 10 100000 + * ./t_kperf kv aes256-cts 1024 10000 + * + * The first usage encrypts ('e') a hundred thousand ten-byte blobs + * with aes128-cts, using the non-caching APIs ('c'). The second + * usage verifies ('v') ten thousand checksums over 1K blobs with the + * first available keyed checksum type for aes256-cts, using the + * caching APIs ('k'). Run commands under "time" to measure how much + * time is used by the operations. + */ + +#include "k5-int.h" + +int +main(int argc, char **argv) +{ + krb5_keyblock kblock; + krb5_key key; + krb5_enctype enctype; + krb5_cksumtype cktype, *cktypelist; + int blocksize, num_blocks, intf, op, i; + unsigned int count; + size_t outlen, cklen; + krb5_data block; + krb5_enc_data outblock; + krb5_checksum sum; + krb5_boolean val; + + if (argc != 5) { + fprintf(stderr, "Usage: t_kperf {c|k}{e|d|m|v} type size nblocks\n"); + exit(1); + } + intf = argv[1][0]; + assert(intf == 'c' || intf =='k'); + op = argv[1][1]; + assert(krb5_string_to_enctype(argv[2], &enctype) == 0); + blocksize = atoi(argv[3]); + num_blocks = atoi(argv[4]); + + /* Pick the first available keyed checksum type. */ + krb5_c_keyed_checksum_types(NULL, enctype, &count, &cktypelist); + assert(count > 0); + cktype = cktypelist[0]; + + block.data = "notrandom"; + block.length = 9; + krb5_c_random_seed(NULL, &block); + + krb5_c_make_random_key(NULL, enctype, &kblock); + krb5_k_create_key(NULL, &kblock, &key); + + block.length = blocksize; + block.data = calloc(1, blocksize); + + krb5_c_encrypt_length(NULL, enctype, blocksize, &outlen); + outblock.enctype = enctype; + outblock.ciphertext.length = outlen; + outblock.ciphertext.data = calloc(1, outlen); + + krb5_c_checksum_length(NULL, cktype, &cklen); + sum.checksum_type = cktype; + sum.length = cklen; + sum.contents = calloc(1, cklen); + + for (i = 0; i < num_blocks; i++) { + if (intf == 'c') { + if (op == 'e') + krb5_c_encrypt(NULL, &kblock, 0, NULL, &block, &outblock); + else if (op == 'd') + krb5_c_decrypt(NULL, &kblock, 0, NULL, &outblock, &block); + else if (op == 'm') + krb5_c_make_checksum(NULL, cktype, &kblock, 0, &block, &sum); + else if (op == 'v') + krb5_c_verify_checksum(NULL, &kblock, 0, &block, &sum, &val); + } else { + if (op == 'e') + krb5_k_encrypt(NULL, key, 0, NULL, &block, &outblock); + else if (op == 'd') + krb5_k_decrypt(NULL, key, 0, NULL, &outblock, &block); + else if (op == 'm') + krb5_k_make_checksum(NULL, cktype, key, 0, &block, &sum); + else if (op == 'v') + krb5_k_verify_checksum(NULL, key, 0, &block, &sum, &val); + } + } + return 0; +} diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in index e64ef8f31..fe96eba85 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 ac5e7e87c..3b11da5dc 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 2c99eb868..cc43875e2 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 8c3ea1936..acfb99bbd 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; @@ -224,6 +231,9 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey, if (ret) goto cleanup; outblockdata = k5alloc(blocksize, &ret); + if (ret) + goto cleanup; + ret = krb5_k_create_key(NULL, inkey, &key); if (ret) goto cleanup; @@ -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 29b6ef75c..36c3bf0ab 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 c2f2c0b61..fcc997377 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 fb5622a73..31e7de90e 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 8c8214c12..c2638e804 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 9ddeb408c..6566ce8d5 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 13eb007cd..5c9c1ad5c 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 1c0358a2d..abb7a39b0 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 b06079c63..bb045fa6b 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 326565758..48b053ad9 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 741485a31..3c39838cf 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 21242bca2..b7b2f5814 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 8d83b4200..edaa00cae 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 000000000..4ea72b478 --- /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 ee88f9a8a..51e31d301 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 bf68e324c..b08e30b7c 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 34ce67169..61c6d8c21 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 49700a89d..1514dccc6 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 24d631706..e7a84e2a8 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 d05b97f00..589c3475e 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 ca4ca5805..dd34df377 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 a16b849c0..32c9a4cb4 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 94ee6421e..6cfb0c97a 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 cfbbd7272..dd9ad19cb 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 98bd109e0..1121dc935 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 d2c633e75..12ec22b65 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 869f2e0bf..dd9907bda 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 cc3e2d934..cc203875c 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 180ce027d..97bbf049d 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 2b1b73f91..3affaa539 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 f4b7d5f0b..84ae73023 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 f52fe000d..68070d1da 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 767da1f9f..dd62806e4 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 68b819c01..462239ee5 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 4466c7dad..82f4fb11f 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 341c89684..f322dc386 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 2af410440..84cadd13f 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 96999c0db..ad0d307fc 100644 --- a/src/lib/crypto/krb/yarrow/ycipher.h +++ b/src/lib/crypto/krb/yarrow/ycipher.h @@ -7,7 +7,7 @@ typedef struct { - krb5_keyblock key; + krb5_key key; } CIPHER_CTX; /* We need to choose a cipher. To do this, choose an enc_provider. diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports index 4ea46fa19..953497e17 100644 --- a/src/lib/crypto/libk5crypto.exports +++ b/src/lib/crypto/libk5crypto.exports @@ -72,6 +72,18 @@ krb5_finish_random_key krb5_free_cksumtypes krb5_hmac krb5_init_random_key +krb5_k_create_key +krb5_k_decrypt +krb5_k_decrypt_iov +krb5_k_encrypt +krb5_k_encrypt_iov +krb5_k_free_key +krb5_k_key_enctype +krb5_k_key_keyblock +krb5_k_make_checksum +krb5_k_make_checksum_iov +krb5_k_verify_checksum +krb5_k_verify_checksum_iov krb5_nfold krb5_old_decrypt krb5_old_encrypt @@ -100,6 +112,8 @@ krb5int_aes_string_to_key krb5int_arcfour_string_to_key krb5int_arcfour_translate_usage krb5int_c_combine_keys +krb5int_c_copy_keyblock +krb5int_c_copy_keyblock_contents krb5int_c_free_keyblock krb5int_c_free_keyblock_contents krb5int_c_init_keyblock @@ -122,6 +136,7 @@ krb5int_hash_crc32 krb5int_hash_md4 krb5int_hash_md5 krb5int_hash_sha1 +krb5int_hmac_keyblock krb5int_keyhash_descbc krb5int_keyhash_hmac_md5 krb5int_keyhash_md4des diff --git a/src/lib/crypto/openssl/aes/aes_s2k.c b/src/lib/crypto/openssl/aes/aes_s2k.c index 1383be11a..db6553e25 100644 --- a/src/lib/crypto/openssl/aes/aes_s2k.c +++ b/src/lib/crypto/openssl/aes/aes_s2k.c @@ -44,6 +44,7 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc, unsigned long iter_count; krb5_data out; static const krb5_data usage = { KV5M_DATA, 8, "kerberos" }; + krb5_key tempkey = NULL; krb5_error_code err; if (params) { @@ -66,25 +67,25 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc, if (iter_count >= MAX_ITERATION_COUNT) return KRB5_ERR_BAD_S2K_PARAMS; - /* - * Dense key space, no parity bits or anything, so take a shortcut - * and use the key contents buffer for the generated bytes. - */ + /* Use the output keyblock contents for temporary space. */ out.data = (char *) key->contents; out.length = key->length; if (out.length != 16 && out.length != 32) return KRB5_CRYPTO_INTERNAL; err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt); - if (err) { - memset(out.data, 0, out.length); - return err; - } + if (err) + goto cleanup; - err = krb5_derive_key (enc, key, key, &usage); - if (err) { - memset(out.data, 0, out.length); - return err; - } - return 0; + err = krb5_k_create_key (NULL, key, &tempkey); + if (err) + goto cleanup; + + err = krb5_derive_keyblock (enc, tempkey, key, &usage); + +cleanup: + if (err) + memset (out.data, 0, out.length); + krb5_k_free_key (NULL, tempkey); + return err; } diff --git a/src/lib/crypto/openssl/arcfour/arcfour.c b/src/lib/crypto/openssl/arcfour/arcfour.c index 687f276b0..2c89b99b8 100644 --- a/src/lib/crypto/openssl/arcfour/arcfour.c +++ b/src/lib/crypto/openssl/arcfour/arcfour.c @@ -65,11 +65,12 @@ case 7: /* tgs-req authenticator */ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3, salt, plaintext, checksum, ciphertext, confounder; krb5_keyusage ms_usage; size_t keylength, keybytes, blocksize, hashsize; @@ -84,7 +85,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, d1.data=malloc(d1.length); if (d1.data == NULL) return (ENOMEM); - k1 = *key; + k1 = key->keyblock; k1.length=d1.length; k1.contents= (void *) d1.data; @@ -94,7 +95,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, free(d1.data); return (ENOMEM); } - k2 = *key; + k2 = key->keyblock; k2.length=d2.length; k2.contents=(void *) d2.data; @@ -105,7 +106,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, free(d2.data); return (ENOMEM); } - k3 = *key; + k3 = key->keyblock; k3.length=d3.length; k3.contents= (void *) d3.data; @@ -141,7 +142,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, /* begin the encryption, computer K1 */ ms_usage=krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data+10); } else { @@ -152,7 +153,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype==ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype==ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents+7, 0xab, 9); ret=krb5_c_random_make_octets(/* XXX */ 0, &confounder); @@ -160,11 +161,19 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, if (ret) goto cleanup; - krb5_hmac(hash, &k2, 1, &plaintext, &checksum); + ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum); + if (ret) + goto cleanup; + + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); + if (ret) + goto cleanup; - krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret) + goto cleanup; - ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext); + ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext); cleanup: memset(d1.data, 0, d1.length); @@ -185,11 +194,12 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_keyblock k1,k2,k3; + krb5_key k3key; krb5_data d1,d2,d3,salt,ciphertext,plaintext,checksum; krb5_keyusage ms_usage; size_t keybytes, keylength, hashsize, blocksize; @@ -204,7 +214,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, d1.data=malloc(d1.length); if (d1.data == NULL) return (ENOMEM); - k1 = *key; + k1 = key->keyblock; k1.length=d1.length; k1.contents= (void *) d1.data; @@ -214,7 +224,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, free(d1.data); return (ENOMEM); } - k2 = *key; + k2 = key->keyblock; k2.length=d2.length; k2.contents= (void *) d2.data; @@ -225,7 +235,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, free(d2.data); return (ENOMEM); } - k3 = *key; + k3 = key->keyblock; k3.length=d3.length; k3.contents= (void *) d3.data; @@ -258,7 +268,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, /* We may have to try two ms_usage values; see below. */ do { /* compute the salt */ - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data + 10); } else { @@ -271,18 +281,22 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xab, 9); - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); if (ret) goto cleanup; - ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret) + goto cleanup; + ret = (*(enc->decrypt))(k3key, ivec, &ciphertext, &plaintext); + krb5_k_free_key(NULL, k3key); if (ret) goto cleanup; - ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1); + ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &d1); if (ret) goto cleanup; diff --git a/src/lib/crypto/openssl/arcfour/arcfour.h b/src/lib/crypto/openssl/arcfour/arcfour.h index be408febc..1a2876437 100644 --- a/src/lib/crypto/openssl/arcfour/arcfour.h +++ b/src/lib/crypto/openssl/arcfour/arcfour.h @@ -10,7 +10,7 @@ krb5_arcfour_encrypt_length(const struct krb5_enc_provider *, extern krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *, const struct krb5_hash_provider *, - const krb5_keyblock *, + krb5_key, krb5_keyusage, const krb5_data *, const krb5_data *, @@ -19,7 +19,7 @@ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *, extern krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *, const struct krb5_hash_provider *, - const krb5_keyblock *, + krb5_key, krb5_keyusage, const krb5_data *, const krb5_data *, @@ -34,10 +34,5 @@ extern krb5_error_code krb5int_arcfour_string_to_key( extern const struct krb5_enc_provider krb5int_enc_arcfour; extern const struct krb5_aead_provider krb5int_aead_arcfour; - krb5_error_code krb5int_arcfour_prf( - const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, - const krb5_data *in, krb5_data *out); #endif /* ARCFOUR_H */ diff --git a/src/lib/crypto/openssl/arcfour/arcfour_aead.c b/src/lib/crypto/openssl/arcfour/arcfour_aead.c index cff7d66d6..4896afaaf 100644 --- a/src/lib/crypto/openssl/arcfour/arcfour_aead.c +++ b/src/lib/crypto/openssl/arcfour/arcfour_aead.c @@ -82,7 +82,7 @@ static krb5_error_code krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -91,6 +91,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3; krb5_data checksum, confounder, header_data; krb5_keyusage ms_usage; @@ -126,15 +127,15 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, data[i].data.length = 0; } - ret = alloc_derived_key(enc, &k1, &d1, key); + ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k2, &d2, key); + ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k3, &d3, key); + ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock); if (ret != 0) goto cleanup; @@ -144,7 +145,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, ms_usage = krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data + 10); } else { @@ -157,7 +158,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xAB, 9); header->data.length = hash->hashsize + CONFOUNDERLENGTH; @@ -176,15 +177,19 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, header->data.length -= hash->hashsize; header->data.data += hash->hashsize; - ret = krb5int_hmac_iov(hash, &k2, data, num_data, &checksum); + ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &checksum); if (ret != 0) goto cleanup; - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); if (ret != 0) goto cleanup; - ret = enc->encrypt_iov(&k3, ivec, data, num_data); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret != 0) + goto cleanup; + + ret = enc->encrypt_iov(k3key, ivec, data, num_data); if (ret != 0) goto cleanup; @@ -204,6 +209,7 @@ cleanup: free(d3.data); } + krb5_k_free_key(NULL, k3key); return ret; } @@ -211,7 +217,7 @@ static krb5_error_code krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -220,6 +226,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3; krb5_data checksum, header_data; krb5_keyusage ms_usage; @@ -240,15 +247,15 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, if (trailer != NULL && trailer->data.length != 0) return KRB5_BAD_MSIZE; - ret = alloc_derived_key(enc, &k1, &d1, key); + ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k2, &d2, key); + ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k3, &d3, key); + ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock); if (ret != 0) goto cleanup; @@ -258,7 +265,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, ms_usage = krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, (unsigned char *)salt.data + 10); } else { @@ -271,7 +278,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xAB, 9); checksum.data = header->data.data; @@ -281,15 +288,19 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, header->data.length -= hash->hashsize; header->data.data += hash->hashsize; - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); + if (ret != 0) + goto cleanup; + + ret = krb5_k_create_key(NULL, &k3, &k3key); if (ret != 0) goto cleanup; - ret = enc->decrypt_iov(&k3, ivec, data, num_data); + ret = enc->decrypt_iov(k3key, ivec, data, num_data); if (ret != 0) goto cleanup; - ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1); + ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1); if (ret != 0) goto cleanup; @@ -314,6 +325,7 @@ cleanup: free(d3.data); } + krb5_k_free_key(NULL, k3key); return ret; } diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c index 81d306300..76f81d41e 100644 --- a/src/lib/crypto/openssl/enc_provider/aes.c +++ b/src/lib/crypto/openssl/enc_provider/aes.c @@ -36,22 +36,22 @@ /* proto's */ static krb5_error_code -cts_enc(const krb5_keyblock *key, const krb5_data *ivec, +cts_enc(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); static krb5_error_code -cbc_enc(const krb5_keyblock *key, const krb5_data *ivec, +cbc_enc(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); static krb5_error_code -cts_decr(const krb5_keyblock *key, const krb5_data *ivec, +cts_decr(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); static krb5_error_code -cbc_decr(const krb5_keyblock *key, const krb5_data *ivec, +cbc_decr(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output); static krb5_error_code -cts_encr_iov(const krb5_keyblock *key, const krb5_data *ivec, +cts_encr_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen); static krb5_error_code -cts_decr_iov(const krb5_keyblock *key, const krb5_data *ivec, +cts_decr_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen); #define NUM_BITS 8 @@ -69,7 +69,7 @@ map_mode(unsigned int len) } static krb5_error_code -cbc_enc(const krb5_keyblock *key, const krb5_data *ivec, +cbc_enc(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -77,7 +77,7 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec, unsigned char *tmp_buf = NULL; EVP_CIPHER_CTX ciph_ctx; - key_buf = OPENSSL_malloc(key->length); + key_buf = OPENSSL_malloc(key->keyblock.length); if (!key_buf) return ENOMEM; @@ -87,11 +87,11 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec, OPENSSL_free(key_buf); return ENOMEM; } - memcpy(key_buf, key->contents, key->length); + memcpy(key_buf, key->keyblock.contents, key->keyblock.length); EVP_CIPHER_CTX_init(&ciph_ctx); - ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->length), + ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), NULL, key_buf, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 1){ @@ -112,7 +112,7 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec, ret = KRB5_CRYPTO_INTERNAL; } - memset(key_buf, 0, key->length); + memset(key_buf, 0, key->keyblock.length); memset(tmp_buf, 0, input->length); OPENSSL_free(key_buf); OPENSSL_free(tmp_buf); @@ -121,7 +121,7 @@ cbc_enc(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -cbc_decr(const krb5_keyblock *key, const krb5_data *ivec, +cbc_decr(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -129,7 +129,7 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec, unsigned char *tmp_buf = NULL; EVP_CIPHER_CTX ciph_ctx; - key_buf = OPENSSL_malloc(key->length); + key_buf = OPENSSL_malloc(key->keyblock.length); if (!key_buf) return ENOMEM; @@ -139,11 +139,11 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec, OPENSSL_free(key_buf); return ENOMEM; } - memcpy(key_buf, key->contents, key->length); + memcpy(key_buf, key->keyblock.contents, key->keyblock.length); EVP_CIPHER_CTX_init(&ciph_ctx); - ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->length), + ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), NULL, key_buf, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 1) { EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); @@ -164,7 +164,7 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec, ret = KRB5_CRYPTO_INTERNAL; } - memset(key_buf, 0, key->length); + memset(key_buf, 0, key->keyblock.length); memset(tmp_buf, 0, input->length); OPENSSL_free(key_buf); OPENSSL_free(tmp_buf); @@ -173,7 +173,7 @@ cbc_decr(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -cts_enc(const krb5_keyblock *key, const krb5_data *ivec, +cts_enc(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -194,7 +194,8 @@ cts_enc(const krb5_keyblock *key, const krb5_data *ivec, return ENOMEM; tmp_len = input->length; - AES_set_encrypt_key(key->contents, NUM_BITS * key->length, &enck); + AES_set_encrypt_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &enck); size = CRYPTO_cts128_encrypt((unsigned char *)input->data, tmp_buf, input->length, &enck, @@ -217,7 +218,7 @@ cts_enc(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -cts_decr(const krb5_keyblock *key, const krb5_data *ivec, +cts_decr(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -238,7 +239,8 @@ cts_decr(const krb5_keyblock *key, const krb5_data *ivec, return ENOMEM; tmp_len = input->length; - AES_set_decrypt_key(key->contents, NUM_BITS * key->length, &deck); + AES_set_decrypt_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &deck); size = CRYPTO_cts128_decrypt((unsigned char *)input->data, tmp_buf, input->length, &deck, @@ -261,7 +263,7 @@ cts_decr(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -cts_encr_iov(const krb5_keyblock *key, +cts_encr_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) @@ -313,7 +315,8 @@ cts_encr_iov(const krb5_keyblock *key, if (tlen > dlen) break; } - AES_set_encrypt_key(key->contents, NUM_BITS * key->length, &enck); + AES_set_encrypt_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &enck); size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, iv_cts, (cbc128_f)AES_cbc_encrypt); @@ -336,7 +339,7 @@ cts_encr_iov(const krb5_keyblock *key, } static krb5_error_code -cts_decr_iov(const krb5_keyblock *key, +cts_decr_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) @@ -373,7 +376,8 @@ cts_decr_iov(const krb5_keyblock *key, memset(oblock, 0, oblock_len); memset(dbuf, 0, dlen); - AES_set_decrypt_key(key->contents, NUM_BITS * key->length, &deck); + AES_set_decrypt_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &deck); tlen = 0; for (;;) { @@ -411,7 +415,7 @@ cts_decr_iov(const krb5_keyblock *key, } krb5_error_code -krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0; @@ -426,7 +430,7 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, } krb5_error_code -krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0; @@ -445,7 +449,7 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -krb5int_aes_encrypt_iov(const krb5_keyblock *key, +krb5int_aes_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -470,7 +474,7 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -krb5int_aes_decrypt_iov(const krb5_keyblock *key, +krb5int_aes_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c index 4965c6e6f..a4208eefc 100644 --- a/src/lib/crypto/openssl/enc_provider/des.c +++ b/src/lib/crypto/openssl/enc_provider/des.c @@ -11,11 +11,11 @@ #define DES_KEY_BYTES 7 static krb5_error_code -validate(const krb5_keyblock *key, const krb5_data *ivec, +validate(krb5_key key, const krb5_data *ivec, const krb5_data *input, const krb5_data *output) { - /* key->enctype was checked by the caller */ - if (key->length != KRB5_MIT_DES_KEYSIZE) + /* key->keyblock.enctype was checked by the caller */ + if (key->keyblock.length != KRB5_MIT_DES_KEYSIZE) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); @@ -28,7 +28,7 @@ validate(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -validate_iov(const krb5_keyblock *key, const krb5_data *ivec, +validate_iov(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data) { size_t i, input_length; @@ -39,7 +39,7 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec, input_length += iov->data.length; } - if (key->length != KRB5_MIT_DES3_KEYSIZE) + if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE) return(KRB5_BAD_KEYSIZE); if ((input_length%DES_BLOCK_SIZE) != 0) return(KRB5_BAD_MSIZE); @@ -50,7 +50,7 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -63,8 +63,8 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) return ret; - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; tmp_buf_len = output->length*2; tmp_buf=OPENSSL_malloc(tmp_buf_len); @@ -103,10 +103,10 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, static krb5_error_code -k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ int ret = 0, tmp_len = 0; unsigned char *keybuf = NULL; unsigned char *tmp_buf; @@ -116,8 +116,8 @@ k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) return ret; - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; tmp_buf=OPENSSL_malloc(output->length); if (!tmp_buf) @@ -152,7 +152,7 @@ k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des_encrypt_iov(const krb5_keyblock *key, +k5_des_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -176,8 +176,8 @@ k5_des_encrypt_iov(const krb5_keyblock *key, IOV_BLOCK_STATE_INIT(&input_pos); IOV_BLOCK_STATE_INIT(&output_pos); - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; ret = validate_iov(key, ivec, data, num_data); if (ret) @@ -229,7 +229,7 @@ k5_des_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -k5_des_decrypt_iov(const krb5_keyblock *key, +k5_des_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -254,8 +254,8 @@ k5_des_decrypt_iov(const krb5_keyblock *key, IOV_BLOCK_STATE_INIT(&input_pos); IOV_BLOCK_STATE_INIT(&output_pos); - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; ret = validate_iov(key, ivec, data, num_data); if (ret) diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c index 1dec8e27e..e20e42e23 100644 --- a/src/lib/crypto/openssl/enc_provider/des3.c +++ b/src/lib/crypto/openssl/enc_provider/des3.c @@ -11,12 +11,12 @@ #define DES_BLOCK_SIZE 8 static krb5_error_code -validate(const krb5_keyblock *key, const krb5_data *ivec, +validate(krb5_key key, const krb5_data *ivec, const krb5_data *input, const krb5_data *output) { - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != KRB5_MIT_DES3_KEYSIZE) + if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE) return(KRB5_BAD_KEYSIZE); if ((input->length%DES_BLOCK_SIZE) != 0) return(KRB5_BAD_MSIZE); @@ -29,7 +29,7 @@ validate(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -validate_iov(const krb5_keyblock *key, const krb5_data *ivec, +validate_iov(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data) { size_t i, input_length; @@ -40,7 +40,7 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec, input_length += iov->data.length; } - if (key->length != KRB5_MIT_DES3_KEYSIZE) + if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE) return(KRB5_BAD_KEYSIZE); if ((input_length%DES_BLOCK_SIZE) != 0) return(KRB5_BAD_MSIZE); @@ -51,7 +51,7 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des3_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -64,8 +64,8 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) return ret; - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; tmp_buf_len = output->length * 2; tmp_buf = OPENSSL_malloc(tmp_buf_len); @@ -104,7 +104,7 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des3_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -117,8 +117,8 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) return ret; - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; tmp_buf_len = output->length; tmp_buf=OPENSSL_malloc(tmp_buf_len); @@ -156,7 +156,7 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_encrypt_iov(const krb5_keyblock *key, +k5_des3_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -185,8 +185,8 @@ k5_des3_encrypt_iov(const krb5_keyblock *key, IOV_BLOCK_STATE_INIT(&input_pos); IOV_BLOCK_STATE_INIT(&output_pos); - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; memset(oblock, 0, oblock_len); @@ -236,7 +236,7 @@ k5_des3_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -k5_des3_decrypt_iov(const krb5_keyblock *key, +k5_des3_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -265,8 +265,8 @@ k5_des3_decrypt_iov(const krb5_keyblock *key, IOV_BLOCK_STATE_INIT(&input_pos); IOV_BLOCK_STATE_INIT(&output_pos); - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; memset(oblock, 0, oblock_len); diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c index ae2f58f40..fd1c7238d 100644 --- a/src/lib/crypto/openssl/enc_provider/rc4.c +++ b/src/lib/crypto/openssl/enc_provider/rc4.c @@ -15,7 +15,7 @@ /* prototypes */ static krb5_error_code -k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *, +k5_arcfour_docrypt(krb5_key, const krb5_data *, const krb5_data *, krb5_data *); static krb5_error_code k5_arcfour_free_state ( krb5_data *state); @@ -29,7 +29,7 @@ k5_arcfour_init_state (const krb5_keyblock *key, /* In-place rc4 crypto */ static krb5_error_code -k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, +k5_arcfour_docrypt(krb5_key key, const krb5_data *state, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; @@ -37,14 +37,14 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, unsigned char *tmp_buf = NULL; EVP_CIPHER_CTX ciph_ctx; - if (key->length != RC4_KEY_SIZE) + if (key->keyblock.length != RC4_KEY_SIZE) return(KRB5_BAD_KEYSIZE); if (input->length != output->length) return(KRB5_BAD_MSIZE); - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; EVP_CIPHER_CTX_init(&ciph_ctx); @@ -72,7 +72,7 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, /* In-place IOV crypto */ static krb5_error_code -k5_arcfour_docrypt_iov(const krb5_keyblock *key, +k5_arcfour_docrypt_iov(krb5_key key, const krb5_data *state, krb5_crypto_iov *data, size_t num_data) @@ -84,8 +84,8 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, krb5_crypto_iov *iov = NULL; EVP_CIPHER_CTX ciph_ctx; - keybuf=key->contents; - keybuf[key->length] = '\0'; + keybuf=key->keyblock.contents; + keybuf[key->keyblock.length] = '\0'; EVP_CIPHER_CTX_init(&ciph_ctx); diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c index e0c8dec79..658bc28f1 100644 --- a/src/lib/crypto/openssl/hmac.c +++ b/src/lib/crypto/openssl/hmac.c @@ -32,8 +32,9 @@ map_digest(const struct krb5_hash_provider *hash) } krb5_error_code -krb5_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key, - unsigned int icount, const krb5_data *input, krb5_data *output) +krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, unsigned int icount, + const krb5_data *input, krb5_data *output) { unsigned int i = 0, md_len = 0; unsigned char md[EVP_MAX_MD_SIZE]; @@ -72,8 +73,10 @@ krb5_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key, } krb5_error_code -krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key, - const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +krb5int_hmac_iov_keyblock(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { krb5_data *sign_data; size_t num_sign_data; @@ -101,10 +104,25 @@ krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key } /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */ - ret = krb5_hmac(hash, key, num_sign_data, sign_data, output); + ret = krb5int_hmac_keyblock(hash, key, num_sign_data, sign_data, output); free(sign_data); return ret; } +krb5_error_code +krb5_hmac(const struct krb5_hash_provider *hash, krb5_key key, + unsigned int icount, const krb5_data *input, krb5_data *output) +{ + return krb5int_hmac_keyblock(hash, &key->keyblock, icount, input, output); +} + +krb5_error_code +krb5int_hmac_iov(const struct krb5_hash_provider *hash, krb5_key key, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + return krb5int_hmac_iov_keyblock(hash, &key->keyblock, data, num_data, + output); +} diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index 934302cff..6c141ae99 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -437,6 +437,7 @@ kg_accept_krb5(minor_status, context_handle, int no_encap = 0; krb5_flags ap_req_options = 0; krb5_enctype negotiated_etype; + krb5_keyblock *keyblock = NULL; krb5_authdata_context ad_context = NULL; code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); @@ -883,22 +884,21 @@ kg_accept_krb5(minor_status, context_handle, krb5_auth_con_set_authdata_context(context, auth_context, NULL); if ((code = krb5_auth_con_getrecvsubkey(context, auth_context, - &ctx->subkey))) { + &keyblock))) { major_status = GSS_S_FAILURE; goto fail; } /* use the session key if the subkey isn't present */ - if (ctx->subkey == NULL) { - if ((code = krb5_auth_con_getkey(context, auth_context, - &ctx->subkey))) { + if (keyblock == NULL) { + if ((code = krb5_auth_con_getkey(context, auth_context, &keyblock))) { major_status = GSS_S_FAILURE; goto fail; } } - if (ctx->subkey == NULL) { + if (keyblock == NULL) { /* this isn't a very good error, but it's not clear to me this can actually happen */ major_status = GSS_S_FAILURE; @@ -906,6 +906,12 @@ kg_accept_krb5(minor_status, context_handle, goto fail; } + code = krb5_k_create_key(context, keyblock, &ctx->subkey); + if (code) { + major_status = GSS_S_FAILURE; + goto fail; + } + ctx->enc = NULL; ctx->seq = NULL; ctx->have_acceptor_subkey = 0; @@ -1033,12 +1039,19 @@ kg_accept_krb5(minor_status, context_handle, /* Get the new acceptor subkey. With the code above, there should always be one if we make it to this point. */ code = krb5_auth_con_getsendsubkey(context, auth_context, - &ctx->acceptor_subkey); + &keyblock); + if (code != 0) { + major_status = GSS_S_FAILURE; + goto fail; + } + code = krb5_k_create_key(context, keyblock, &ctx->acceptor_subkey); if (code != 0) { major_status = GSS_S_FAILURE; goto fail; } ctx->have_acceptor_subkey = 1; + krb5_free_keyblock(context, keyblock); + keyblock = NULL; code = kg_setup_keys(context, ctx, ctx->acceptor_subkey, &ctx->acceptor_subkey_cksumtype); @@ -1150,6 +1163,8 @@ fail: xfree(reqcksum.contents); if (ap_rep.data) krb5_free_data_contents(context, &ap_rep); + if (keyblock) + krb5_free_keyblock(context, keyblock); if (major_status == GSS_S_COMPLETE || (major_status == GSS_S_CONTINUE_NEEDED && code != KRB5KRB_AP_ERR_MSG_TYPE)) { ctx->k5_context = context; diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c index e2da3dc98..2032d5585 100644 --- a/src/lib/gssapi/krb5/delete_sec_context.c +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -82,19 +82,19 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) g_order_free(&(ctx->seqstate)); if (ctx->enc) - krb5_free_keyblock(context, ctx->enc); + krb5_k_free_key(context, ctx->enc); if (ctx->seq) - krb5_free_keyblock(context, ctx->seq); + krb5_k_free_key(context, ctx->seq); if (ctx->here) kg_release_name(context, 0, &ctx->here); if (ctx->there) kg_release_name(context, 0, &ctx->there); if (ctx->subkey) - krb5_free_keyblock(context, ctx->subkey); + krb5_k_free_key(context, ctx->subkey); if (ctx->acceptor_subkey) - krb5_free_keyblock(context, ctx->acceptor_subkey); + krb5_k_free_key(context, ctx->acceptor_subkey); if (ctx->auth_context) { if (ctx->cred_rcache) diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index e05c5bc81..541a74554 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -190,15 +190,14 @@ typedef struct _krb5_gss_ctx_id_rec { unsigned char seed[16]; krb5_gss_name_t here; krb5_gss_name_t there; - krb5_keyblock *subkey; /*One of two potential keys to use with RFC - * 4121 packets; this key must always be set.*/ + krb5_key subkey; /* One of two potential keys to use with RFC 4121 + * packets; this key must always be set. */ int signalg; size_t cksum_size; int sealalg; - krb5_keyblock *enc; /*RFC 1964 encryption key;seq xored with a - * constant for DES, - * seq for other RFC 1964 enctypes */ - krb5_keyblock *seq; /*RFC 1964 sequencing key*/ + krb5_key enc; /* RFC 1964 encryption key; seq xored with a constant + * for DES, seq for other RFC 1964 enctypes */ + krb5_key seq; /* RFC 1964 sequencing key */ krb5_ticket_times krb_times; krb5_flags krb_flags; /* XXX these used to be signed. the old spec is inspecific, and @@ -218,7 +217,7 @@ typedef struct _krb5_gss_ctx_id_rec { 1964 tokens is permitted.*/ int proto; krb5_cksumtype cksumtype; /* for "main" subkey */ - krb5_keyblock *acceptor_subkey; /* CFX only */ + krb5_key acceptor_subkey; /* CFX only */ krb5_cksumtype acceptor_subkey_cksumtype; int cred_rcache; /* did we get rcache from creds? */ krb5_authdata **authdata; @@ -259,32 +258,32 @@ krb5_error_code kg_checksum_channel_bindings int bigend); krb5_error_code kg_make_seq_num (krb5_context context, - krb5_keyblock *key, + krb5_key key, int direction, krb5_ui_4 seqnum, unsigned char *cksum, unsigned char *buf); krb5_error_code kg_get_seq_num (krb5_context context, - krb5_keyblock *key, + krb5_key key, unsigned char *cksum, unsigned char *buf, int *direction, krb5_ui_4 *seqnum); krb5_error_code kg_make_seed (krb5_context context, - krb5_keyblock *key, + krb5_key key, unsigned char *seed); krb5_error_code kg_setup_keys(krb5_context context, krb5_gss_ctx_id_rec *ctx, - krb5_keyblock *subkey, + krb5_key subkey, krb5_cksumtype *cksumtype); -int kg_confounder_size (krb5_context context, krb5_keyblock *key); +int kg_confounder_size (krb5_context context, krb5_key key); krb5_error_code kg_make_confounder (krb5_context context, - krb5_keyblock *key, unsigned char *buf); + krb5_key key, unsigned char *buf); krb5_error_code kg_encrypt (krb5_context context, - krb5_keyblock *key, int usage, + krb5_key key, int usage, krb5_pointer iv, krb5_const_pointer in, krb5_pointer out, @@ -293,7 +292,7 @@ krb5_error_code kg_encrypt (krb5_context context, krb5_error_code kg_encrypt_iov (krb5_context context, int proto, int dce_style, size_t ec, size_t rrc, - krb5_keyblock *key, int usage, + krb5_key key, int usage, krb5_pointer iv, gss_iov_buffer_desc *iov, int iov_count); @@ -312,7 +311,7 @@ kg_arcfour_docrypt_iov (krb5_context context, int iov_count); krb5_error_code kg_decrypt (krb5_context context, - krb5_keyblock *key, int usage, + krb5_key key, int usage, krb5_pointer iv, krb5_const_pointer in, krb5_pointer out, @@ -321,7 +320,7 @@ krb5_error_code kg_decrypt (krb5_context context, krb5_error_code kg_decrypt_iov (krb5_context context, int proto, int dce_style, size_t ec, size_t rrc, - krb5_keyblock *key, int usage, + krb5_key key, int usage, krb5_pointer iv, gss_iov_buffer_desc *iov, int iov_count); @@ -409,8 +408,8 @@ void kg_release_iov(gss_iov_buffer_desc *iov, krb5_error_code kg_make_checksum_iov_v1(krb5_context context, krb5_cksumtype type, size_t token_cksum_len, - krb5_keyblock *seq, - krb5_keyblock *enc, /* for conf len */ + krb5_key seq, + krb5_key enc, /* for conf len */ krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, @@ -420,7 +419,7 @@ krb5_error_code kg_make_checksum_iov_v1(krb5_context context, krb5_error_code kg_make_checksum_iov_v3(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, + krb5_key key, krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count); @@ -428,7 +427,7 @@ krb5_error_code kg_make_checksum_iov_v3(krb5_context context, krb5_error_code kg_verify_checksum_iov_v3(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, + krb5_key key, krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 62e7d6ed7..e04818f76 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -482,6 +482,7 @@ kg_new_connection( krb5_gss_ctx_id_rec *ctx, *ctx_free; krb5_timestamp now; gss_buffer_desc token; + krb5_keyblock *keyblock; k5_mutex_assert_locked(&cred->lock); major_status = GSS_S_FAILURE; @@ -602,8 +603,14 @@ kg_new_connection( krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp); ctx->seq_send = seq_temp; - krb5_auth_con_getsendsubkey(context, ctx->auth_context, - &ctx->subkey); + code = krb5_auth_con_getsendsubkey(context, ctx->auth_context, + &keyblock); + if (code != 0) + goto fail; + code = krb5_k_create_key(context, keyblock, &ctx->subkey); + krb5_free_keyblock(context, keyblock); + if (code != 0) + goto fail; } krb5_free_creds(context, k_cred); @@ -668,7 +675,7 @@ fail: if (ctx_free->there) kg_release_name(context, 0, &ctx_free->there); if (ctx_free->subkey) - krb5_free_keyblock(context, ctx_free->subkey); + krb5_k_free_key(context, ctx_free->subkey); xfree(ctx_free); } else (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); @@ -797,7 +804,7 @@ mutual_auth( * To be removed in 1999 -- proven */ krb5_auth_con_setuseruserkey(context, ctx->auth_context, - ctx->subkey); + &ctx->subkey->keyblock); if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, &ap_rep_data))) goto fail; @@ -811,11 +818,11 @@ mutual_auth( if (ap_rep_data->subkey != NULL && (ctx->proto == 1 || (ctx->gss_flags & GSS_C_DCE_STYLE) || - ap_rep_data->subkey->enctype != ctx->subkey->enctype)) { + ap_rep_data->subkey->enctype != ctx->subkey->keyblock.enctype)) { /* Keep acceptor's subkey. */ ctx->have_acceptor_subkey = 1; - code = krb5_copy_keyblock(context, ap_rep_data->subkey, - &ctx->acceptor_subkey); + code = krb5_k_create_key(context, ap_rep_data->subkey, + &ctx->acceptor_subkey); if (code) { krb5_free_ap_rep_enc_part(context, ap_rep_data); goto fail; diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c index fbc389245..eaf1c4d02 100644 --- a/src/lib/gssapi/krb5/inq_context.c +++ b/src/lib/gssapi/krb5/inq_context.c @@ -187,7 +187,7 @@ gss_krb5int_inq_session_key( gss_buffer_set_t *data_set) { krb5_gss_ctx_id_rec *ctx; - krb5_keyblock *key; + krb5_key key; gss_buffer_desc keyvalue, keyinfo; OM_uint32 major_status, minor; unsigned char oid_buf[GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH + 6]; @@ -196,8 +196,8 @@ gss_krb5int_inq_session_key( ctx = (krb5_gss_ctx_id_rec *) context_handle; key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey; - keyvalue.value = key->contents; - keyvalue.length = key->length; + keyvalue.value = key->keyblock.contents; + keyvalue.length = key->keyblock.length; major_status = generic_gss_add_buffer_set_member(minor_status, &keyvalue, data_set); if (GSS_ERROR(major_status)) @@ -209,7 +209,7 @@ gss_krb5int_inq_session_key( major_status = generic_gss_oid_compose(minor_status, GSS_KRB5_SESSION_KEY_ENCTYPE_OID, GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH, - key->enctype, + key->keyblock.enctype, &oid); if (GSS_ERROR(major_status)) goto cleanup; diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index 1949020ab..7a6e5aae8 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -53,8 +53,8 @@ static krb5_error_code make_seal_token_v1 (krb5_context context, - krb5_keyblock *enc, - krb5_keyblock *seq, + krb5_key enc, + krb5_key seq, gssint_uint64 *seqnum, int direction, gss_buffer_t text, @@ -197,7 +197,7 @@ make_seal_token_v1 (krb5_context context, (void) memcpy(data_ptr+8, plain, msglen); plaind.length = 8 + (bigend ? text->length : msglen); plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq, + code = krb5_k_make_checksum(context, md5cksum.checksum_type, seq, sign_usage, &plaind, &md5cksum); xfree(data_ptr); @@ -212,7 +212,7 @@ make_seal_token_v1 (krb5_context context, if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL, (g_OID_equal(oid, gss_mech_krb5_old) ? - seq->contents : NULL), + seq->keyblock.contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { krb5_free_checksum_contents(context, &md5cksum); xfree (plain); @@ -259,7 +259,7 @@ make_seal_token_v1 (krb5_context context, krb5_keyblock *enc_key; int i; store_32_be(*seqnum, bigend_seqnum); - code = krb5_copy_keyblock (context, enc, &enc_key); + code = krb5_k_key_keyblock(context, enc, &enc_key); if (code) { xfree(plain); diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c index f4354a9f3..1a9eac994 100644 --- a/src/lib/gssapi/krb5/k5sealiov.c +++ b/src/lib/gssapi/krb5/k5sealiov.c @@ -193,7 +193,7 @@ make_seal_token_v1_iov(krb5_context context, case SGN_ALG_3: code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq->contents : NULL), + ctx->seq->keyblock.contents : NULL), md5cksum.contents, md5cksum.contents, 16); if (code != 0) goto cleanup; @@ -226,7 +226,7 @@ make_seal_token_v1_iov(krb5_context context, store_32_be(ctx->seq_send, bigend_seqnum); - code = krb5_copy_keyblock(context, ctx->enc, &enc_key); + code = krb5_k_key_keyblock(context, ctx->enc, &enc_key); if (code != 0) goto cleanup; @@ -408,13 +408,12 @@ kg_seal_iov_length(OM_uint32 *minor_status, gss_headerlen = gss_padlen = gss_trailerlen = 0; if (ctx->proto == 1) { + krb5_key key; krb5_enctype enctype; size_t ec; - if (ctx->have_acceptor_subkey) - enctype = ctx->acceptor_subkey->enctype; - else - enctype = ctx->subkey->enctype; + key = (ctx->have_acceptor_subkey) ? ctx->acceptor_subkey : ctx->subkey; + enctype = key->keyblock.enctype; code = krb5_c_crypto_length(context, enctype, conf_req_flag ? diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c index 26e20d73b..ad5c03a39 100644 --- a/src/lib/gssapi/krb5/k5sealv3.c +++ b/src/lib/gssapi/krb5/k5sealv3.c @@ -81,7 +81,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, size_t ec; unsigned short tok_id; krb5_checksum sum; - krb5_keyblock *key; + krb5_key key; krb5_cksumtype cksumtype; assert(ctx->big_endian == 0); @@ -136,7 +136,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, return ENOMEM; /* Get size of ciphertext. */ - bufsize = 16 + krb5_encrypt_size (plain.length, key->enctype); + bufsize = 16 + krb5_encrypt_size (plain.length, key->keyblock.enctype); /* Allocate space for header plus encrypted data. */ outbuf = malloc(bufsize); if (outbuf == NULL) { @@ -164,8 +164,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, cipher.ciphertext.data = (char *)outbuf + 16; cipher.ciphertext.length = bufsize - 16; - cipher.enctype = key->enctype; - err = krb5_c_encrypt(context, key, key_usage, 0, &plain, &cipher); + cipher.enctype = key->keyblock.enctype; + err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher); zap(plain.data, plain.length); free(plain.data); plain.data = 0; @@ -245,7 +245,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, sum.contents = outbuf + 16 + message2->length; sum.length = cksumsize; - err = krb5_c_make_checksum(context, cksumtype, key, + err = krb5_k_make_checksum(context, cksumtype, key, key_usage, &plain, &sum); zap(plain.data, plain.length); free(plain.data); @@ -317,7 +317,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, krb5_checksum sum; krb5_error_code err; krb5_boolean valid; - krb5_keyblock *key; + krb5_key key; krb5_cksumtype cksumtype; if (ctx->big_endian != 0) @@ -398,14 +398,14 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, For all current cryptosystems, the ciphertext size will be larger than the plaintext size. */ - cipher.enctype = key->enctype; + cipher.enctype = key->keyblock.enctype; cipher.ciphertext.length = bodysize - 16; cipher.ciphertext.data = (char *)ptr + 16; plain.length = bodysize - 16; plain.data = malloc(plain.length); if (plain.data == NULL) goto no_mem; - err = krb5_c_decrypt(context, key, key_usage, 0, + err = krb5_k_decrypt(context, key, key_usage, 0, &cipher, &plain); if (err) { free(plain.data); @@ -459,7 +459,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, } sum.contents = ptr+bodysize-ec; sum.checksum_type = cksumtype; - err = krb5_c_verify_checksum(context, key, key_usage, + err = krb5_k_verify_checksum(context, key, key_usage, &plain, &sum, &valid); if (err) goto error; @@ -496,7 +496,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, sum.length = bodysize - 16; sum.contents = ptr + 16; sum.checksum_type = cksumtype; - err = krb5_c_verify_checksum(context, key, key_usage, + err = krb5_k_verify_checksum(context, key, key_usage, &plain, &sum, &valid); free(plain.data); plain.data = NULL; diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c index c30352b0a..b5b979310 100644 --- a/src/lib/gssapi/krb5/k5sealv3iov.c +++ b/src/lib/gssapi/krb5/k5sealv3iov.c @@ -53,7 +53,7 @@ gss_krb5int_make_seal_token_v3_iov(krb5_context context, int key_usage; size_t rrc = 0; unsigned int gss_headerlen, gss_trailerlen; - krb5_keyblock *key; + krb5_key key; krb5_cksumtype cksumtype; size_t data_length, assoc_data_length; @@ -95,24 +95,26 @@ gss_krb5int_make_seal_token_v3_iov(krb5_context context, size_t ec = 0; size_t conf_data_length = data_length - assoc_data_length; - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); if (code != 0) goto cleanup; - code = krb5_c_padding_length(context, key->enctype, + code = krb5_c_padding_length(context, key->keyblock.enctype, conf_data_length + 16 /* E(Header) */, &k5_padlen); if (code != 0) goto cleanup; if (k5_padlen == 0 && (ctx->gss_flags & GSS_C_DCE_STYLE)) { /* Windows rejects AEAD tokens with non-zero EC */ - code = krb5_c_block_size(context, key->enctype, &ec); + code = krb5_c_block_size(context, key->keyblock.enctype, &ec); if (code != 0) goto cleanup; } else ec = k5_padlen; - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); if (code != 0) goto cleanup; @@ -186,7 +188,9 @@ gss_krb5int_make_seal_token_v3_iov(krb5_context context, gss_headerlen = 16; - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &gss_trailerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_CHECKSUM, + &gss_trailerlen); if (code != 0) goto cleanup; @@ -291,7 +295,7 @@ gss_krb5int_unseal_v3_iov(krb5_context context, int key_usage; size_t rrc, ec; size_t data_length, assoc_data_length; - krb5_keyblock *key; + krb5_key key; gssint_uint64 seqnum; krb5_boolean valid; krb5_cksumtype cksumtype; @@ -357,7 +361,7 @@ gss_krb5int_unseal_v3_iov(krb5_context context, rrc = load_16_be(ptr + 6); seqnum = load_64_be(ptr + 8); - code = krb5_c_crypto_length(context, key->enctype, + code = krb5_c_crypto_length(context, key->keyblock.enctype, conf_flag ? KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM, &k5_trailerlen); diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index f55180af8..2ef59a722 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -176,7 +176,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, krb5_keyblock *enc_key; int i; store_32_be(seqnum, bigend_seqnum); - code = krb5_copy_keyblock (context, ctx->enc, &enc_key); + code = krb5_k_key_keyblock(context, ctx->enc, &enc_key); if (code) { xfree(plain); @@ -287,7 +287,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, + code = krb5_k_make_checksum(context, md5cksum.checksum_type, ctx->seq, sign_usage, &plaind, &md5cksum); xfree(data_ptr); @@ -301,7 +301,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq->contents : NULL), + ctx->seq->keyblock.contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { krb5_free_checksum_contents(context, &md5cksum); if (toktype == KG_TOK_SEAL_MSG) @@ -354,7 +354,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, (ctx->big_endian ? token.length : plainlen); plaind.data = data_ptr; krb5_free_checksum_contents(context, &md5cksum); - code = krb5_c_make_checksum(context, md5cksum.checksum_type, + code = krb5_k_make_checksum(context, md5cksum.checksum_type, ctx->seq, sign_usage, &plaind, &md5cksum); xfree(data_ptr); @@ -400,7 +400,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, + code = krb5_k_make_checksum(context, md5cksum.checksum_type, ctx->seq, sign_usage, &plaind, &md5cksum); xfree(data_ptr); diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c index 5d2bd1afa..d09bf89a4 100644 --- a/src/lib/gssapi/krb5/k5unsealiov.c +++ b/src/lib/gssapi/krb5/k5unsealiov.c @@ -153,7 +153,7 @@ kg_unseal_v1_iov(krb5_context context, store_32_be(seqnum, bigend_seqnum); - code = krb5_copy_keyblock(context, ctx->enc, &enc_key); + code = krb5_k_key_keyblock(context, ctx->enc, &enc_key); if (code != 0) { retval = GSS_S_FAILURE; goto cleanup; @@ -231,7 +231,7 @@ kg_unseal_v1_iov(krb5_context context, case SGN_ALG_3: code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq->contents : NULL), + ctx->seq->keyblock.contents : NULL), md5cksum.contents, md5cksum.contents, 16); if (code != 0) { retval = GSS_S_FAILURE; @@ -518,7 +518,7 @@ kg_unseal_stream_iov(OM_uint32 *minor_status, case KG2_TOK_WRAP_MSG: case KG2_TOK_DEL_CTX: { size_t ec, rrc; - krb5_enctype enctype = ctx->enc->enctype; + krb5_enctype enctype = ctx->enc->keyblock.enctype; unsigned int k5_headerlen = 0; unsigned int k5_trailerlen = 0; diff --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c index cefac261e..fb5a8e787 100644 --- a/src/lib/gssapi/krb5/lucid_context.c +++ b/src/lib/gssapi/krb5/lucid_context.c @@ -213,7 +213,7 @@ make_external_lucid_ctx_v1( lctx->rfc1964_kd.sign_alg = gctx->signalg; lctx->rfc1964_kd.seal_alg = gctx->sealalg; /* Copy key */ - if ((retval = copy_keyblock_to_lucid_key(gctx->seq, + if ((retval = copy_keyblock_to_lucid_key(&gctx->seq->keyblock, &lctx->rfc1964_kd.ctx_key))) goto error_out; } @@ -221,11 +221,11 @@ make_external_lucid_ctx_v1( /* Copy keys */ /* (subkey is always present, either a copy of the kerberos session key or a subkey) */ - if ((retval = copy_keyblock_to_lucid_key(gctx->subkey, + if ((retval = copy_keyblock_to_lucid_key(&gctx->subkey->keyblock, &lctx->cfx_kd.ctx_key))) goto error_out; if (gctx->have_acceptor_subkey) { - if ((retval = copy_keyblock_to_lucid_key(gctx->acceptor_subkey, + if ((retval = copy_keyblock_to_lucid_key(&gctx->acceptor_subkey->keyblock, &lctx->cfx_kd.acceptor_subkey))) goto error_out; lctx->cfx_kd.have_acceptor_subkey = 1; diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 9b55a6507..bdcd7685e 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -304,19 +304,19 @@ kg_ctx_size(kcontext, arg, sizep) if (!kret && ctx->subkey) kret = krb5_size_opaque(kcontext, KV5M_KEYBLOCK, - (krb5_pointer) ctx->subkey, + (krb5_pointer) &ctx->subkey->keyblock, &required); if (!kret && ctx->enc) kret = krb5_size_opaque(kcontext, KV5M_KEYBLOCK, - (krb5_pointer) ctx->enc, + (krb5_pointer) &ctx->enc->keyblock, &required); if (!kret && ctx->seq) kret = krb5_size_opaque(kcontext, KV5M_KEYBLOCK, - (krb5_pointer) ctx->seq, + (krb5_pointer) &ctx->seq->keyblock, &required); if (!kret) @@ -339,8 +339,8 @@ kg_ctx_size(kcontext, arg, sizep) &required); if (!kret && ctx->acceptor_subkey) kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->acceptor_subkey, + KV5M_KEYBLOCK, (krb5_pointer) + &ctx->acceptor_subkey->keyblock, &required); if (!kret && ctx->authdata) { krb5_int32 i; @@ -459,20 +459,20 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) if (!kret && ctx->subkey) kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->subkey, + KV5M_KEYBLOCK, (krb5_pointer) + &ctx->subkey->keyblock, &bp, &remain); if (!kret && ctx->enc) kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->enc, + KV5M_KEYBLOCK, (krb5_pointer) + &ctx->enc->keyblock, &bp, &remain); if (!kret && ctx->seq) kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->seq, + KV5M_KEYBLOCK, (krb5_pointer) + &ctx->seq->keyblock, &bp, &remain); if (!kret && ctx->seqstate) @@ -499,8 +499,8 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); if (!kret && ctx->acceptor_subkey) kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) ctx->acceptor_subkey, + KV5M_KEYBLOCK, (krb5_pointer) + &ctx->acceptor_subkey->keyblock, &bp, &remain); if (!kret) kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype, @@ -554,6 +554,22 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) return(kret); } +/* Internalize a keyblock and convert it to a key. */ +static krb5_error_code +intern_key(krb5_context ctx, krb5_key *key, krb5_octet **bp, size_t *sp) +{ + krb5_keyblock *keyblock; + krb5_error_code ret; + + ret = krb5_internalize_opaque(ctx, KV5M_KEYBLOCK, + (krb5_pointer *) &keyblock, bp, sp); + if (ret != 0) + return ret; + ret = krb5_k_create_key(ctx, keyblock, key); + krb5_free_keyblock(ctx, keyblock); + return ret; +} + /* * Internalize this krb5_gss_ctx_id_t. */ @@ -670,26 +686,17 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) kret = 0; } if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) &ctx->subkey, - &bp, &remain))) { + (kret = intern_key(kcontext, &ctx->subkey, &bp, &remain))) { if (kret == EINVAL) kret = 0; } if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) &ctx->enc, - &bp, &remain))) { + (kret = intern_key(kcontext, &ctx->enc, &bp, &remain))) { if (kret == EINVAL) kret = 0; } if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) &ctx->seq, - &bp, &remain))) { + (kret = intern_key(kcontext, &ctx->seq, &bp, &remain))) { if (kret == EINVAL) kret = 0; } @@ -720,10 +727,8 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->cksumtype = ibuf; if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) &ctx->acceptor_subkey, - &bp, &remain))) { + (kret = intern_key(kcontext, &ctx->acceptor_subkey, + &bp, &remain))) { if (kret == EINVAL) kret = 0; } @@ -781,11 +786,11 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) *argp = (krb5_pointer) ctx; } else { if (ctx->seq) - krb5_free_keyblock(kcontext, ctx->seq); + krb5_k_free_key(kcontext, ctx->seq); if (ctx->enc) - krb5_free_keyblock(kcontext, ctx->enc); + krb5_k_free_key(kcontext, ctx->enc); if (ctx->subkey) - krb5_free_keyblock(kcontext, ctx->subkey); + krb5_k_free_key(kcontext, ctx->subkey); if (ctx->there) kg_release_name(kcontext, 0, &ctx->there); if (ctx->here) diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index fc6c849c9..9d4e08ff8 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -112,8 +112,8 @@ krb5_error_code kg_make_checksum_iov_v1(krb5_context context, krb5_cksumtype type, size_t cksum_len, - krb5_keyblock *seq, - krb5_keyblock *enc, + krb5_key seq, + krb5_key enc, krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, @@ -137,7 +137,7 @@ kg_make_checksum_iov_v1(krb5_context context, /* Checksum over ( Header | Confounder | Data | Pad ) */ if (toktype == KG_TOK_WRAP_MSG) - conf_len = kg_confounder_size(context, (krb5_keyblock *)enc); + conf_len = kg_confounder_size(context, enc); /* Checksum output */ kiov[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; @@ -173,7 +173,7 @@ kg_make_checksum_iov_v1(krb5_context context, i++; } - code = krb5_c_make_checksum_iov(context, type, seq, sign_usage, kiov, kiov_count); + code = krb5_k_make_checksum_iov(context, type, seq, sign_usage, kiov, kiov_count); if (code == 0) { checksum->length = kiov[0].data.length; checksum->contents = (unsigned char *)kiov[0].data.data; @@ -189,7 +189,7 @@ static krb5_error_code checksum_iov_v3(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, + krb5_key key, krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, @@ -207,7 +207,7 @@ checksum_iov_v3(krb5_context context, if (verify) *valid = FALSE; - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen); if (code != 0) return code; @@ -258,9 +258,9 @@ checksum_iov_v3(krb5_context context, i++; if (verify) - code = krb5_c_verify_checksum_iov(context, type, key, sign_usage, kiov, kiov_count, valid); + code = krb5_k_verify_checksum_iov(context, type, key, sign_usage, kiov, kiov_count, valid); else - code = krb5_c_make_checksum_iov(context, type, key, sign_usage, kiov, kiov_count); + code = krb5_k_make_checksum_iov(context, type, key, sign_usage, kiov, kiov_count); xfree(kiov); @@ -271,7 +271,7 @@ krb5_error_code kg_make_checksum_iov_v3(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, + krb5_key key, krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count) @@ -284,7 +284,7 @@ krb5_error_code kg_verify_checksum_iov_v3(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, + krb5_key key, krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 87e04065f..53e420d9f 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -59,39 +59,53 @@ static const char kg_arcfour_l40[] = "fortybits"; static krb5_error_code kg_copy_keys(krb5_context context, krb5_gss_ctx_id_rec *ctx, - krb5_keyblock *subkey) + krb5_key subkey) { krb5_error_code code; - if (ctx->enc != NULL) { - krb5_free_keyblock(context, ctx->enc); - ctx->enc = NULL; - } + krb5_k_free_key(context, ctx->enc); + ctx->enc = NULL; + code = krb5_k_create_key(context, &subkey->keyblock, &ctx->enc); + if (code != 0) + return code; - code = krb5_copy_keyblock(context, subkey, &ctx->enc); + krb5_k_free_key(context, ctx->seq); + ctx->seq = NULL; + code = krb5_k_create_key(context, &subkey->keyblock, &ctx->seq); if (code != 0) return code; - if (ctx->seq != NULL) { - krb5_free_keyblock(context, ctx->seq); - ctx->seq = NULL; - } + return 0; +} + +static krb5_error_code +kg_derive_des_enc_key(krb5_context context, krb5_key subkey, krb5_key *out) +{ + krb5_error_code code; + krb5_keyblock *keyblock; + unsigned int i; + + *out = NULL; - code = krb5_copy_keyblock(context, subkey, &ctx->seq); + code = krb5_k_key_keyblock(context, subkey, &keyblock); if (code != 0) return code; - return 0; + for (i = 0; i < keyblock->length; i++) + keyblock->contents[i] ^= 0xF0; + + code = krb5_k_create_key(context, keyblock, out); + krb5_free_keyblock(context, keyblock); + return code; } krb5_error_code kg_setup_keys(krb5_context context, krb5_gss_ctx_id_rec *ctx, - krb5_keyblock *subkey, + krb5_key subkey, krb5_cksumtype *cksumtype) { krb5_error_code code; - unsigned int i; krb5int_access kaccess; assert(ctx != NULL); @@ -109,36 +123,40 @@ kg_setup_keys(krb5_context context, if (code != 0) return code; - code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype, + code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, + subkey->keyblock.enctype, cksumtype); if (code != 0) return code; - switch (subkey->enctype) { + switch (subkey->keyblock.enctype) { case ENCTYPE_DES_CBC_MD5: case ENCTYPE_DES_CBC_MD4: case ENCTYPE_DES_CBC_CRC: - code = kg_copy_keys(context, ctx, subkey); + krb5_k_free_key(context, ctx->seq); + code = krb5_k_create_key(context, &subkey->keyblock, &ctx->seq); + if (code != 0) + return code; + + krb5_k_free_key(context, ctx->enc); + code = kg_derive_des_enc_key(context, subkey, &ctx->enc); if (code != 0) return code; - ctx->enc->enctype = ENCTYPE_DES_CBC_RAW; - ctx->seq->enctype = ENCTYPE_DES_CBC_RAW; + ctx->enc->keyblock.enctype = ENCTYPE_DES_CBC_RAW; + ctx->seq->keyblock.enctype = ENCTYPE_DES_CBC_RAW; ctx->signalg = SGN_ALG_DES_MAC_MD5; ctx->cksum_size = 8; ctx->sealalg = SEAL_ALG_DES; - for (i = 0; i < ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xF0; break; case ENCTYPE_DES3_CBC_SHA1: code = kg_copy_keys(context, ctx, subkey); if (code != 0) return code; - ctx->enc->enctype = ENCTYPE_DES3_CBC_RAW; - ctx->seq->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->enc->keyblock.enctype = ENCTYPE_DES3_CBC_RAW; + ctx->seq->keyblock.enctype = ENCTYPE_DES3_CBC_RAW; ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; ctx->cksum_size = 20; ctx->sealalg = SEAL_ALG_DES3KD; @@ -164,15 +182,15 @@ kg_setup_keys(krb5_context context, int kg_confounder_size(context, key) krb5_context context; - krb5_keyblock *key; + krb5_key key; { krb5_error_code code; size_t blocksize; /* We special case rc4*/ - if (key->enctype == ENCTYPE_ARCFOUR_HMAC || - key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC || + key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) return 8; - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(-1); /* XXX */ @@ -182,7 +200,7 @@ kg_confounder_size(context, key) krb5_error_code kg_make_confounder(context, key, buf) krb5_context context; - krb5_keyblock *key; + krb5_key key; unsigned char *buf; { int confsize; @@ -201,7 +219,7 @@ kg_make_confounder(context, key, buf) krb5_error_code kg_encrypt(context, key, usage, iv, in, out, length) krb5_context context; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; krb5_const_pointer in; @@ -214,7 +232,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) krb5_enc_data outputd; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -234,7 +252,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) outputd.ciphertext.length = length; outputd.ciphertext.data = out; - code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd); + code = krb5_k_encrypt(context, key, usage, pivd, &inputd, &outputd); if (pivd != NULL) free(pivd->data); return code; @@ -245,7 +263,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) krb5_error_code kg_decrypt(context, key, usage, iv, in, out, length) krb5_context context; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; krb5_const_pointer in; @@ -258,7 +276,7 @@ kg_decrypt(context, key, usage, iv, in, out, length) krb5_enc_data inputd; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -279,7 +297,7 @@ kg_decrypt(context, key, usage, iv, in, out, length) outputd.length = length; outputd.data = out; - code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd); + code = krb5_k_decrypt(context, key, usage, pivd, &inputd, &outputd); if (pivd != NULL) free(pivd->data); return code; @@ -294,6 +312,7 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, krb5_error_code code; krb5_data input, output; krb5int_access kaccess; + krb5_key key; krb5_keyblock seq_enc_key, usage_key; unsigned char t[14]; size_t i = 0; @@ -341,9 +360,11 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, input.length = input_len; output.data = (void * ) output_buf; output.length = input_len; - code = ((*kaccess.arcfour_enc_provider->encrypt)( - &seq_enc_key, 0, - &input, &output)); + code = krb5_k_create_key(NULL, &seq_enc_key, &key); + if (code) + goto cleanup_arcfour; + code = (*kaccess.arcfour_enc_provider->encrypt)(key, 0, &input, &output); + krb5_k_free_key(NULL, key); cleanup_arcfour: memset (seq_enc_key.contents, 0, seq_enc_key.length); memset (usage_key.contents, 0, usage_key.length); @@ -356,7 +377,7 @@ cleanup_arcfour: static krb5_error_code kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count) krb5_context context; - const krb5_keyblock *key; + krb5_key key; gss_iov_buffer_desc *iov; int iov_count; krb5_crypto_iov **pkiov; @@ -372,7 +393,7 @@ kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count) *pkiov = NULL; *pkiov_count = 0; - conf_len = kg_confounder_size(context, (krb5_keyblock *)key); + conf_len = kg_confounder_size(context, key); header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); assert(header != NULL); @@ -427,7 +448,7 @@ kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pki int dce_style; /* DCE_STYLE indicates actual RRC is EC + RRC */ size_t ec; /* Extra rotate count for DCE_STYLE, pad length otherwise */ size_t rrc; /* Rotate count */ - const krb5_keyblock *key; + krb5_key key; gss_iov_buffer_desc *iov; int iov_count; krb5_crypto_iov **pkiov; @@ -451,11 +472,13 @@ kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pki trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); assert(trailer == NULL || rrc == 0); - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); if (code != 0) return code; - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); if (code != 0) return code; @@ -541,7 +564,7 @@ kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, pkiov, int dce_style; size_t ec; size_t rrc; - const krb5_keyblock *key; + krb5_key key; gss_iov_buffer_desc *iov; int iov_count; krb5_crypto_iov **pkiov; @@ -559,7 +582,7 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun int dce_style; size_t ec; size_t rrc; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; gss_iov_buffer_desc *iov; @@ -572,7 +595,7 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun krb5_crypto_iov *kiov; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -589,7 +612,7 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun code = kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, &kiov, &kiov_count); if (code == 0) { - code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count); + code = krb5_k_encrypt_iov(context, key, usage, pivd, kiov, kiov_count); free(kiov); } @@ -608,7 +631,7 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun int dce_style; size_t ec; size_t rrc; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; gss_iov_buffer_desc *iov; @@ -621,7 +644,7 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun krb5_crypto_iov *kiov; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -638,7 +661,7 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun code = kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, &kiov, &kiov_count); if (code == 0) { - code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count); + code = krb5_k_decrypt_iov(context, key, usage, pivd, kiov, kiov_count); free(kiov); } @@ -657,6 +680,7 @@ kg_arcfour_docrypt_iov (krb5_context context, krb5_error_code code; krb5_data input, output; krb5int_access kaccess; + krb5_key key; krb5_keyblock seq_enc_key, usage_key; unsigned char t[14]; size_t i = 0; @@ -709,9 +733,12 @@ kg_arcfour_docrypt_iov (krb5_context context, if (code) goto cleanup_arcfour; - code = ((*kaccess.arcfour_enc_provider->encrypt_iov)( - &seq_enc_key, 0, - kiov, kiov_count)); + code = krb5_k_create_key(context, &seq_enc_key, &key); + if (code) + goto cleanup_arcfour; + code = (*kaccess.arcfour_enc_provider->encrypt_iov)(key, 0, kiov, + kiov_count); + krb5_k_free_key(context, key); cleanup_arcfour: memset (seq_enc_key.contents, 0, seq_enc_key.length); memset (usage_key.contents, 0, usage_key.length); diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c index b559f5e08..5c696ea3b 100644 --- a/src/lib/gssapi/krb5/util_seed.c +++ b/src/lib/gssapi/krb5/util_seed.c @@ -31,25 +31,31 @@ static const unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; krb5_error_code kg_make_seed(context, key, seed) krb5_context context; - krb5_keyblock *key; + krb5_key key; unsigned char *seed; { krb5_error_code code; - krb5_keyblock *tmpkey; + krb5_key rkey = NULL; + krb5_keyblock *tmpkey, *kb; unsigned int i; - code = krb5_copy_keyblock(context, key, &tmpkey); + code = krb5_k_key_keyblock(context, key, &tmpkey); if (code) return(code); /* reverse the key bytes, as per spec */ - + kb = &key->keyblock; for (i=0; ilength; i++) - tmpkey->contents[i] = key->contents[key->length - 1 - i]; + tmpkey->contents[i] = kb->contents[kb->length - 1 - i]; + + code = krb5_k_create_key(context, tmpkey, &rkey); + if (code) + goto cleanup; - code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16); + code = kg_encrypt(context, rkey, KG_USAGE_SEAL, NULL, zeros, seed, 16); +cleanup: krb5_free_keyblock(context, tmpkey); - + krb5_k_free_key(context, rkey); return(code); } diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c index b91dd658c..388990a30 100644 --- a/src/lib/gssapi/krb5/util_seqnum.c +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -32,7 +32,7 @@ krb5_error_code kg_make_seq_num(context, key, direction, seqnum, cksum, buf) krb5_context context; - krb5_keyblock *key; + krb5_key key; int direction; krb5_ui_4 seqnum; unsigned char *cksum; @@ -44,11 +44,11 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf) plain[5] = direction; plain[6] = direction; plain[7] = direction; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC || - key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC || + key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { /* Yes, Microsoft used big-endian sequence number.*/ store_32_be(seqnum, plain); - return kg_arcfour_docrypt (key, 0, + return kg_arcfour_docrypt (&key->keyblock, 0, cksum, 8, &plain[0], 8, buf); @@ -61,7 +61,7 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf) krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) krb5_context context; - krb5_keyblock *key; + krb5_key key; unsigned char *cksum; unsigned char *buf; int *direction; @@ -70,9 +70,9 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) krb5_error_code code; unsigned char plain[8]; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC || - key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { - code = kg_arcfour_docrypt (key, 0, + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC || + key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + code = kg_arcfour_docrypt (&key->keyblock, 0, cksum, 8, buf, 8, plain); @@ -88,8 +88,8 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) return((krb5_error_code) KG_BAD_SEQ); *direction = plain[4]; - if (key->enctype == ENCTYPE_ARCFOUR_HMAC || - key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC || + key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24)); } else { *seqnum = ((plain[0]) | diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c index 7fa9c44d6..0b90bba00 100644 --- a/src/lib/gssapi/krb5/wrap_size_limit.c +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -114,10 +114,12 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, /* Token header: 16 octets. */ if (conf_req_flag) { + krb5_key key; krb5_enctype enctype; - enctype = ctx->have_acceptor_subkey ? ctx->acceptor_subkey->enctype - : ctx->subkey->enctype; + key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey + : ctx->subkey; + enctype = key->keyblock.enctype; while (sz > 0 && krb5_encrypt_size(sz, enctype) + 16 > req_output_size) sz--; diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c index b88219cdb..ee31fb82b 100644 --- a/src/lib/krb5/krb/auth_con.c +++ b/src/lib/krb5/krb/auth_con.c @@ -56,12 +56,12 @@ krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context) krb5_free_address(context, auth_context->remote_port); if (auth_context->authentp) krb5_free_authenticator(context, auth_context->authentp); - if (auth_context->keyblock) - krb5_free_keyblock(context, auth_context->keyblock); + if (auth_context->key) + krb5_k_free_key(context, auth_context->key); if (auth_context->send_subkey) - krb5_free_keyblock(context, auth_context->send_subkey); + krb5_k_free_key(context, auth_context->send_subkey); if (auth_context->recv_subkey) - krb5_free_keyblock(context, auth_context->recv_subkey); + krb5_k_free_key(context, auth_context->recv_subkey); if (auth_context->rcache) krb5_rc_close(context, auth_context->rcache); if (auth_context->permitted_etypes) @@ -160,16 +160,16 @@ krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb krb5_error_code KRB5_CALLCONV krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock) { - if (auth_context->keyblock) - krb5_free_keyblock(context, auth_context->keyblock); - return(krb5_copy_keyblock(context, keyblock, &(auth_context->keyblock))); + if (auth_context->key) + krb5_k_free_key(context, auth_context->key); + return(krb5_k_create_key(context, keyblock, &(auth_context->key))); } krb5_error_code KRB5_CALLCONV krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock) { - if (auth_context->keyblock) - return krb5_copy_keyblock(context, auth_context->keyblock, keyblock); + if (auth_context->key) + return krb5_k_key_keyblock(context, auth_context->key, keyblock); *keyblock = NULL; return 0; } @@ -190,10 +190,10 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock) { if (ac->send_subkey != NULL) - krb5_free_keyblock(ctx, ac->send_subkey); + krb5_k_free_key(ctx, ac->send_subkey); ac->send_subkey = NULL; if (keyblock !=NULL) - return krb5_copy_keyblock(ctx, keyblock, &ac->send_subkey); + return krb5_k_create_key(ctx, keyblock, &ac->send_subkey); else return 0; } @@ -202,10 +202,10 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock) { if (ac->recv_subkey != NULL) - krb5_free_keyblock(ctx, ac->recv_subkey); + krb5_k_free_key(ctx, ac->recv_subkey); ac->recv_subkey = NULL; if (keyblock != NULL) - return krb5_copy_keyblock(ctx, keyblock, &ac->recv_subkey); + return krb5_k_create_key(ctx, keyblock, &ac->recv_subkey); else return 0; } @@ -214,7 +214,7 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock) { if (ac->send_subkey != NULL) - return krb5_copy_keyblock(ctx, ac->send_subkey, keyblock); + return krb5_k_key_keyblock(ctx, ac->send_subkey, keyblock); *keyblock = NULL; return 0; } @@ -223,7 +223,7 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock) { if (ac->recv_subkey != NULL) - return krb5_copy_keyblock(ctx, ac->recv_subkey, keyblock); + return krb5_k_key_keyblock(ctx, ac->recv_subkey, keyblock); *keyblock = NULL; return 0; } @@ -268,12 +268,13 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context) { krb5_error_code ret; + krb5_enctype enctype; - if (auth_context->keyblock) { + if (auth_context->key) { size_t blocksize; - if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype, - &blocksize))) + enctype = krb5_k_key_enctype(context, auth_context->key); + if ((ret = krb5_c_block_size(context, enctype, &blocksize))) return(ret); if ((auth_context->i_vector = (krb5_pointer)calloc(1,blocksize))) { return 0; diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h index 6254ac67c..684eb4e40 100644 --- a/src/lib/krb5/krb/auth_con.h +++ b/src/lib/krb5/krb/auth_con.h @@ -8,9 +8,9 @@ struct _krb5_auth_context { krb5_address * remote_port; krb5_address * local_addr; krb5_address * local_port; - krb5_keyblock * keyblock; - krb5_keyblock * send_subkey; - krb5_keyblock * recv_subkey; + krb5_key key; + krb5_key send_subkey; + krb5_key recv_subkey; krb5_int32 auth_context_flags; krb5_ui_4 remote_seq_number; diff --git a/src/lib/krb5/krb/copy_key.c b/src/lib/krb5/krb/copy_key.c index f926b4f36..4772c58c1 100644 --- a/src/lib/krb5/krb/copy_key.c +++ b/src/lib/krb5/krb/copy_key.c @@ -35,16 +35,5 @@ krb5_error_code KRB5_CALLCONV krb5_copy_keyblock(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to) { - krb5_keyblock *new_key; - - if (!(new_key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock)))) - return ENOMEM; - *new_key = *from; - if (!(new_key->contents = (krb5_octet *)malloc(new_key->length))) { - free(new_key); - return(ENOMEM); - } - memcpy(new_key->contents, from->contents, new_key->length); - *to = new_key; - return 0; + return krb5int_c_copy_keyblock(context, from, to); } diff --git a/src/lib/krb5/krb/cp_key_cnt.c b/src/lib/krb5/krb/cp_key_cnt.c index fb90bfac1..74efb5ef1 100644 --- a/src/lib/krb5/krb/cp_key_cnt.c +++ b/src/lib/krb5/krb/cp_key_cnt.c @@ -35,13 +35,5 @@ krb5_error_code KRB5_CALLCONV krb5_copy_keyblock_contents(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to) { - *to = *from; - if (to->length) { - to->contents = (krb5_octet *)malloc(to->length); - if (!to->contents) - return ENOMEM; - memcpy(to->contents, from->contents, to->length); - } else - to->contents = 0; - return 0; + return krb5int_c_copy_keyblock_contents(context, from, to); } diff --git a/src/lib/krb5/krb/enc_helper.c b/src/lib/krb5/krb/enc_helper.c index 34aa612d6..01324d014 100644 --- a/src/lib/krb5/krb/enc_helper.c +++ b/src/lib/krb5/krb/enc_helper.c @@ -48,3 +48,28 @@ krb5_encrypt_helper(krb5_context context, const krb5_keyblock *key, krb5_keyusag return(ret); } +krb5_error_code +krb5_encrypt_keyhelper(krb5_context context, krb5_key key, krb5_keyusage usage, + const krb5_data *plain, krb5_enc_data *cipher) +{ + krb5_enctype enctype; + krb5_error_code ret; + size_t enclen; + + enctype = krb5_k_key_enctype(context, key); + ret = krb5_c_encrypt_length(context, enctype, plain->length, &enclen); + if (ret != 0) + return ret; + + cipher->ciphertext.length = enclen; + cipher->ciphertext.data = malloc(enclen); + if (cipher->ciphertext.data == NULL) + return ENOMEM; + ret = krb5_k_encrypt(context, key, usage, 0, plain, cipher); + if (ret) { + free(cipher->ciphertext.data); + cipher->ciphertext.data = NULL; + } + + return ret; +} diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c index f17a14858..6ce0e354e 100644 --- a/src/lib/krb5/krb/mk_cred.c +++ b/src/lib/krb5/krb/mk_cred.c @@ -22,7 +22,7 @@ */ static krb5_error_code encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart, - krb5_keyblock *pkeyblock, krb5_enc_data *pencdata) + krb5_key pkey, krb5_enc_data *pencdata) { krb5_error_code retval; krb5_data * scratch; @@ -35,7 +35,7 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart, * If the keyblock is NULL, just copy the data from the encoded * data to the ciphertext area. */ - if (pkeyblock == NULL) { + if (pkey == NULL) { pencdata->ciphertext.data = scratch->data; pencdata->ciphertext.length = scratch->length; free(scratch); @@ -43,9 +43,9 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart, } /* call the encryption routine */ - retval = krb5_encrypt_helper(context, pkeyblock, - KRB5_KEYUSAGE_KRB_CRED_ENCPART, - scratch, pencdata); + retval = krb5_encrypt_keyhelper(context, pkey, + KRB5_KEYUSAGE_KRB_CRED_ENCPART, + scratch, pencdata); if (retval) { memset(pencdata->ciphertext.data, 0, pencdata->ciphertext.length); @@ -65,7 +65,7 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart, static krb5_error_code krb5_mk_ncred_basic(krb5_context context, krb5_creds **ppcreds, krb5_int32 nppcreds, - krb5_keyblock *keyblock, krb5_replay_data *replaydata, + krb5_key key, krb5_replay_data *replaydata, krb5_address *local_addr, krb5_address *remote_addr, krb5_cred *pcred) { @@ -134,8 +134,7 @@ krb5_mk_ncred_basic(krb5_context context, pcred->tickets[i] = NULL; /* encrypt the credential encrypted part */ - retval = encrypt_credencpart(context, &credenc, keyblock, - &pcred->enc_part); + retval = encrypt_credencpart(context, &credenc, key, &pcred->enc_part); cleanup: krb5_free_cred_enc_part(context, &credenc); @@ -158,7 +157,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_address remote_fulladdr; krb5_address local_fulladdr; krb5_error_code retval; - krb5_keyblock * keyblock; + krb5_key key; krb5_replay_data replaydata; krb5_cred * pcred; krb5_int32 ncred; @@ -188,8 +187,8 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, } /* Get keyblock */ - if ((keyblock = auth_context->send_subkey) == NULL) - keyblock = auth_context->keyblock; + if ((key = auth_context->send_subkey) == NULL) + key = auth_context->key; /* Get replay info */ if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) && @@ -246,7 +245,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, } /* Setup creds structure */ - if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, keyblock, + if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, key, &replaydata, plocal_fulladdr, premote_fulladdr, pcred))) { goto error; diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c index 30ffec3e1..824bfd507 100644 --- a/src/lib/krb5/krb/mk_priv.c +++ b/src/lib/krb5/krb/mk_priv.c @@ -33,10 +33,11 @@ static krb5_error_code krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata, - const krb5_keyblock *keyblock, krb5_replay_data *replaydata, + krb5_key key, krb5_replay_data *replaydata, krb5_address *local_addr, krb5_address *remote_addr, krb5_pointer i_vector, krb5_data *outbuf) { + krb5_enctype enctype = krb5_k_key_enctype(context, key); krb5_error_code retval; krb5_priv privmsg; krb5_priv_enc_part privmsg_enc_part; @@ -44,7 +45,7 @@ krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata, size_t blocksize, enclen; privmsg.enc_part.kvno = 0; /* XXX allow user-set? */ - privmsg.enc_part.enctype = keyblock->enctype; + privmsg.enc_part.enctype = enctype; privmsg_enc_part.user_data = *userdata; privmsg_enc_part.s_address = local_addr; @@ -60,7 +61,7 @@ krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata, return retval; /* put together an eblock for this encryption */ - if ((retval = krb5_c_encrypt_length(context, keyblock->enctype, + if ((retval = krb5_c_encrypt_length(context, enctype, scratch1->length, &enclen))) goto clean_scratch; @@ -73,15 +74,14 @@ krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata, /* call the encryption routine */ if (i_vector) { - if ((retval = krb5_c_block_size(context, keyblock->enctype, - &blocksize))) + if ((retval = krb5_c_block_size(context, enctype, &blocksize))) goto clean_encpart; ivdata.length = blocksize; ivdata.data = i_vector; } - if ((retval = krb5_c_encrypt(context, keyblock, + if ((retval = krb5_k_encrypt(context, key, KRB5_KEYUSAGE_KRB_PRIV_ENCPART, i_vector?&ivdata:0, scratch1, &privmsg.enc_part))) @@ -115,15 +115,15 @@ krb5_mk_priv(krb5_context context, krb5_auth_context auth_context, krb5_replay_data *outdata) { krb5_error_code retval; - krb5_keyblock * keyblock; + krb5_key key; krb5_replay_data replaydata; /* Clear replaydata block */ memset(&replaydata, 0, sizeof(krb5_replay_data)); /* Get keyblock */ - if ((keyblock = auth_context->send_subkey) == NULL) - keyblock = auth_context->keyblock; + if ((key = auth_context->send_subkey) == NULL) + key = auth_context->key; /* Get replay info */ if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) && @@ -192,7 +192,7 @@ krb5_mk_priv(krb5_context context, krb5_auth_context auth_context, } } - if ((retval = krb5_mk_priv_basic(context, userdata, keyblock, &replaydata, + if ((retval = krb5_mk_priv_basic(context, userdata, key, &replaydata, plocal_fulladdr, premote_fulladdr, auth_context->i_vector, outbuf))) { CLEANUP_DONE(); diff --git a/src/lib/krb5/krb/mk_rep.c b/src/lib/krb5/krb/mk_rep.c index 29155b6e1..a4dbc467f 100644 --- a/src/lib/krb5/krb/mk_rep.c +++ b/src/lib/krb5/krb/mk_rep.c @@ -80,7 +80,8 @@ k5_mk_rep(krb5_context context, krb5_auth_context auth_context, if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) || (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) && (auth_context->local_seq_number == 0)) { - if ((retval = krb5_generate_seq_number(context, auth_context->keyblock, + if ((retval = krb5_generate_seq_number(context, + &auth_context->key->keyblock, &auth_context->local_seq_number))) return(retval); } @@ -98,11 +99,11 @@ k5_mk_rep(krb5_context context, krb5_auth_context auth_context, assert(auth_context->negotiated_etype != ENCTYPE_NULL); retval = krb5int_generate_and_save_subkey (context, auth_context, - auth_context->keyblock, + &auth_context->key->keyblock, auth_context->negotiated_etype); if (retval) return retval; - repl.subkey = auth_context->send_subkey; + repl.subkey = &auth_context->send_subkey->keyblock; } else repl.subkey = auth_context->authentp->subkey; @@ -115,9 +116,9 @@ k5_mk_rep(krb5_context context, krb5_auth_context auth_context, if ((retval = encode_krb5_ap_rep_enc_part(&repl, &scratch))) return retval; - if ((retval = krb5_encrypt_helper(context, auth_context->keyblock, - KRB5_KEYUSAGE_AP_REP_ENCPART, - scratch, &reply.enc_part))) + if ((retval = krb5_encrypt_keyhelper(context, auth_context->key, + KRB5_KEYUSAGE_AP_REP_ENCPART, + scratch, &reply.enc_part))) goto cleanup_scratch; if (!(retval = encode_krb5_ap_rep(&reply, &toutbuf))) { diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c index df5ac2872..4277f1eec 100644 --- a/src/lib/krb5/krb/mk_req_ext.c +++ b/src/lib/krb5/krb/mk_req_ext.c @@ -73,7 +73,7 @@ make_etype_list(krb5_context context, static krb5_error_code krb5_generate_authenticator (krb5_context, krb5_authenticator *, krb5_principal, - krb5_checksum *, krb5_keyblock *, + krb5_checksum *, krb5_key, krb5_ui_4, krb5_authdata **, krb5_authdata_context ad_context, krb5_enctype *desired_etypes, @@ -94,6 +94,7 @@ krb5int_generate_and_save_subkey (krb5_context context, } rnd_data; krb5_data d; krb5_error_code retval; + krb5_keyblock *kb = NULL; if (krb5_crypto_us_timeofday(&rnd_data.sec, &rnd_data.usec) == 0) { d.length = sizeof(rnd_data); @@ -101,22 +102,23 @@ krb5int_generate_and_save_subkey (krb5_context context, krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_TIMING, &d); } - if (auth_context->send_subkey) - krb5_free_keyblock(context, auth_context->send_subkey); - if ((retval = krb5_generate_subkey_extended(context, keyblock, enctype, - &auth_context->send_subkey))) + retval = krb5_generate_subkey_extended(context, keyblock, enctype, &kb); + if (retval) return retval; + retval = krb5_auth_con_setsendsubkey(context, auth_context, kb); + if (retval) + goto cleanup; + retval = krb5_auth_con_setrecvsubkey(context, auth_context, kb); + if (retval) + goto cleanup; - if (auth_context->recv_subkey) - krb5_free_keyblock(context, auth_context->recv_subkey); - retval = krb5_copy_keyblock(context, auth_context->send_subkey, - &auth_context->recv_subkey); +cleanup: if (retval) { - krb5_free_keyblock(context, auth_context->send_subkey); - auth_context->send_subkey = NULL; - return retval; + (void) krb5_auth_con_setsendsubkey(context, auth_context, NULL); + (void) krb5_auth_con_setrecvsubkey(context, auth_context, NULL); } - return 0; + krb5_free_keyblock(context, kb); + return retval; } krb5_error_code KRB5_CALLCONV @@ -160,14 +162,14 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context, *auth_context = new_auth_context; } - if ((*auth_context)->keyblock != NULL) { - krb5_free_keyblock(context, (*auth_context)->keyblock); - (*auth_context)->keyblock = NULL; + if ((*auth_context)->key != NULL) { + krb5_k_free_key(context, (*auth_context)->key); + (*auth_context)->key = NULL; } /* set auth context keyblock */ - if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock, - &((*auth_context)->keyblock)))) + if ((retval = krb5_k_create_key(context, &in_creds->keyblock, + &((*auth_context)->key)))) goto cleanup; /* generate seq number if needed */ @@ -206,16 +208,18 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context, checksum.length = in_data->length; checksum.contents = (krb5_octet *) in_data->data; } else { + krb5_enctype enctype = krb5_k_key_enctype(context, + (*auth_context)->key); krb5_cksumtype cksumtype; - retval = krb5int_c_mandatory_cksumtype(context, (*auth_context)->keyblock->enctype, + retval = krb5int_c_mandatory_cksumtype(context, enctype, &cksumtype); if (retval) goto cleanup_cksum; if ((*auth_context)->req_cksumtype) cksumtype = (*auth_context)->req_cksumtype; - if ((retval = krb5_c_make_checksum(context, + if ((retval = krb5_k_make_checksum(context, cksumtype, - (*auth_context)->keyblock, + (*auth_context)->key, KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, in_data, &checksum))) goto cleanup_cksum; @@ -300,7 +304,7 @@ cleanup: static krb5_error_code krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent, krb5_principal client, krb5_checksum *cksum, - krb5_keyblock *key, krb5_ui_4 seq_number, + krb5_key key, krb5_ui_4 seq_number, krb5_authdata **authorization, krb5_authdata_context ad_context, krb5_enctype *desired_etypes, @@ -312,7 +316,7 @@ krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent, authent->client = client; authent->checksum = cksum; if (key) { - retval = krb5_copy_keyblock(context, key, &authent->subkey); + retval = krb5_k_key_keyblock(context, key, &authent->subkey); if (retval) return retval; } else diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c index 23358b957..f3bfde390 100644 --- a/src/lib/krb5/krb/mk_safe.c +++ b/src/lib/krb5/krb/mk_safe.c @@ -48,7 +48,7 @@ */ static krb5_error_code krb5_mk_safe_basic(krb5_context context, const krb5_data *userdata, - const krb5_keyblock *keyblock, krb5_replay_data *replaydata, + krb5_key key, krb5_replay_data *replaydata, krb5_address *local_addr, krb5_address *remote_addr, krb5_cksumtype sumtype, krb5_data *outbuf) { @@ -88,7 +88,7 @@ krb5_mk_safe_basic(krb5_context context, const krb5_data *userdata, if ((retval = encode_krb5_safe(&safemsg, &scratch1))) return retval; - if ((retval = krb5_c_make_checksum(context, sumtype, keyblock, + if ((retval = krb5_k_make_checksum(context, sumtype, key, KRB5_KEYUSAGE_KRB_SAFE_CKSUM, scratch1, &safe_checksum))) goto cleanup_checksum; @@ -115,15 +115,15 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, krb5_replay_data *outdata) { krb5_error_code retval; - krb5_keyblock * keyblock; + krb5_key key; krb5_replay_data replaydata; /* Clear replaydata block */ memset(&replaydata, 0, sizeof(krb5_replay_data)); - /* Get keyblock */ - if ((keyblock = auth_context->send_subkey) == NULL) - keyblock = auth_context->keyblock; + /* Get key */ + if ((key = auth_context->send_subkey) == NULL) + key = auth_context->key; /* Get replay info */ if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) && @@ -195,10 +195,11 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, } { + krb5_enctype enctype = krb5_k_key_enctype(context, key); unsigned int nsumtypes; unsigned int i; krb5_cksumtype *sumtypes; - retval = krb5_c_keyed_checksum_types (context, keyblock->enctype, + retval = krb5_c_keyed_checksum_types (context, enctype, &nsumtypes, &sumtypes); if (retval) { CLEANUP_DONE (); @@ -218,7 +219,7 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, sumtype = sumtypes[i]; krb5_free_cksumtypes (context, sumtypes); } - if ((retval = krb5_mk_safe_basic(context, userdata, keyblock, &replaydata, + if ((retval = krb5_mk_safe_basic(context, userdata, key, &replaydata, plocal_fulladdr, premote_fulladdr, sumtype, outbuf))) { CLEANUP_DONE(); diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c index 48637450d..a5d00dc4e 100644 --- a/src/lib/krb5/krb/rd_cred.c +++ b/src/lib/krb5/krb/rd_cred.c @@ -13,7 +13,7 @@ */ static krb5_error_code decrypt_credencdata(krb5_context context, krb5_cred *pcred, - krb5_keyblock *pkeyblock, krb5_cred_enc_part *pcredenc) + krb5_key pkey, krb5_cred_enc_part *pcredenc) { krb5_cred_enc_part * ppart = NULL; krb5_error_code retval; @@ -23,8 +23,8 @@ decrypt_credencdata(krb5_context context, krb5_cred *pcred, if (!(scratch.data = (char *)malloc(scratch.length))) return ENOMEM; - if (pkeyblock != NULL) { - if ((retval = krb5_c_decrypt(context, pkeyblock, + if (pkey != NULL) { + if ((retval = krb5_k_decrypt(context, pkey, KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0, &pcred->enc_part, &scratch))) goto cleanup; @@ -53,7 +53,7 @@ cleanup: static krb5_error_code krb5_rd_cred_basic(krb5_context context, krb5_data *pcreddata, - krb5_keyblock *pkeyblock, krb5_replay_data *replaydata, + krb5_key pkey, krb5_replay_data *replaydata, krb5_creds ***pppcreds) { krb5_error_code retval; @@ -68,7 +68,7 @@ krb5_rd_cred_basic(krb5_context context, krb5_data *pcreddata, memset(&encpart, 0, sizeof(encpart)); - if ((retval = decrypt_credencdata(context, pcred, pkeyblock, &encpart))) + if ((retval = decrypt_credencdata(context, pcred, pkey, &encpart))) goto cleanup_cred; @@ -167,12 +167,12 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_replay_data *outdata) { krb5_error_code retval; - krb5_keyblock * keyblock; + krb5_key key; krb5_replay_data replaydata; - /* Get keyblock */ - if ((keyblock = auth_context->recv_subkey) == NULL) - keyblock = auth_context->keyblock; + /* Get key */ + if ((key = auth_context->recv_subkey) == NULL) + key = auth_context->key; if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) || (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) && @@ -186,14 +186,14 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, /* - * If decrypting with the first keyblock we try fails, perhaps the + * If decrypting with the first key we try fails, perhaps the * credentials are stored in the session key so try decrypting with * that. */ - if ((retval = krb5_rd_cred_basic(context, pcreddata, keyblock, + if ((retval = krb5_rd_cred_basic(context, pcreddata, key, &replaydata, pppcreds))) { if ((retval = krb5_rd_cred_basic(context, pcreddata, - auth_context->keyblock, + auth_context->key, &replaydata, pppcreds))) { return retval; } diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c index eaeaed894..9b84ad87a 100644 --- a/src/lib/krb5/krb/rd_priv.c +++ b/src/lib/krb5/krb/rd_priv.c @@ -54,8 +54,7 @@ Returns system errors, integrity errors. static krb5_error_code krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf, - const krb5_keyblock *keyblock, - const krb5_address *local_addr, + const krb5_key key, const krb5_address *local_addr, const krb5_address *remote_addr, krb5_pointer i_vector, krb5_replay_data *replaydata, krb5_data *outbuf) { @@ -65,6 +64,7 @@ krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf, krb5_priv_enc_part * privmsg_enc_part; size_t blocksize; krb5_data ivdata; + krb5_enctype enctype; if (!krb5_is_krb_priv(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; @@ -74,8 +74,8 @@ krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf, return retval; if (i_vector) { - if ((retval = krb5_c_block_size(context, keyblock->enctype, - &blocksize))) + enctype = krb5_k_key_enctype(context, key); + if ((retval = krb5_c_block_size(context, enctype, &blocksize))) goto cleanup_privmsg; ivdata.length = blocksize; @@ -88,7 +88,7 @@ krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf, goto cleanup_privmsg; } - if ((retval = krb5_c_decrypt(context, keyblock, + if ((retval = krb5_k_decrypt(context, key, KRB5_KEYUSAGE_KRB_PRIV_ENCPART, i_vector?&ivdata:0, &privmsg->enc_part, &scratch))) @@ -156,12 +156,12 @@ krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, krb5_replay_data *outdata) { krb5_error_code retval; - krb5_keyblock * keyblock; + krb5_key key; krb5_replay_data replaydata; - /* Get keyblock */ - if ((keyblock = auth_context->recv_subkey) == NULL) - keyblock = auth_context->keyblock; + /* Get key */ + if ((key = auth_context->recv_subkey) == NULL) + key = auth_context->key; if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) || (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) && @@ -213,7 +213,7 @@ krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, } memset(&replaydata, 0, sizeof(replaydata)); - if ((retval = krb5_rd_priv_basic(context, inbuf, keyblock, + if ((retval = krb5_rd_priv_basic(context, inbuf, key, plocal_fulladdr, premote_fulladdr, auth_context->i_vector, diff --git a/src/lib/krb5/krb/rd_rep.c b/src/lib/krb5/krb/rd_rep.c index 1e3c14526..6e9cb0808 100644 --- a/src/lib/krb5/krb/rd_rep.c +++ b/src/lib/krb5/krb/rd_rep.c @@ -95,7 +95,7 @@ krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, goto clean_scratch; } - retval = krb5_c_decrypt(context, auth_context->keyblock, + retval = krb5_k_decrypt(context, auth_context->key, KRB5_KEYUSAGE_AP_REP_ENCPART, 0, &reply->enc_part, &scratch); if (retval) @@ -115,23 +115,14 @@ krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, /* Set auth subkey. */ if (enc->subkey) { - if (auth_context->recv_subkey) { - krb5_free_keyblock(context, auth_context->recv_subkey); - auth_context->recv_subkey = NULL; - } - retval = krb5_copy_keyblock(context, enc->subkey, - &auth_context->recv_subkey); + retval = krb5_auth_con_setrecvsubkey(context, auth_context, + enc->subkey); if (retval) goto clean_scratch; - if (auth_context->send_subkey) { - krb5_free_keyblock(context, auth_context->send_subkey); - auth_context->send_subkey = NULL; - } - retval = krb5_copy_keyblock(context, enc->subkey, - &auth_context->send_subkey); + retval = krb5_auth_con_setsendsubkey(context, auth_context, + enc->subkey); if (retval) { - krb5_free_keyblock(context, auth_context->send_subkey); - auth_context->send_subkey = NULL; + (void) krb5_auth_con_setrecvsubkey(context, auth_context, NULL); goto clean_scratch; } /* Not used for anything yet. */ @@ -178,7 +169,7 @@ krb5_rd_rep_dce(krb5_context context, krb5_auth_context auth_context, return(ENOMEM); } - if ((retval = krb5_c_decrypt(context, auth_context->keyblock, + if ((retval = krb5_k_decrypt(context, auth_context->key, KRB5_KEYUSAGE_AP_REP_ENCPART, 0, &reply->enc_part, &scratch))) goto clean_scratch; diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index 6edf6d760..48503d333 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -238,16 +238,17 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, do we need special processing here ? */ /* decrypt the ticket */ - if ((*auth_context)->keyblock) { /* User to User authentication */ - if ((retval = krb5_decrypt_tkt_part(context, (*auth_context)->keyblock, + if ((*auth_context)->key) { /* User to User authentication */ + if ((retval = krb5_decrypt_tkt_part(context, + &(*auth_context)->key->keyblock, req->ticket))) goto cleanup; if (check_valid_flag) { - decrypt_key = *((*auth_context)->keyblock); - free((*auth_context)->keyblock); - } else - krb5_free_keyblock(context, (*auth_context)->keyblock); - (*auth_context)->keyblock = NULL; + decrypt_key = (*auth_context)->key->keyblock; + (*auth_context)->key->keyblock.contents = NULL; + } + krb5_k_free_key(context, (*auth_context)->key); + (*auth_context)->key = NULL; } else { if ((retval = krb5_rd_req_decrypt_tkt_part(context, req, server, keytab, @@ -487,14 +488,14 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, (*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number; if ((*auth_context)->authentp->subkey) { - if ((retval = krb5_copy_keyblock(context, - (*auth_context)->authentp->subkey, - &((*auth_context)->recv_subkey)))) + if ((retval = krb5_k_create_key(context, + (*auth_context)->authentp->subkey, + &((*auth_context)->recv_subkey)))) goto cleanup; - retval = krb5_copy_keyblock(context, (*auth_context)->authentp->subkey, - &((*auth_context)->send_subkey)); + retval = krb5_k_create_key(context, (*auth_context)->authentp->subkey, + &((*auth_context)->send_subkey)); if (retval) { - krb5_free_keyblock(context, (*auth_context)->recv_subkey); + krb5_k_free_key(context, (*auth_context)->recv_subkey); (*auth_context)->recv_subkey = NULL; goto cleanup; } @@ -503,8 +504,8 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, (*auth_context)->send_subkey = 0; } - if ((retval = krb5_copy_keyblock(context, req->ticket->enc_part2->session, - &((*auth_context)->keyblock)))) + if ((retval = krb5_k_create_key(context, req->ticket->enc_part2->session, + &((*auth_context)->key)))) goto cleanup; debug_log_authz_data("ticket", req->ticket->enc_part2->authorization_data); @@ -527,7 +528,8 @@ krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, *ap_req_options = req->ap_options & AP_OPTS_WIRE_MASK; if (rfc4537_etypes_len != 0) *ap_req_options |= AP_OPTS_ETYPE_NEGOTIATION; - if ((*auth_context)->negotiated_etype != (*auth_context)->keyblock->enctype) + if ((*auth_context)->negotiated_etype != + krb5_k_key_enctype(context, (*auth_context)->key)) *ap_req_options |= AP_OPTS_USE_SUBKEY; } diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c index 989c22242..68c13317c 100644 --- a/src/lib/krb5/krb/rd_safe.c +++ b/src/lib/krb5/krb/rd_safe.c @@ -46,7 +46,7 @@ */ static krb5_error_code krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, - const krb5_keyblock *keyblock, + krb5_key key, const krb5_address *recv_addr, const krb5_address *sender_addr, krb5_replay_data *replaydata, krb5_data *outbuf) @@ -124,7 +124,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, if (retval) goto cleanup; - retval = krb5_c_verify_checksum(context, keyblock, + retval = krb5_k_verify_checksum(context, key, KRB5_KEYUSAGE_KRB_SAFE_CKSUM, scratch, his_cksum, &valid); @@ -136,7 +136,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, * Checksum over only the KRB-SAFE-BODY, like RFC 1510 says, in * case someone actually implements it correctly. */ - retval = krb5_c_verify_checksum(context, keyblock, + retval = krb5_k_verify_checksum(context, key, KRB5_KEYUSAGE_KRB_SAFE_CKSUM, &safe_body, his_cksum, &valid); if (!valid) { @@ -164,7 +164,7 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, krb5_replay_data *outdata) { krb5_error_code retval; - krb5_keyblock * keyblock; + krb5_key key; krb5_replay_data replaydata; if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) || @@ -180,9 +180,9 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, if (!auth_context->remote_addr) return KRB5_REMOTE_ADDR_REQUIRED; - /* Get keyblock */ - if ((keyblock = auth_context->recv_subkey) == NULL) - keyblock = auth_context->keyblock; + /* Get key */ + if ((key = auth_context->recv_subkey) == NULL) + key = auth_context->key; { krb5_address * premote_fulladdr; @@ -220,7 +220,7 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, } memset(&replaydata, 0, sizeof(replaydata)); - if ((retval = krb5_rd_safe_basic(context, inbuf, keyblock, + if ((retval = krb5_rd_safe_basic(context, inbuf, key, plocal_fulladdr, premote_fulladdr, &replaydata, outbuf))) { CLEANUP_DONE(); diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c index 487455b9d..65b7e2729 100644 --- a/src/lib/krb5/krb/ser_actx.c +++ b/src/lib/krb5/krb/ser_actx.c @@ -75,6 +75,7 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) krb5_error_code kret; krb5_auth_context auth_context; size_t required; + krb5_enctype enctype; /* * krb5_auth_context requires at minimum: @@ -92,9 +93,9 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) kret = 0; /* Calculate size required by i_vector - ptooey */ - if (auth_context->i_vector && auth_context->keyblock) { - kret = krb5_c_block_size(kcontext, auth_context->keyblock->enctype, - &required); + if (auth_context->i_vector && auth_context->key) { + enctype = krb5_k_key_enctype(kcontext, auth_context->key); + kret = krb5_c_block_size(kcontext, enctype, &required); } else { required = 0; } @@ -141,11 +142,11 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) required += sizeof(krb5_int32); } - /* Calculate size required by keyblock, if appropriate */ - if (!kret && auth_context->keyblock) { + /* Calculate size required by key, if appropriate */ + if (!kret && auth_context->key) { kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) auth_context->keyblock, + KV5M_KEYBLOCK, (krb5_pointer) + &auth_context->key->keyblock, &required); if (!kret) required += sizeof(krb5_int32); @@ -154,8 +155,8 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) /* Calculate size required by send_subkey, if appropriate */ if (!kret && auth_context->send_subkey) { kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) auth_context->send_subkey, + KV5M_KEYBLOCK, (krb5_pointer) + &auth_context->send_subkey->keyblock, &required); if (!kret) required += sizeof(krb5_int32); @@ -164,8 +165,8 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) /* Calculate size required by recv_subkey, if appropriate */ if (!kret && auth_context->recv_subkey) { kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) auth_context->recv_subkey, + KV5M_KEYBLOCK, (krb5_pointer) + &auth_context->recv_subkey->keyblock, &required); if (!kret) required += sizeof(krb5_int32); @@ -197,6 +198,7 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe size_t remain; size_t obuf; krb5_int32 obuf32; + krb5_enctype enctype; required = 0; bp = *buffer; @@ -224,9 +226,8 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe /* Now figure out the number of bytes for i_vector and write it */ if (auth_context->i_vector) { - kret = krb5_c_block_size(kcontext, - auth_context->keyblock->enctype, - &obuf); + enctype = krb5_k_key_enctype(kcontext, auth_context->key); + kret = krb5_c_block_size(kcontext, enctype, &obuf); } else { obuf = 0; } @@ -289,12 +290,12 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe } /* Now handle keyblock, if appropriate */ - if (!kret && auth_context->keyblock) { + if (!kret && auth_context->key) { (void) krb5_ser_pack_int32(TOKEN_KEYBLOCK, &bp, &remain); kret = krb5_externalize_opaque(kcontext, KV5M_KEYBLOCK, (krb5_pointer) - auth_context->keyblock, + &auth_context->key->keyblock, &bp, &remain); } @@ -304,8 +305,8 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe (void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain); kret = krb5_externalize_opaque(kcontext, KV5M_KEYBLOCK, - (krb5_pointer) - auth_context->send_subkey, + (krb5_pointer) &auth_context-> + send_subkey->keyblock, &bp, &remain); } @@ -315,8 +316,8 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe (void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain); kret = krb5_externalize_opaque(kcontext, KV5M_KEYBLOCK, - (krb5_pointer) - auth_context->recv_subkey, + (krb5_pointer) &auth_context-> + recv_subkey->keyblock, &bp, &remain); } @@ -345,6 +346,22 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe return(kret); } +/* Internalize a keyblock and convert it to a key. */ +static krb5_error_code +intern_key(krb5_context ctx, krb5_key *key, krb5_octet **bp, size_t *sp) +{ + krb5_keyblock *keyblock; + krb5_error_code ret; + + ret = krb5_internalize_opaque(ctx, KV5M_KEYBLOCK, + (krb5_pointer *) &keyblock, bp, sp); + if (ret != 0) + return ret; + ret = krb5_k_create_key(ctx, keyblock, key); + krb5_free_keyblock(ctx, keyblock); + return ret; +} + /* * krb5_auth_context_internalize() - Internalize the krb5_auth_context. */ @@ -464,37 +481,29 @@ krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_oc /* This is the keyblock */ if (!kret && (tag == TOKEN_KEYBLOCK)) { - if (!(kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) - &auth_context->keyblock, - &bp, - &remain))) + if (!(kret = intern_key(kcontext, + &auth_context->key, + &bp, + &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the send_subkey */ if (!kret && (tag == TOKEN_LSKBLOCK)) { - if (!(kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) - &auth_context-> - send_subkey, - &bp, - &remain))) + if (!(kret = intern_key(kcontext, + &auth_context->send_subkey, + &bp, + &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the recv_subkey */ if (!kret) { if (tag == TOKEN_RSKBLOCK) { - kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) - &auth_context-> - recv_subkey, - &bp, - &remain); + kret = intern_key(kcontext, + &auth_context->recv_subkey, + &bp, + &remain); } else { /* diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c index bb66568db..5575687dd 100644 --- a/src/lib/krb5/os/accessor.c +++ b/src/lib/krb5/os/accessor.c @@ -52,7 +52,7 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version) krb5int_access internals_temp; #endif S (free_addrlist, krb5int_free_addrlist), - S (krb5_hmac, krb5_hmac), + S (krb5_hmac, krb5int_hmac_keyblock), S (krb5_auth_con_get_subkey_enctype, krb5_auth_con_get_subkey_enctype), S (md5_hash_provider, &krb5int_hash_md5), S (arcfour_enc_provider, &krb5int_enc_arcfour), -- 2.26.2