From: Greg Hudson Date: Mon, 5 Oct 2009 18:30:00 +0000 (+0000) Subject: Respecify most crypto internals in terms of krb5_key. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07634e9d36eccf5ea97627f5e5e425adb7de3015;p=thirdparty%2Fkrb5.git Respecify most crypto internals in terms of krb5_key. Implement krb5_k_encrypt/decrypt/etc. with krb5_c versions as wrapers. OpenSSL back end not yet updated since it is undergoing work on trunk. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/enc-perf@22845 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 62d33fc5d1..f30ac9b5e2 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -648,12 +648,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); @@ -666,13 +666,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); @@ -691,27 +691,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, @@ -729,7 +729,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, @@ -737,7 +737,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, @@ -754,10 +754,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, @@ -2465,10 +2476,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/lib/crypto/builtin/aes/aes_s2k.c b/src/lib/crypto/builtin/aes/aes_s2k.c index 36045edc0d..76d73c6357 100644 --- a/src/lib/crypto/builtin/aes/aes_s2k.c +++ b/src/lib/crypto/builtin/aes/aes_s2k.c @@ -44,6 +44,7 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc, unsigned long iter_count; krb5_data out; static const krb5_data usage = { KV5M_DATA, 8, "kerberos" }; + krb5_key tempkey = NULL; krb5_error_code err; if (params) { @@ -66,25 +67,25 @@ krb5int_aes_string_to_key(const struct krb5_enc_provider *enc, if (iter_count >= MAX_ITERATION_COUNT) return KRB5_ERR_BAD_S2K_PARAMS; - /* - * Dense key space, no parity bits or anything, so take a shortcut - * and use the key contents buffer for the generated bytes. - */ + /* Use the output keyblock contents for temporary space. */ out.data = (char *) key->contents; out.length = key->length; if (out.length != 16 && out.length != 32) return KRB5_CRYPTO_INTERNAL; err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt); - if (err) { - memset(out.data, 0, out.length); - return err; - } + if (err) + goto cleanup; - err = krb5_derive_key (enc, key, key, &usage); - if (err) { - memset(out.data, 0, out.length); - return err; - } - return 0; + err = krb5_k_create_key (NULL, key, &tempkey); + if (err) + goto cleanup; + + err = krb5_derive_keyblock (enc, tempkey, key, &usage); + +cleanup: + if (err) + memset (out.data, 0, out.length); + krb5_k_free_key (NULL, tempkey); + return err; } diff --git a/src/lib/crypto/builtin/arcfour/arcfour.c b/src/lib/crypto/builtin/arcfour/arcfour.c index e5cdfdc8c2..150a7aa067 100644 --- a/src/lib/crypto/builtin/arcfour/arcfour.c +++ b/src/lib/crypto/builtin/arcfour/arcfour.c @@ -64,11 +64,12 @@ case 7: /* tgs-req authenticator */ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3, salt, plaintext, checksum, ciphertext, confounder; krb5_keyusage ms_usage; size_t keylength, keybytes, blocksize, hashsize; @@ -83,7 +84,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, d1.data=malloc(d1.length); if (d1.data == NULL) return (ENOMEM); - k1 = *key; + k1 = key->keyblock; k1.length=d1.length; k1.contents= (void *) d1.data; @@ -93,7 +94,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, free(d1.data); return (ENOMEM); } - k2 = *key; + k2 = key->keyblock; k2.length=d2.length; k2.contents=(void *) d2.data; @@ -104,7 +105,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, free(d2.data); return (ENOMEM); } - k3 = *key; + k3 = key->keyblock; k3.length=d3.length; k3.contents= (void *) d3.data; @@ -140,7 +141,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, /* begin the encryption, computer K1 */ ms_usage=krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data+10); } else { @@ -151,7 +152,7 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype==ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype==ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents+7, 0xab, 9); ret=krb5_c_random_make_octets(/* XXX */ 0, &confounder); @@ -159,11 +160,19 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, if (ret) goto cleanup; - krb5_hmac(hash, &k2, 1, &plaintext, &checksum); + ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &checksum); + if (ret) + goto cleanup; + + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); + if (ret) + goto cleanup; - krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret) + goto cleanup; - ret=(*(enc->encrypt))(&k3, ivec, &plaintext, &ciphertext); + ret=(*(enc->encrypt))(k3key, ivec, &plaintext, &ciphertext); cleanup: memset(d1.data, 0, d1.length); @@ -184,11 +193,12 @@ krb5_arcfour_encrypt(const struct krb5_enc_provider *enc, krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_keyblock k1,k2,k3; + krb5_key k3key; krb5_data d1,d2,d3,salt,ciphertext,plaintext,checksum; krb5_keyusage ms_usage; size_t keybytes, keylength, hashsize, blocksize; @@ -203,7 +213,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, d1.data=malloc(d1.length); if (d1.data == NULL) return (ENOMEM); - k1 = *key; + k1 = key->keyblock; k1.length=d1.length; k1.contents= (void *) d1.data; @@ -213,7 +223,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, free(d1.data); return (ENOMEM); } - k2 = *key; + k2 = key->keyblock; k2.length=d2.length; k2.contents= (void *) d2.data; @@ -224,7 +234,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, free(d2.data); return (ENOMEM); } - k3 = *key; + k3 = key->keyblock; k3.length=d3.length; k3.contents= (void *) d3.data; @@ -257,7 +267,7 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, /* We may have to try two ms_usage values; see below. */ do { /* compute the salt */ - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data + 10); } else { @@ -270,18 +280,22 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xab, 9); - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); if (ret) goto cleanup; - ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret) + goto cleanup; + ret = (*(enc->decrypt))(k3key, ivec, &ciphertext, &plaintext); + krb5_k_free_key(NULL, k3key); if (ret) goto cleanup; - ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1); + ret = krb5int_hmac_keyblock(hash, &k2, 1, &plaintext, &d1); if (ret) goto cleanup; diff --git a/src/lib/crypto/builtin/arcfour/arcfour.h b/src/lib/crypto/builtin/arcfour/arcfour.h index e8ff203ca1..1a2876437d 100644 --- a/src/lib/crypto/builtin/arcfour/arcfour.h +++ b/src/lib/crypto/builtin/arcfour/arcfour.h @@ -10,7 +10,7 @@ krb5_arcfour_encrypt_length(const struct krb5_enc_provider *, extern krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *, const struct krb5_hash_provider *, - const krb5_keyblock *, + krb5_key, krb5_keyusage, const krb5_data *, const krb5_data *, @@ -19,7 +19,7 @@ krb5_error_code krb5_arcfour_encrypt(const struct krb5_enc_provider *, extern krb5_error_code krb5_arcfour_decrypt(const struct krb5_enc_provider *, const struct krb5_hash_provider *, - const krb5_keyblock *, + krb5_key, krb5_keyusage, const krb5_data *, const krb5_data *, diff --git a/src/lib/crypto/builtin/arcfour/arcfour_aead.c b/src/lib/crypto/builtin/arcfour/arcfour_aead.c index cff7d66d65..4896afaaf4 100644 --- a/src/lib/crypto/builtin/arcfour/arcfour_aead.c +++ b/src/lib/crypto/builtin/arcfour/arcfour_aead.c @@ -82,7 +82,7 @@ static krb5_error_code krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -91,6 +91,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3; krb5_data checksum, confounder, header_data; krb5_keyusage ms_usage; @@ -126,15 +127,15 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, data[i].data.length = 0; } - ret = alloc_derived_key(enc, &k1, &d1, key); + ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k2, &d2, key); + ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k3, &d3, key); + ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock); if (ret != 0) goto cleanup; @@ -144,7 +145,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, ms_usage = krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, salt.data + 10); } else { @@ -157,7 +158,7 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xAB, 9); header->data.length = hash->hashsize + CONFOUNDERLENGTH; @@ -176,15 +177,19 @@ krb5int_arcfour_encrypt_iov(const struct krb5_aead_provider *aead, header->data.length -= hash->hashsize; header->data.data += hash->hashsize; - ret = krb5int_hmac_iov(hash, &k2, data, num_data, &checksum); + ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &checksum); if (ret != 0) goto cleanup; - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); if (ret != 0) goto cleanup; - ret = enc->encrypt_iov(&k3, ivec, data, num_data); + ret = krb5_k_create_key(NULL, &k3, &k3key); + if (ret != 0) + goto cleanup; + + ret = enc->encrypt_iov(k3key, ivec, data, num_data); if (ret != 0) goto cleanup; @@ -204,6 +209,7 @@ cleanup: free(d3.data); } + krb5_k_free_key(NULL, k3key); return ret; } @@ -211,7 +217,7 @@ static krb5_error_code krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -220,6 +226,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock k1, k2, k3; + krb5_key k3key = NULL; krb5_data d1, d2, d3; krb5_data checksum, header_data; krb5_keyusage ms_usage; @@ -240,15 +247,15 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, if (trailer != NULL && trailer->data.length != 0) return KRB5_BAD_MSIZE; - ret = alloc_derived_key(enc, &k1, &d1, key); + ret = alloc_derived_key(enc, &k1, &d1, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k2, &d2, key); + ret = alloc_derived_key(enc, &k2, &d2, &key->keyblock); if (ret != 0) goto cleanup; - ret = alloc_derived_key(enc, &k3, &d3, key); + ret = alloc_derived_key(enc, &k3, &d3, &key->keyblock); if (ret != 0) goto cleanup; @@ -258,7 +265,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, ms_usage = krb5int_arcfour_translate_usage(usage); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { strncpy(salt.data, krb5int_arcfour_l40, salt.length); store_32_le(ms_usage, (unsigned char *)salt.data + 10); } else { @@ -271,7 +278,7 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, memcpy(k2.contents, k1.contents, k2.length); - if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(k1.contents + 7, 0xAB, 9); checksum.data = header->data.data; @@ -281,15 +288,19 @@ krb5int_arcfour_decrypt_iov(const struct krb5_aead_provider *aead, header->data.length -= hash->hashsize; header->data.data += hash->hashsize; - ret = krb5_hmac(hash, &k1, 1, &checksum, &d3); + ret = krb5int_hmac_keyblock(hash, &k1, 1, &checksum, &d3); + if (ret != 0) + goto cleanup; + + ret = krb5_k_create_key(NULL, &k3, &k3key); if (ret != 0) goto cleanup; - ret = enc->decrypt_iov(&k3, ivec, data, num_data); + ret = enc->decrypt_iov(k3key, ivec, data, num_data); if (ret != 0) goto cleanup; - ret = krb5int_hmac_iov(hash, &k2, data, num_data, &d1); + ret = krb5int_hmac_iov_keyblock(hash, &k2, data, num_data, &d1); if (ret != 0) goto cleanup; @@ -314,6 +325,7 @@ cleanup: free(d3.data); } + krb5_k_free_key(NULL, k3key); return ret; } diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c index c0e1606a00..6d92b81763 100644 --- a/src/lib/crypto/builtin/enc_provider/aes.c +++ b/src/lib/crypto/builtin/enc_provider/aes.c @@ -86,7 +86,7 @@ static void xorblock(char *out, const char *in) } krb5_error_code -krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { aes_ctx ctx; @@ -95,7 +95,8 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, /* CHECK_SIZES; */ - if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) + if (aes_enc_key(key->keyblock.contents, key->keyblock.length, + &ctx) != aes_good) abort(); if (ivec) @@ -140,7 +141,7 @@ krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, } krb5_error_code -krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { aes_ctx ctx; @@ -149,7 +150,8 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, CHECK_SIZES; - if (aes_dec_key(key->contents, key->length, &ctx) != aes_good) + if (aes_dec_key(key->keyblock.contents, key->keyblock.length, + &ctx) != aes_good) abort(); if (ivec) @@ -200,7 +202,7 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -krb5int_aes_encrypt_iov(const krb5_keyblock *key, +krb5int_aes_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -210,7 +212,8 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key, int nblocks = 0, blockno; size_t input_length, i; - if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) + if (aes_enc_key(key->keyblock.contents, key->keyblock.length, &ctx) + != aes_good) abort(); if (ivec != NULL) @@ -280,7 +283,7 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -krb5int_aes_decrypt_iov(const krb5_keyblock *key, +krb5int_aes_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -293,7 +296,8 @@ krb5int_aes_decrypt_iov(const krb5_keyblock *key, CHECK_SIZES; - if (aes_dec_key(key->contents, key->length, &ctx) != aes_good) + if (aes_dec_key(key->keyblock.contents, key->keyblock.length, + &ctx) != aes_good) abort(); if (ivec != NULL) diff --git a/src/lib/crypto/builtin/enc_provider/des.c b/src/lib/crypto/builtin/enc_provider/des.c index 433032dd31..d73a1d2901 100644 --- a/src/lib/crypto/builtin/enc_provider/des.c +++ b/src/lib/crypto/builtin/enc_provider/des.c @@ -32,14 +32,14 @@ static krb5_error_code -k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_docrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output, int enc) { mit_des_key_schedule schedule; - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); @@ -48,7 +48,7 @@ k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, if (input->length != output->length) return(KRB5_BAD_MSIZE); - switch (mit_des_key_sched(key->contents, schedule)) { + switch (mit_des_key_sched(key->keyblock.contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: @@ -71,30 +71,30 @@ k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { return(k5_des_docrypt(key, ivec, input, output, 1)); } static krb5_error_code -k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { return(k5_des_docrypt(key, ivec, input, output, 0)); } static krb5_error_code -k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, +k5_des_docrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, int enc) { mit_des_key_schedule schedule; size_t input_length = 0; unsigned int i; - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); for (i = 0; i < num_data; i++) { @@ -109,7 +109,7 @@ k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); - switch (mit_des_key_sched(key->contents, schedule)) { + switch (mit_des_key_sched(key->keyblock.contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: @@ -128,7 +128,7 @@ k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des_encrypt_iov(const krb5_keyblock *key, +k5_des_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -137,7 +137,7 @@ k5_des_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -k5_des_decrypt_iov(const krb5_keyblock *key, +k5_des_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) diff --git a/src/lib/crypto/builtin/enc_provider/des3.c b/src/lib/crypto/builtin/enc_provider/des3.c index 7dba292ae0..eae504b8c3 100644 --- a/src/lib/crypto/builtin/enc_provider/des3.c +++ b/src/lib/crypto/builtin/enc_provider/des3.c @@ -30,13 +30,13 @@ #include static krb5_error_code -validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, +validate_and_schedule(krb5_key key, const krb5_data *ivec, const krb5_data *input, const krb5_data *output, mit_des3_key_schedule *schedule) { - /* key->enctype was checked by the caller */ + /* key->keyblock.enctype was checked by the caller */ - if (key->length != 24) + if (key->keyblock.length != 24) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); @@ -45,7 +45,7 @@ validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, if (input->length != output->length) return(KRB5_BAD_MSIZE); - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents, *schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); @@ -56,7 +56,7 @@ validate_and_schedule(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, +validate_and_schedule_iov(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, mit_des3_key_schedule *schedule) { @@ -69,14 +69,14 @@ validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, input_length += iov->data.length; } - if (key->length != 24) + if (key->keyblock.length != 24) return(KRB5_BAD_KEYSIZE); if ((input_length%8) != 0) return(KRB5_BAD_MSIZE); if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents, *schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); @@ -87,7 +87,7 @@ validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des3_encrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { mit_des3_key_schedule schedule; @@ -109,7 +109,7 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, +k5_des3_decrypt(krb5_key key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { mit_des3_key_schedule schedule; @@ -131,7 +131,7 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } static krb5_error_code -k5_des3_encrypt_iov(const krb5_keyblock *key, +k5_des3_encrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) @@ -154,7 +154,7 @@ k5_des3_encrypt_iov(const krb5_keyblock *key, } static krb5_error_code -k5_des3_decrypt_iov(const krb5_keyblock *key, +k5_des3_decrypt_iov(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) diff --git a/src/lib/crypto/builtin/enc_provider/rc4.c b/src/lib/crypto/builtin/enc_provider/rc4.c index df2c914f88..47c131da4d 100644 --- a/src/lib/crypto/builtin/enc_provider/rc4.c +++ b/src/lib/crypto/builtin/enc_provider/rc4.c @@ -29,7 +29,7 @@ static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest, /* Interface layer to kerb5 crypto layer */ static krb5_error_code -k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *, +k5_arcfour_docrypt(krb5_key, const krb5_data *, const krb5_data *, krb5_data *); static const unsigned char arcfour_weakkey1[] = {0x00, 0x00, 0xfd}; @@ -113,14 +113,14 @@ k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key, /* The workhorse of the arcfour system, this impliments the cipher */ static krb5_error_code -k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, +k5_arcfour_docrypt(krb5_key key, const krb5_data *state, const krb5_data *input, krb5_data *output) { ArcfourContext *arcfour_ctx; ArcFourCipherState *cipher_state; int ret; - if (key->length != 16) + if (key->keyblock.length != 16) return(KRB5_BAD_KEYSIZE); if (state && (state->length != sizeof (ArcFourCipherState))) return(KRB5_BAD_MSIZE); @@ -131,7 +131,8 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, cipher_state = (ArcFourCipherState *) state->data; arcfour_ctx=&cipher_state->ctx; if (cipher_state->initialized == 0) { - if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) { + if ((ret=k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length))) { return ret; } cipher_state->initialized = 1; @@ -142,7 +143,8 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, arcfour_ctx=malloc(sizeof (ArcfourContext)); if (arcfour_ctx == NULL) return ENOMEM; - if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) { + if ((ret=k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length))) { free(arcfour_ctx); return (ret); } @@ -157,7 +159,7 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, /* In-place encryption */ static krb5_error_code -k5_arcfour_docrypt_iov(const krb5_keyblock *key, +k5_arcfour_docrypt_iov(krb5_key key, const krb5_data *state, krb5_crypto_iov *data, size_t num_data) @@ -167,7 +169,7 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, krb5_error_code ret; size_t i; - if (key->length != 16) + if (key->keyblock.length != 16) return KRB5_BAD_KEYSIZE; if (state != NULL && (state->length != sizeof(ArcFourCipherState))) return KRB5_BAD_MSIZE; @@ -176,7 +178,8 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, cipher_state = (ArcFourCipherState *)state->data; arcfour_ctx = &cipher_state->ctx; if (cipher_state->initialized == 0) { - ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length); + ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length); if (ret != 0) return ret; @@ -187,7 +190,8 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, if (arcfour_ctx == NULL) return ENOMEM; - ret = k5_arcfour_init(arcfour_ctx, key->contents, key->length); + ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents, + key->keyblock.length); if (ret != 0) { free(arcfour_ctx); return ret; diff --git a/src/lib/crypto/builtin/hmac.c b/src/lib/crypto/builtin/hmac.c index 3bff3cf957..91f6108626 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 biult-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 d897e9a718..9201e23b09 100644 --- a/src/lib/crypto/builtin/pbkdf2.c +++ b/src/lib/crypto/builtin/pbkdf2.c @@ -25,19 +25,36 @@ * * * Implementation of PBKDF2 from RFC 2898. - * Not currently used; likely to be used when we get around to AES support. */ #include #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/krb/aead.c b/src/lib/crypto/krb/aead.c index ac5e7e87c7..3b11da5dc2 100644 --- a/src/lib/crypto/krb/aead.c +++ b/src/lib/crypto/krb/aead.c @@ -93,7 +93,7 @@ make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider, krb5_error_code krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, @@ -107,7 +107,7 @@ krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type, if (cksum_type->keyed_etype) { e1 = find_enctype(cksum_type->keyed_etype); - e2 = find_enctype(key->enctype); + e2 = find_enctype(key->keyblock.enctype); if (e1 == NULL || e2 == NULL || e1->enc != e2->enc) { ret = KRB5_BAD_ENCTYPE; goto cleanup; @@ -338,7 +338,7 @@ krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -451,7 +451,7 @@ krb5_error_code krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { @@ -513,7 +513,7 @@ krb5_error_code krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { diff --git a/src/lib/crypto/krb/aead.h b/src/lib/crypto/krb/aead.h index 2c99eb868c..cc43875e25 100644 --- a/src/lib/crypto/krb/aead.h +++ b/src/lib/crypto/krb/aead.h @@ -36,7 +36,7 @@ krb5int_c_locate_iov(krb5_crypto_iov *data, krb5_error_code krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, @@ -87,7 +87,7 @@ krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -97,7 +97,7 @@ krb5_error_code krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output); @@ -105,7 +105,7 @@ krb5_error_code krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output); diff --git a/src/lib/crypto/krb/combine_keys.c b/src/lib/crypto/krb/combine_keys.c index 8c3ea1936e..acfb99bbdb 100644 --- a/src/lib/crypto/krb/combine_keys.c +++ b/src/lib/crypto/krb/combine_keys.c @@ -79,7 +79,8 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1, size_t keybytes, keylength; const struct krb5_enc_provider *enc; krb5_data input, randbits; - krb5_keyblock tkey; + krb5_keyblock tkeyblock; + krb5_key tkey = NULL; krb5_error_code ret; const struct krb5_keytypes *ktp; krb5_boolean myalloc = FALSE; @@ -152,10 +153,14 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1, randbits.length = keybytes; randbits.data = (char *) rnd; - tkey.length = keylength; - tkey.contents = output; + tkeyblock.length = keylength; + tkeyblock.contents = output; - ret = (*enc->make_key)(&randbits, &tkey); + ret = (*enc->make_key)(&randbits, &tkeyblock); + if (ret) + goto cleanup; + + ret = krb5_k_create_key(NULL, &tkeyblock, &tkey); if (ret) goto cleanup; @@ -185,7 +190,7 @@ krb5int_c_combine_keys(krb5_context context, krb5_keyblock *key1, myalloc = TRUE; } - ret = krb5_derive_key(enc, &tkey, outkey, &input); + ret = krb5_derive_keyblock(enc, tkey, outkey, &input); if (ret) { if (myalloc) { free(outkey->contents); @@ -200,6 +205,7 @@ cleanup: zapfree(rnd, keybytes); zapfree(combined, keybytes * 2); zapfree(output, keylength); + krb5_k_free_key(NULL, tkey); return ret; } @@ -215,6 +221,7 @@ dr(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey, unsigned char *inblockdata = NULL, *outblockdata = NULL; krb5_data inblock, outblock; krb5_error_code ret; + krb5_key key = NULL; blocksize = enc->block_size; keybytes = enc->keybytes; @@ -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 29b6ef75ca..36c3bf0ab8 100644 --- a/src/lib/crypto/krb/decrypt.c +++ b/src/lib/crypto/krb/decrypt.c @@ -29,13 +29,13 @@ #include "aead.h" krb5_error_code KRB5_CALLCONV -krb5_c_decrypt(krb5_context context, const krb5_keyblock *key, +krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_enc_data *input, krb5_data *output) { const struct krb5_keytypes *ktp; - ktp = find_enctype(key->enctype); + ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; @@ -53,3 +53,19 @@ krb5_c_decrypt(krb5_context context, const krb5_keyblock *key, return (*ktp->decrypt)(ktp->enc, ktp->hash, key, usage, ivec, &input->ciphertext, output); } + +krb5_error_code KRB5_CALLCONV +krb5_c_decrypt(krb5_context context, const krb5_keyblock *keyblock, + krb5_keyusage usage, const krb5_data *ivec, + const krb5_enc_data *input, krb5_data *output) +{ + krb5_key key; + krb5_error_code ret; + + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = krb5_k_decrypt(context, key, usage, ivec, input, output); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/decrypt_iov.c b/src/lib/crypto/krb/decrypt_iov.c index c2f2c0b61c..fcc9973776 100644 --- a/src/lib/crypto/krb/decrypt_iov.c +++ b/src/lib/crypto/krb/decrypt_iov.c @@ -29,8 +29,8 @@ #include "aead.h" krb5_error_code KRB5_CALLCONV -krb5_c_decrypt_iov(krb5_context context, - const krb5_keyblock *key, +krb5_k_decrypt_iov(krb5_context context, + krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, @@ -38,7 +38,7 @@ krb5_c_decrypt_iov(krb5_context context, { const struct krb5_keytypes *ktp; - ktp = find_enctype(key->enctype); + ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL || ktp->aead == NULL) return KRB5_BAD_ENCTYPE; @@ -53,3 +53,22 @@ krb5_c_decrypt_iov(krb5_context context, usage, cipher_state, data, num_data); } +krb5_error_code KRB5_CALLCONV +krb5_c_decrypt_iov(krb5_context context, + const krb5_keyblock *keyblock, + krb5_keyusage usage, + const krb5_data *cipher_state, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_key key; + krb5_error_code ret; + + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = krb5_k_decrypt_iov(context, key, usage, cipher_state, data, + num_data); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c index fb5622a735..31e7de90ef 100644 --- a/src/lib/crypto/krb/dk/checksum.c +++ b/src/lib/crypto/krb/dk/checksum.c @@ -33,19 +33,17 @@ krb5_error_code krb5_dk_make_checksum(const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *input, krb5_data *output) { const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; - size_t keylength; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; - unsigned char *kcdata; - krb5_keyblock kc; + krb5_key kc; - ktp = find_enctype(key->enctype); + ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; enc = ktp->enc; @@ -55,15 +53,6 @@ krb5_dk_make_checksum(const struct krb5_hash_provider *hash, * output->length will be tested in krb5_hmac. */ - /* Allocate and set to-be-derived keys. */ - keylength = enc->keylength; - kcdata = malloc(keylength); - if (kcdata == NULL) - return ENOMEM; - - kc.contents = kcdata; - kc.length = keylength; - /* Derive the key. */ datain.data = (char *) constantdata; @@ -75,37 +64,34 @@ krb5_dk_make_checksum(const struct krb5_hash_provider *hash, ret = krb5_derive_key(enc, key, &kc, &datain); if (ret) - goto cleanup; + return ret; /* hash the data */ datain = *input; - ret = krb5_hmac(hash, &kc, 1, &datain, output); + ret = krb5_hmac(hash, kc, 1, &datain, output); if (ret) memset(output->data, 0, output->length); -cleanup: - zapfree(kcdata, keylength); + krb5_k_free_key(NULL, kc); return ret; } krb5_error_code krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; - size_t keylength; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; - unsigned char *kcdata; - krb5_keyblock kc; + krb5_key kc; - ktp = find_enctype(key->enctype); + ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; enc = ktp->enc; @@ -115,16 +101,6 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, * output->length will be tested in krb5_hmac. */ - /* Allocate and set to-be-derived keys. */ - - keylength = enc->keylength; - kcdata = malloc(keylength); - if (kcdata == NULL) - return ENOMEM; - - kc.contents = kcdata; - kc.length = keylength; - /* Derive the key. */ datain.data = (char *) constantdata; @@ -136,17 +112,14 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, ret = krb5_derive_key(enc, key, &kc, &datain); if (ret) - goto cleanup; + return ret; /* Hash the data. */ - ret = krb5int_hmac_iov(hash, &kc, data, num_data, output); + ret = krb5int_hmac_iov(hash, kc, data, num_data, output); if (ret) memset(output->data, 0, output->length); -cleanup: - zapfree(kcdata, keylength); - - return(ret); + krb5_k_free_key(NULL, kc); + return ret; } - diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c index 8c8214c125..ce55663107 100644 --- a/src/lib/crypto/krb/dk/derive.c +++ b/src/lib/crypto/krb/dk/derive.c @@ -28,9 +28,9 @@ #include "dk.h" 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 +40,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 +104,37 @@ 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; + + *outkey = NULL; + + /* Set up 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; + + /* Convert the keyblock to a key. */ + ret = krb5_k_create_key(NULL, &keyblock, outkey); + +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 +145,7 @@ krb5_derive_random(const struct krb5_enc_provider *enc, blocksize = enc->block_size; keybytes = enc->keybytes; - if (inkey->length != enc->keylength || outrnd->length != keybytes) + if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) return KRB5_CRYPTO_INTERNAL; /* Allocate and set up buffers. */ diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h index 9ddeb408c8..6566ce8d5a 100644 --- a/src/lib/crypto/krb/dk/dk.h +++ b/src/lib/crypto/krb/dk/dk.h @@ -32,7 +32,7 @@ void krb5_dk_encrypt_length(const struct krb5_enc_provider *enc, krb5_error_code krb5_dk_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output); @@ -42,7 +42,7 @@ void krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc, krb5_error_code krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, @@ -50,13 +50,13 @@ krb5_error_code krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, krb5_error_code krb5_dk_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *arg_output); krb5_error_code krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, @@ -68,26 +68,31 @@ krb5_error_code krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, const krb5_data *params, krb5_keyblock *key); +krb5_error_code krb5_derive_keyblock(const struct krb5_enc_provider *enc, + krb5_key inkey, + krb5_keyblock *outkey, + const krb5_data *in_constant); + krb5_error_code krb5_derive_key(const struct krb5_enc_provider *enc, - const krb5_keyblock *inkey, - krb5_keyblock *outkey, + krb5_key inkey, + krb5_key *outkey, const krb5_data *in_constant); krb5_error_code krb5_dk_make_checksum(const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *input, krb5_data *output); krb5_error_code krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); krb5_error_code krb5_derive_random(const struct krb5_enc_provider *enc, - const krb5_keyblock *inkey, krb5_data *outrnd, + krb5_key inkey, krb5_data *outrnd, const krb5_data *in_constant); /* AEAD */ diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c index 13eb007cdb..5c9c1ad5c7 100644 --- a/src/lib/crypto/krb/dk/dk_aead.c +++ b/src/lib/crypto/krb/dk/dk_aead.c @@ -61,7 +61,7 @@ static krb5_error_code krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -71,7 +71,7 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; krb5_crypto_iov *header, *trailer, *padding; - krb5_keyblock ke, ki; + krb5_key ke = NULL, ki = NULL; size_t i; unsigned int blocksize = 0; unsigned int plainlen = 0; @@ -79,9 +79,6 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, unsigned int padsize = 0; unsigned char *cksum = NULL; - ke.contents = ki.contents = NULL; - ke.length = ki.length = 0; - /* E(Confounder | Plaintext | Pad) | Checksum */ ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, @@ -126,14 +123,6 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, padding->data.length = padsize; } - ke.length = enc->keylength; - ke.contents = k5alloc(ke.length, &ret); - if (ret != 0) - goto cleanup; - ki.length = enc->keylength; - ki.contents = k5alloc(ki.length, &ret); - if (ret != 0) - goto cleanup; cksum = k5alloc(hash->hashsize, &ret); if (ret != 0) goto cleanup; @@ -169,14 +158,14 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, d2.length = hash->hashsize; d2.data = (char *)cksum; - ret = krb5int_hmac_iov(hash, &ki, data, num_data, &d2); + ret = krb5int_hmac_iov(hash, ki, data, num_data, &d2); if (ret != 0) goto cleanup; /* Encrypt the plaintext (header | data | padding) */ assert(enc->encrypt_iov != NULL); - ret = (*enc->encrypt_iov)(&ke, ivec, data, num_data); /* updates ivec */ + ret = (*enc->encrypt_iov)(ke, ivec, data, num_data); /* updates ivec */ if (ret != 0) goto cleanup; @@ -187,8 +176,8 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, trailer->data.length = hmacsize; cleanup: - zapfree(ke.contents, ke.length); - zapfree(ki.contents, ki.length); + krb5_k_free_key(NULL, ke); + krb5_k_free_key(NULL, ki); free(cksum); return ret; } @@ -197,7 +186,7 @@ static krb5_error_code krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -207,7 +196,7 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, unsigned char constantdata[K5CLENGTH]; krb5_data d1; krb5_crypto_iov *header, *trailer; - krb5_keyblock ke, ki; + krb5_key ke = NULL, ki = NULL; size_t i; unsigned int blocksize = 0; /* enc block size, not confounder len */ unsigned int cipherlen = 0; @@ -220,9 +209,6 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, usage, ivec, data, num_data); } - ke.contents = ki.contents = NULL; - ke.length = ki.length = 0; - /* E(Confounder | Plaintext | Pad) | Checksum */ ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, @@ -262,14 +248,6 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, if (trailer == NULL || trailer->data.length != hmacsize) return KRB5_BAD_MSIZE; - ke.length = enc->keylength; - ke.contents = k5alloc(ke.length, &ret); - if (ret != 0) - goto cleanup; - ki.length = enc->keylength; - ki.contents = k5alloc(ki.length, &ret); - if (ret != 0) - goto cleanup; cksum = k5alloc(hash->hashsize, &ret); if (ret != 0) goto cleanup; @@ -296,7 +274,7 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, /* Decrypt the plaintext (header | data | padding). */ assert(enc->decrypt_iov != NULL); - ret = (*enc->decrypt_iov)(&ke, ivec, data, num_data); /* updates ivec */ + ret = (*enc->decrypt_iov)(ke, ivec, data, num_data); /* updates ivec */ if (ret != 0) goto cleanup; @@ -304,7 +282,7 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, d1.length = hash->hashsize; /* non-truncated length */ d1.data = (char *)cksum; - ret = krb5int_hmac_iov(hash, &ki, data, num_data, &d1); + ret = krb5int_hmac_iov(hash, ki, data, num_data, &d1); if (ret != 0) goto cleanup; @@ -315,10 +293,9 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, } cleanup: - zapfree(ke.contents, ke.length); - zapfree(ki.contents, ki.length); + krb5_k_free_key(NULL, ke); + krb5_k_free_key(NULL, ki); free(cksum); - return ret; } diff --git a/src/lib/crypto/krb/dk/dk_decrypt.c b/src/lib/crypto/krb/dk/dk_decrypt.c index 1c0358a2d3..abb7a39b06 100644 --- a/src/lib/crypto/krb/dk/dk_decrypt.c +++ b/src/lib/crypto/krb/dk/dk_decrypt.c @@ -32,7 +32,7 @@ static krb5_error_code krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, @@ -43,7 +43,7 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, krb5_error_code krb5_dk_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { @@ -54,7 +54,7 @@ krb5_dk_decrypt(const struct krb5_enc_provider *enc, krb5_error_code krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { @@ -65,22 +65,20 @@ krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc, static krb5_error_code krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output, size_t hmacsize, int ivec_mode) { krb5_error_code ret; - size_t hashsize, blocksize, keylength, enclen, plainlen; - unsigned char *plaindata = NULL, *kedata = NULL, *kidata = NULL; - unsigned char *cksum = NULL, *cn; - krb5_keyblock ke, ki; + size_t hashsize, blocksize, enclen, plainlen; + unsigned char *plaindata = NULL, *cksum = NULL, *cn; + krb5_key ke = NULL, ki = NULL; krb5_data d1, d2; unsigned char constantdata[K5CLENGTH]; hashsize = hash->hashsize; blocksize = enc->block_size; - keylength = enc->keylength; if (hmacsize == 0) hmacsize = hashsize; @@ -90,12 +88,6 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, enclen = input->length - hmacsize; /* Allocate and set up ciphertext and to-be-derived keys. */ - kedata = k5alloc(keylength, &ret); - if (ret != 0) - goto cleanup; - kidata = k5alloc(keylength, &ret); - if (ret != 0) - goto cleanup; plaindata = k5alloc(enclen, &ret); if (ret != 0) goto cleanup; @@ -103,11 +95,6 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, if (ret != 0) goto cleanup; - ke.contents = kedata; - ke.length = keylength; - ki.contents = kidata; - ki.length = keylength; - /* Derive the keys. */ d1.data = (char *) constantdata; @@ -135,7 +122,7 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, d2.length = enclen; d2.data = (char *) plaindata; - ret = (*enc->decrypt)(&ke, ivec, &d1, &d2); + ret = (*enc->decrypt)(ke, ivec, &d1, &d2); if (ret != 0) goto cleanup; @@ -155,7 +142,7 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, d1.length = hashsize; d1.data = (char *) cksum; - ret = krb5_hmac(hash, &ki, 1, &d2, &d1); + ret = krb5_hmac(hash, ki, 1, &d2, &d1); if (ret != 0) goto cleanup; @@ -183,8 +170,8 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, memcpy(ivec->data, cn, blocksize); cleanup: - zapfree(kedata, keylength); - zapfree(kidata, keylength); + krb5_k_free_key(NULL, ke); + krb5_k_free_key(NULL, ki); zapfree(plaindata, enclen); zapfree(cksum, hashsize); return ret; diff --git a/src/lib/crypto/krb/dk/dk_encrypt.c b/src/lib/crypto/krb/dk/dk_encrypt.c index b06079c636..bb045fa6b0 100644 --- a/src/lib/crypto/krb/dk/dk_encrypt.c +++ b/src/lib/crypto/krb/dk/dk_encrypt.c @@ -53,20 +53,19 @@ krb5_dk_encrypt_length(const struct krb5_enc_provider *enc, krb5_error_code krb5_dk_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { - size_t blocksize, keylength, plainlen, enclen; + size_t blocksize, plainlen, enclen; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; - unsigned char *plaintext = NULL, *kedata = NULL, *kidata = NULL; + unsigned char *plaintext = NULL; char *cn; - krb5_keyblock ke, ki; + krb5_key ke = NULL, ki = NULL; blocksize = enc->block_size; - keylength = enc->keylength; plainlen = krb5_roundup(blocksize + input->length, blocksize); krb5_dk_encrypt_length(enc, hash, input->length, &enclen); @@ -78,20 +77,9 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, /* Allocate and set up plaintext and to-be-derived keys. */ - kedata = k5alloc(keylength, &ret); - if (ret != 0) - goto cleanup; - kidata = k5alloc(keylength, &ret); - if (ret != 0) - goto cleanup; - plaintext = k5alloc(plainlen, &ret); - if (ret != 0) - goto cleanup; - - ke.contents = kedata; - ke.length = keylength; - ki.contents = kidata; - ki.length = keylength; + plaintext = malloc(plainlen); + if (plaintext == NULL) + return ENOMEM; /* Derive the keys. */ @@ -134,7 +122,7 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, d2.length = plainlen; d2.data = output->data; - ret = (*enc->encrypt)(&ke, ivec, &d1, &d2); + ret = (*enc->encrypt)(ke, ivec, &d1, &d2); if (ret != 0) goto cleanup; @@ -150,7 +138,7 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, output->length = enclen; - ret = krb5_hmac(hash, &ki, 1, &d1, &d2); + ret = krb5_hmac(hash, ki, 1, &d1, &d2); if (ret != 0) { memset(d2.data, 0, d2.length); goto cleanup; @@ -161,8 +149,8 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, memcpy(ivec->data, cn, blocksize); cleanup: - zapfree(kedata, keylength); - zapfree(kidata, keylength); + krb5_k_free_key(NULL, ke); + krb5_k_free_key(NULL, ki); zapfree(plaintext, plainlen); return ret; } @@ -186,7 +174,7 @@ krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc, static krb5_error_code trunc_hmac (const struct krb5_hash_provider *hash, - const krb5_keyblock *ki, unsigned int num, + krb5_key ki, unsigned int num, const krb5_data *input, const krb5_data *output) { size_t hashsize; @@ -211,23 +199,22 @@ trunc_hmac (const struct krb5_hash_provider *hash, krb5_error_code krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { - size_t blocksize, keybytes, keylength, plainlen, enclen; + size_t blocksize, keybytes, plainlen, enclen; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; - unsigned char *plaintext = NULL, *kedata = NULL, *kidata = NULL; + unsigned char *plaintext = NULL; char *cn; - krb5_keyblock ke, ki; + krb5_key ke = NULL, ki = NULL; /* allocate and set up plaintext and to-be-derived keys */ blocksize = enc->block_size; keybytes = enc->keybytes; - keylength = enc->keylength; plainlen = blocksize+input->length; krb5int_aes_encrypt_length(enc, hash, input->length, &enclen); @@ -237,20 +224,9 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, if (output->length < enclen) return KRB5_BAD_MSIZE; - kedata = k5alloc(keylength, &ret); - if (ret != 0) - goto cleanup; - kidata = k5alloc(keylength, &ret); - if (ret != 0) - goto cleanup; - plaintext = k5alloc(plainlen, &ret); - if (ret != 0) - goto cleanup; - - ke.contents = kedata; - ke.length = keylength; - ki.contents = kidata; - ki.length = keylength; + plaintext = malloc(plainlen); + if (plaintext == NULL) + return ENOMEM; /* Derive the keys. */ @@ -294,7 +270,7 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, d2.length = plainlen; d2.data = output->data; - ret = (*enc->encrypt)(&ke, ivec, &d1, &d2); + ret = (*enc->encrypt)(ke, ivec, &d1, &d2); if (ret != 0) goto cleanup; @@ -311,7 +287,7 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, if (d2.length != 96 / 8) abort(); - ret = trunc_hmac(hash, &ki, 1, &d1, &d2); + ret = trunc_hmac(hash, ki, 1, &d1, &d2); if (ret != 0) { memset(d2.data, 0, d2.length); goto cleanup; @@ -324,8 +300,8 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, memcpy(ivec->data, cn, blocksize); cleanup: - zapfree(kedata, keylength); - zapfree(kidata, keylength); + krb5_k_free_key(NULL, ke); + krb5_k_free_key(NULL, ki); zapfree(plaintext, plainlen); return ret; } diff --git a/src/lib/crypto/krb/dk/stringtokey.c b/src/lib/crypto/krb/dk/stringtokey.c index 3265657583..48b053ad9c 100644 --- a/src/lib/crypto/krb/dk/stringtokey.c +++ b/src/lib/crypto/krb/dk/stringtokey.c @@ -32,15 +32,16 @@ static const unsigned char kerberos[] = "kerberos"; krb5_error_code krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, const krb5_data *string, const krb5_data *salt, - const krb5_data *parms, krb5_keyblock *key) + const krb5_data *parms, krb5_keyblock *keyblock) { krb5_error_code ret; size_t keybytes, keylength, concatlen; unsigned char *concat = NULL, *foldstring = NULL, *foldkeydata = NULL; krb5_data indata; - krb5_keyblock foldkey; + krb5_keyblock foldkeyblock; + krb5_key foldkey = NULL; - /* key->length is checked by krb5_derive_key. */ + /* keyblock->length is checked by krb5_derive_key. */ keybytes = enc->keybytes; keylength = enc->keylength; @@ -67,10 +68,14 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, indata.length = keybytes; indata.data = (char *) foldstring; - foldkey.length = keylength; - foldkey.contents = foldkeydata; + foldkeyblock.length = keylength; + foldkeyblock.contents = foldkeydata; - ret = (*enc->make_key)(&indata, &foldkey); + ret = (*enc->make_key)(&indata, &foldkeyblock); + if (ret != 0) + goto cleanup; + + ret = krb5_k_create_key(NULL, &foldkeyblock, &foldkey); if (ret != 0) goto cleanup; @@ -79,13 +84,14 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, indata.length = kerberos_len; indata.data = (char *) kerberos; - ret = krb5_derive_key(enc, &foldkey, key, &indata); + ret = krb5_derive_keyblock(enc, foldkey, keyblock, &indata); if (ret != 0) - memset(key->contents, 0, key->length); + memset(keyblock->contents, 0, keyblock->length); cleanup: zapfree(concat, concatlen); zapfree(foldstring, keybytes); zapfree(foldkeydata, keylength); + krb5_k_free_key(NULL, foldkey); return ret; } diff --git a/src/lib/crypto/krb/encrypt.c b/src/lib/crypto/krb/encrypt.c index 741485a314..3c39838cf5 100644 --- a/src/lib/crypto/krb/encrypt.c +++ b/src/lib/crypto/krb/encrypt.c @@ -29,19 +29,19 @@ #include "aead.h" krb5_error_code KRB5_CALLCONV -krb5_c_encrypt(krb5_context context, const krb5_keyblock *key, +krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_enc_data *output) { const struct krb5_keytypes *ktp; - ktp = find_enctype(key->enctype); + ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; output->magic = KV5M_ENC_DATA; output->kvno = 0; - output->enctype = key->enctype; + output->enctype = key->keyblock.enctype; if (ktp->encrypt == NULL) { assert(ktp->aead != NULL); @@ -54,3 +54,19 @@ krb5_c_encrypt(krb5_context context, const krb5_keyblock *key, return (*ktp->encrypt)(ktp->enc, ktp->hash, key, usage, ivec, input, &output->ciphertext); } + +krb5_error_code KRB5_CALLCONV +krb5_c_encrypt(krb5_context context, const krb5_keyblock *keyblock, + krb5_keyusage usage, const krb5_data *ivec, + const krb5_data *input, krb5_enc_data *output) +{ + krb5_key key; + krb5_error_code ret; + + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = krb5_k_encrypt(context, key, usage, ivec, input, output); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/encrypt_iov.c b/src/lib/crypto/krb/encrypt_iov.c index 21242bca2c..b7b2f58145 100644 --- a/src/lib/crypto/krb/encrypt_iov.c +++ b/src/lib/crypto/krb/encrypt_iov.c @@ -28,8 +28,8 @@ #include "etypes.h" krb5_error_code KRB5_CALLCONV -krb5_c_encrypt_iov(krb5_context context, - const krb5_keyblock *key, +krb5_k_encrypt_iov(krb5_context context, + krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, @@ -37,7 +37,7 @@ krb5_c_encrypt_iov(krb5_context context, { const struct krb5_keytypes *ktp; - ktp = find_enctype(key->enctype); + ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL || ktp->aead == NULL) return KRB5_BAD_ENCTYPE; @@ -45,3 +45,22 @@ krb5_c_encrypt_iov(krb5_context context, key, usage, cipher_state, data, num_data); } +krb5_error_code KRB5_CALLCONV +krb5_c_encrypt_iov(krb5_context context, + const krb5_keyblock *keyblock, + krb5_keyusage usage, + const krb5_data *cipher_state, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_key key; + krb5_error_code ret; + + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = krb5_k_encrypt_iov(context, key, usage, cipher_state, data, + num_data); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/etypes.h b/src/lib/crypto/krb/etypes.h index 8d83b4200f..edaa00caea 100644 --- a/src/lib/crypto/krb/etypes.h +++ b/src/lib/crypto/krb/etypes.h @@ -33,7 +33,7 @@ typedef void (*krb5_encrypt_length_func)(const struct krb5_enc_provider *enc, typedef krb5_error_code (*krb5_crypt_func)(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, const krb5_data *input, @@ -48,7 +48,7 @@ typedef krb5_error_code (*krb5_str2key_func)(const struct typedef krb5_error_code (*krb5_prf_func)(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, const krb5_data *in, krb5_data *out); struct krb5_keytypes { diff --git a/src/lib/crypto/krb/keyhash_provider/descbc.c b/src/lib/crypto/krb/keyhash_provider/descbc.c index bf68e324ce..b08e30b7c6 100644 --- a/src/lib/crypto/krb/keyhash_provider/descbc.c +++ b/src/lib/crypto/krb/keyhash_provider/descbc.c @@ -29,12 +29,12 @@ #include "keyhash_provider.h" static krb5_error_code -k5_descbc_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, +k5_descbc_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { mit_des_key_schedule schedule; - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); @@ -43,7 +43,7 @@ k5_descbc_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i if (output->length != 8) return(KRB5_CRYPTO_INTERNAL); - switch (mit_des_key_sched(key->contents, schedule)) { + switch (mit_des_key_sched(key->keyblock.contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: diff --git a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c index 34ce67169e..61c6d8c21d 100644 --- a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c +++ b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c @@ -36,24 +36,23 @@ #include "../aead.h" static krb5_error_code -k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage, +k5_hmac_md5_hash (krb5_key key, krb5_keyusage usage, const krb5_data *iv, const krb5_data *input, krb5_data *output) { krb5_keyusage ms_usage; krb5_error_code ret; - krb5_keyblock ks; + krb5_keyblock keyblock; + krb5_key ks = NULL; krb5_data ds, ks_constant, md5tmp; krb5_MD5_CTX ctx; char t[4]; - ds.length = key->length; - ks.length = key->length; + ds.length = key->keyblock.length; ds.data = malloc(ds.length); if (ds.data == NULL) return ENOMEM; - ks.contents = (void *) ds.data; ks_constant.data = "signaturekey"; ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/ @@ -63,6 +62,12 @@ k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage, if (ret) goto cleanup; + keyblock.length = key->keyblock.length; + keyblock.contents = (void *) ds.data; + ret = krb5_k_create_key(NULL, &keyblock, &ks); + if (ret) + goto cleanup; + krb5_MD5Init (&ctx); ms_usage = krb5int_arcfour_translate_usage (usage); store_32_le(ms_usage, t); @@ -72,36 +77,36 @@ k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage, krb5_MD5Final(&ctx); md5tmp.data = (void *) ctx.digest; md5tmp.length = 16; - ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp, + + ret = krb5_hmac ( &krb5int_hash_md5, ks, 1, &md5tmp, output); cleanup: memset(&ctx, 0, sizeof(ctx)); - memset (ks.contents, 0, ks.length); - free (ks.contents); + zapfree(ds.data, ds.length); + krb5_k_free_key(NULL, ks); return ret; } static krb5_error_code -k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage, +k5_hmac_md5_hash_iov (krb5_key key, krb5_keyusage usage, const krb5_data *iv, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_keyusage ms_usage; krb5_error_code ret; - krb5_keyblock ks; + krb5_keyblock keyblock; + krb5_key ks = NULL; krb5_data ds, ks_constant, md5tmp; krb5_MD5_CTX ctx; char t[4]; size_t i; - ds.length = key->length; - ks.length = key->length; + ds.length = key->keyblock.length; ds.data = malloc(ds.length); if (ds.data == NULL) return ENOMEM; - ks.contents = (void *) ds.data; ks_constant.data = "signaturekey"; ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/ @@ -111,6 +116,12 @@ k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage, if (ret) goto cleanup; + keyblock.length = key->keyblock.length; + keyblock.contents = (void *) ds.data; + ret = krb5_k_create_key(NULL, &keyblock, &ks); + if (ret) + goto cleanup; + krb5_MD5Init (&ctx); ms_usage = krb5int_arcfour_translate_usage (usage); store_32_le(ms_usage, t); @@ -125,13 +136,13 @@ k5_hmac_md5_hash_iov (const krb5_keyblock *key, krb5_keyusage usage, krb5_MD5Final(&ctx); md5tmp.data = (void *) ctx.digest; md5tmp.length = 16; - ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp, + ret = krb5_hmac ( &krb5int_hash_md5, ks, 1, &md5tmp, output); cleanup: memset(&ctx, 0, sizeof(ctx)); - memset (ks.contents, 0, ks.length); - free (ks.contents); + zapfree(keyblock.contents, keyblock.length); + krb5_k_free_key(NULL, ks); return ret; } diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c index 49700a89d4..1514dccc67 100644 --- a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c +++ b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c @@ -39,7 +39,7 @@ extern struct krb5_enc_provider krb5int_enc_des; static krb5_error_code -k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, +k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_error_code ret; @@ -77,7 +77,7 @@ k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i } static krb5_error_code -k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage, +k5_md4des_verify(krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, const krb5_data *hash, krb5_boolean *valid) @@ -89,7 +89,7 @@ k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage, struct krb5_enc_provider *enc = &krb5int_enc_des; krb5_data output, iv; - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) { #ifdef KRB5_MD4DES_BETA5_COMPAT @@ -104,11 +104,11 @@ k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage, } if (compathash) { - iv.data = malloc(key->length); + iv.data = malloc(key->keyblock.length); if (!iv.data) return ENOMEM; - iv.length = key->length; - if (key->contents) - memcpy(iv.data, key->contents, key->length); + iv.length = key->keyblock.length; + if (key->keyblock.contents) + memcpy(iv.data, key->keyblock.contents, key->keyblock.length); } /* decrypt it */ diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c index 24d6317060..e7a84e2a85 100644 --- a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c +++ b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c @@ -39,7 +39,7 @@ extern struct krb5_enc_provider krb5int_enc_des; static krb5_error_code -k5_md5des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, +k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_error_code ret; @@ -78,7 +78,7 @@ k5_md5des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *i } static krb5_error_code -k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, +k5_md5des_verify(krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, const krb5_data *hash, krb5_boolean *valid) { @@ -89,7 +89,7 @@ k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data struct krb5_enc_provider *enc = &krb5int_enc_des; krb5_data output, iv; - if (key->length != 8) + if (key->keyblock.length != 8) return(KRB5_BAD_KEYSIZE); if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) { @@ -104,11 +104,11 @@ k5_md5des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data } if (compathash) { - iv.data = malloc(key->length); + iv.data = malloc(key->keyblock.length); if (!iv.data) return ENOMEM; - iv.length = key->length; - if (key->contents) - memcpy(iv.data, key->contents, key->length); + iv.length = key->keyblock.length; + if (key->keyblock.contents) + memcpy(iv.data, key->keyblock.contents, key->keyblock.length); } /* decrypt it */ diff --git a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c index d05b97f00d..589c3475ed 100644 --- a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c +++ b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c @@ -33,7 +33,7 @@ #include "hash_provider.h" static krb5_error_code -k5_md5_hmac_hash (const krb5_keyblock *key, krb5_keyusage usage, +k5_md5_hmac_hash (krb5_key key, krb5_keyusage usage, const krb5_data *iv, const krb5_data *input, krb5_data *output) { diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c index 29f1ebb2a8..c883937c5f 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; @@ -114,3 +114,21 @@ cleanup: return ret; } + +krb5_error_code KRB5_CALLCONV +krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype, + const krb5_keyblock *keyblock, krb5_keyusage usage, + const krb5_data *input, krb5_checksum *cksum) +{ + krb5_key key = NULL; + krb5_error_code ret; + + if (keyblock != NULL) { + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + } + ret = krb5_k_make_checksum(context, cksumtype, key, usage, input, cksum); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c index a16b849c05..32c9a4cb4f 100644 --- a/src/lib/crypto/krb/make_checksum_iov.c +++ b/src/lib/crypto/krb/make_checksum_iov.c @@ -29,9 +29,9 @@ #include "aead.h" krb5_error_code KRB5_CALLCONV -krb5_c_make_checksum_iov(krb5_context context, +krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data) @@ -81,3 +81,23 @@ krb5_c_make_checksum_iov(krb5_context context, return(ret); } + +krb5_error_code KRB5_CALLCONV +krb5_c_make_checksum_iov(krb5_context context, + krb5_cksumtype cksumtype, + const krb5_keyblock *keyblock, + krb5_keyusage usage, + krb5_crypto_iov *data, + size_t num_data) +{ + krb5_key key; + krb5_error_code ret; + + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = krb5_k_make_checksum_iov(context, cksumtype, key, usage, + data, num_data); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/old/old.h b/src/lib/crypto/krb/old/old.h index 94ee6421e8..6cfb0c97ad 100644 --- a/src/lib/crypto/krb/old/old.h +++ b/src/lib/crypto/krb/old/old.h @@ -34,14 +34,14 @@ void krb5_old_encrypt_length krb5_error_code krb5_old_encrypt (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output); krb5_error_code krb5_old_decrypt (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *arg_output); diff --git a/src/lib/crypto/krb/old/old_decrypt.c b/src/lib/crypto/krb/old/old_decrypt.c index cfbbd7272a..dd9ad19cb3 100644 --- a/src/lib/crypto/krb/old/old_decrypt.c +++ b/src/lib/crypto/krb/old/old_decrypt.c @@ -30,7 +30,7 @@ krb5_error_code krb5_old_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, @@ -87,9 +87,9 @@ krb5_old_decrypt(const struct krb5_enc_provider *enc, cn = NULL; /* XXX this is gross, but I don't have much choice */ - if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { - crcivec.length = key->length; - crcivec.data = (char *) key->contents; + if ((key->keyblock.enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { + crcivec.length = key->keyblock.length; + crcivec.data = (char *) key->keyblock.contents; ivec = &crcivec; } diff --git a/src/lib/crypto/krb/old/old_encrypt.c b/src/lib/crypto/krb/old/old_encrypt.c index 98bd109e0e..1121dc935e 100644 --- a/src/lib/crypto/krb/old/old_encrypt.c +++ b/src/lib/crypto/krb/old/old_encrypt.c @@ -44,7 +44,7 @@ krb5_old_encrypt_length(const struct krb5_enc_provider *enc, krb5_error_code krb5_old_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, @@ -87,9 +87,9 @@ krb5_old_encrypt(const struct krb5_enc_provider *enc, /* encrypt it */ /* XXX this is gross, but I don't have much choice */ - if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { - crcivec.length = key->length; - crcivec.data = (char *) key->contents; + if ((key->keyblock.enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { + crcivec.length = key->keyblock.length; + crcivec.data = (char *) key->keyblock.contents; ivec = &crcivec; real_ivec = 0; } else diff --git a/src/lib/crypto/krb/prf.c b/src/lib/crypto/krb/prf.c index d2c633e757..12ec22b65b 100644 --- a/src/lib/crypto/krb/prf.c +++ b/src/lib/crypto/krb/prf.c @@ -50,15 +50,17 @@ krb5_c_prf_length(krb5_context context, krb5_enctype enctype, size_t *len) } krb5_error_code KRB5_CALLCONV -krb5_c_prf(krb5_context context, const krb5_keyblock *key, +krb5_c_prf(krb5_context context, const krb5_keyblock *keyblock, krb5_data *input, krb5_data *output) { const struct krb5_keytypes *ktp; + krb5_key key; + krb5_error_code ret; assert(input && output); assert(output->data); - ktp = find_enctype(key->enctype); + ktp = find_enctype(keyblock->enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; if (ktp->prf == NULL) @@ -67,5 +69,10 @@ krb5_c_prf(krb5_context context, const krb5_keyblock *key, output->magic = KV5M_DATA; if (ktp->prf_length != output->length) return KRB5_CRYPTO_INTERNAL; - return (*ktp->prf)(ktp->enc, ktp->hash, key, input, output); + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = (*ktp->prf)(ktp->enc, ktp->hash, key, input, output); + krb5_k_free_key(context, key); + return ret; } diff --git a/src/lib/crypto/krb/prf/des_prf.c b/src/lib/crypto/krb/prf/des_prf.c index 869f2e0bf6..dd9907bda4 100644 --- a/src/lib/crypto/krb/prf/des_prf.c +++ b/src/lib/crypto/krb/prf/des_prf.c @@ -35,8 +35,7 @@ krb5_error_code krb5int_des_prf (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, - const krb5_data *in, krb5_data *out) + krb5_key key, const krb5_data *in, krb5_data *out) { krb5_data tmp; krb5_error_code ret = 0; diff --git a/src/lib/crypto/krb/prf/dk_prf.c b/src/lib/crypto/krb/prf/dk_prf.c index cc3e2d9341..cc203875cb 100644 --- a/src/lib/crypto/krb/prf/dk_prf.c +++ b/src/lib/crypto/krb/prf/dk_prf.c @@ -35,12 +35,11 @@ krb5_error_code krb5int_dk_prf (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, - const krb5_data *in, krb5_data *out) + krb5_key key, const krb5_data *in, krb5_data *out) { krb5_data tmp; krb5_data prfconst; - krb5_keyblock *kp = NULL; + krb5_key kp = NULL; krb5_error_code ret = 0; prfconst.data = (char *) "prf"; @@ -51,14 +50,10 @@ krb5int_dk_prf (const struct krb5_enc_provider *enc, return ENOMEM; hash->hash(1, in, &tmp); tmp.length = (tmp.length/enc->block_size)*enc->block_size; /*truncate to block size*/ - ret = krb5int_c_init_keyblock(0, key->enctype, - key->length, &kp); - if (ret == 0) - ret = krb5_derive_key(enc, key, kp, &prfconst); + ret = krb5_derive_key(enc, key, &kp, &prfconst); if (ret == 0) - ret = enc->encrypt(kp, NULL, &tmp, out); - if (kp) - krb5int_c_free_keyblock(0, kp); + ret = enc->encrypt(kp, NULL, &tmp, out); + krb5_k_free_key(NULL, kp); free (tmp.data); return ret; } diff --git a/src/lib/crypto/krb/prf/prf_int.h b/src/lib/crypto/krb/prf/prf_int.h index 180ce027d9..97bbf049d0 100644 --- a/src/lib/crypto/krb/prf/prf_int.h +++ b/src/lib/crypto/krb/prf/prf_int.h @@ -32,19 +32,17 @@ krb5_error_code krb5int_arcfour_prf(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, - const krb5_data *in, krb5_data *out); + krb5_key key, const krb5_data *in, krb5_data *out); krb5_error_code krb5int_des_prf (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, - const krb5_data *in, krb5_data *out); + krb5_key key, const krb5_data *in, krb5_data *out); krb5_error_code krb5int_dk_prf(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, const krb5_data *in, krb5_data *out); + krb5_key key, const krb5_data *in, krb5_data *out); #endif /*PRF_INTERNAL_DEFS*/ diff --git a/src/lib/crypto/krb/prf/rc4_prf.c b/src/lib/crypto/krb/prf/rc4_prf.c index 2b1b73f914..3affaa5398 100644 --- a/src/lib/crypto/krb/prf/rc4_prf.c +++ b/src/lib/crypto/krb/prf/rc4_prf.c @@ -32,8 +32,7 @@ krb5_error_code krb5int_arcfour_prf(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, - const krb5_data *in, krb5_data *out) + krb5_key key, const krb5_data *in, krb5_data *out) { assert(out->length == 20); return krb5_hmac(&krb5int_hash_sha1, key, 1, in, out); diff --git a/src/lib/crypto/krb/raw/raw.h b/src/lib/crypto/krb/raw/raw.h index f4b7d5f0b7..84ae730238 100644 --- a/src/lib/crypto/krb/raw/raw.h +++ b/src/lib/crypto/krb/raw/raw.h @@ -34,14 +34,14 @@ void krb5_raw_encrypt_length krb5_error_code krb5_raw_encrypt (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output); krb5_error_code krb5_raw_decrypt (const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *arg_output); diff --git a/src/lib/crypto/krb/raw/raw_aead.c b/src/lib/crypto/krb/raw/raw_aead.c index f52fe000d1..68070d1daa 100644 --- a/src/lib/crypto/krb/raw/raw_aead.c +++ b/src/lib/crypto/krb/raw/raw_aead.c @@ -54,7 +54,7 @@ static krb5_error_code krb5int_raw_encrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, @@ -104,7 +104,7 @@ static krb5_error_code krb5int_raw_decrypt_iov(const struct krb5_aead_provider *aead, const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, diff --git a/src/lib/crypto/krb/raw/raw_decrypt.c b/src/lib/crypto/krb/raw/raw_decrypt.c index 767da1f9fa..dd62806e4e 100644 --- a/src/lib/crypto/krb/raw/raw_decrypt.c +++ b/src/lib/crypto/krb/raw/raw_decrypt.c @@ -30,7 +30,7 @@ krb5_error_code krb5_raw_decrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { diff --git a/src/lib/crypto/krb/raw/raw_encrypt.c b/src/lib/crypto/krb/raw/raw_encrypt.c index 68b819c016..462239ee59 100644 --- a/src/lib/crypto/krb/raw/raw_encrypt.c +++ b/src/lib/crypto/krb/raw/raw_encrypt.c @@ -42,7 +42,7 @@ krb5_raw_encrypt_length(const struct krb5_enc_provider *enc, krb5_error_code krb5_raw_encrypt(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, + krb5_key key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { diff --git a/src/lib/crypto/krb/verify_checksum.c b/src/lib/crypto/krb/verify_checksum.c index ae15cc872a..1da822fbc2 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) { @@ -78,7 +78,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; @@ -88,3 +88,21 @@ krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key, free(computed.contents); return 0; } + +krb5_error_code KRB5_CALLCONV +krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *keyblock, + krb5_keyusage usage, const krb5_data *data, + const krb5_checksum *cksum, krb5_boolean *valid) +{ + krb5_key key = NULL; + krb5_error_code ret; + + if (keyblock != NULL) { + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + } + ret = krb5_k_verify_checksum(context, key, usage, data, cksum, valid); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c index 341c89684f..f322dc386c 100644 --- a/src/lib/crypto/krb/verify_checksum_iov.c +++ b/src/lib/crypto/krb/verify_checksum_iov.c @@ -29,9 +29,9 @@ #include "aead.h" krb5_error_code KRB5_CALLCONV -krb5_c_verify_checksum_iov(krb5_context context, +krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype checksum_type, - const krb5_keyblock *key, + krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, @@ -94,3 +94,24 @@ krb5_c_verify_checksum_iov(krb5_context context, free(computed.data); return 0; } + +krb5_error_code KRB5_CALLCONV +krb5_c_verify_checksum_iov(krb5_context context, + krb5_cksumtype checksum_type, + const krb5_keyblock *keyblock, + krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_boolean *valid) +{ + krb5_key key; + krb5_error_code ret; + + ret = krb5_k_create_key(context, keyblock, &key); + if (ret != 0) + return ret; + ret = krb5_k_verify_checksum_iov(context, checksum_type, key, usage, data, + num_data, valid); + krb5_k_free_key(context, key); + return ret; +} diff --git a/src/lib/crypto/krb/yarrow/ycipher.c b/src/lib/crypto/krb/yarrow/ycipher.c index 2af410440d..84cadd13fb 100644 --- a/src/lib/crypto/krb/yarrow/ycipher.c +++ b/src/lib/crypto/krb/yarrow/ycipher.c @@ -42,27 +42,28 @@ krb5int_yarrow_cipher_init const struct krb5_enc_provider *enc = &yarrow_enc_provider; krb5_error_code ret; krb5_data randombits; + krb5_keyblock keyblock; + keybytes = enc->keybytes; keylength = enc->keylength; assert (keybytes == CIPHER_KEY_SIZE); - if (ctx->key.contents) { - memset (ctx->key.contents, 0, ctx->key.length); - free (ctx->key.contents); - } - ctx->key.contents = (void *) malloc (keylength); - ctx->key.length = keylength; - if (ctx->key.contents == NULL) + krb5_k_free_key(NULL, ctx->key); + ctx->key = NULL; + keyblock.contents = malloc(keylength); + keyblock.length = keylength; + if (keyblock.contents == NULL) return (YARROW_NOMEM); randombits.data = (char *) key; randombits.length = keybytes; - ret = enc->make_key (&randombits, &ctx->key); - if (ret) { - memset (ctx->key.contents, 0, ctx->key.length); - free(ctx->key.contents); - ctx->key.contents = NULL; - return (YARROW_FAIL); - } - return (YARROW_OK); + ret = enc->make_key(&randombits, &keyblock); + if (ret != 0) + goto cleanup; + ret = krb5_k_create_key(NULL, &keyblock, &ctx->key); +cleanup: + free(keyblock.contents); + if (ret) + return YARROW_FAIL; + return YARROW_OK; } int krb5int_yarrow_cipher_encrypt_block @@ -76,7 +77,7 @@ int krb5int_yarrow_cipher_encrypt_block ind.length = CIPHER_BLOCK_SIZE; outd.data = (char *) out; outd.length = CIPHER_BLOCK_SIZE; - ret = enc->encrypt (&ctx->key, 0, &ind, &outd); + ret = enc->encrypt(ctx->key, 0, &ind, &outd); if (ret) return YARROW_FAIL; return YARROW_OK; @@ -87,10 +88,6 @@ krb5int_yarrow_cipher_final (CIPHER_CTX *ctx) { - if (ctx->key.contents) { - memset (ctx->key.contents, 0, ctx->key.length); - free (ctx->key.contents); - } - ctx->key.contents = 0; - ctx->key.length = 0; + krb5_k_free_key(NULL, ctx->key); + ctx->key = NULL; } diff --git a/src/lib/crypto/krb/yarrow/ycipher.h b/src/lib/crypto/krb/yarrow/ycipher.h index 96999c0dbb..ad0d307fcb 100644 --- a/src/lib/crypto/krb/yarrow/ycipher.h +++ b/src/lib/crypto/krb/yarrow/ycipher.h @@ -7,7 +7,7 @@ typedef struct { - krb5_keyblock key; + krb5_key key; } CIPHER_CTX; /* We need to choose a cipher. To do this, choose an enc_provider. diff --git a/src/lib/rpc/unit-test/lib/helpers.exp b/src/lib/rpc/unit-test/lib/helpers.exp index 963fff4589..97a8e89221 100644 --- a/src/lib/rpc/unit-test/lib/helpers.exp +++ b/src/lib/rpc/unit-test/lib/helpers.exp @@ -96,6 +96,7 @@ proc setup_database {} { } expect_tcl_prompt + while {![file exists /tmp/go]} {} send_tcl_cmd_await_echo {kadm5_init admin admin $KADM5_ADMIN_SERVICE null $KADM5_STRUCT_VERSION $KADM5_API_VERSION_2 server_handle} expect_kadm_ok expect "^% "