From 638fc9ce2cfdd2e8395471d974ec0d28d1b9064c Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Sun, 6 Dec 2009 16:23:11 +0000 Subject: Make the libk5crypto hash_provider interface take crypto_iov lists instead of lists of krb5_data. Make the base HMAC APIs take crypto_iov lists and drop the _iov variants. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23450 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/k5-int.h | 22 +-- src/lib/crypto/builtin/hash_provider/Makefile.in | 2 +- src/lib/crypto/builtin/hash_provider/hash_crc32.c | 16 +- src/lib/crypto/builtin/hash_provider/hash_md4.c | 14 +- src/lib/crypto/builtin/hash_provider/hash_md5.c | 18 ++- src/lib/crypto/builtin/hash_provider/hash_sha1.c | 21 ++- src/lib/crypto/builtin/hmac.c | 186 +++++++--------------- src/lib/crypto/builtin/pbkdf2.c | 17 +- src/lib/crypto/crypto_tests/t_hmac.c | 20 +-- src/lib/crypto/krb/aead.c | 49 +----- src/lib/crypto/krb/aead.h | 5 - src/lib/crypto/krb/arcfour/arcfour.c | 15 +- src/lib/crypto/krb/arcfour/arcfour_aead.c | 8 +- src/lib/crypto/krb/dk/checksum.c | 53 +----- src/lib/crypto/krb/dk/dk.h | 11 +- src/lib/crypto/krb/dk/dk_aead.c | 4 +- src/lib/crypto/krb/keyhash_provider/hmac_md5.c | 120 ++++++-------- src/lib/crypto/krb/keyhash_provider/md5_hmac.c | 17 +- src/lib/crypto/krb/make_checksum.c | 20 +-- src/lib/crypto/krb/old/old_aead.c | 4 +- src/lib/crypto/krb/prf/des_prf.c | 10 +- src/lib/crypto/krb/prf/dk_prf.c | 20 +-- src/lib/crypto/krb/prf/rc4_prf.c | 6 +- src/lib/crypto/openssl/hash_provider/Makefile.in | 2 +- src/lib/crypto/openssl/hash_provider/hash_crc32.c | 12 +- src/lib/crypto/openssl/hash_provider/hash_md4.c | 14 +- src/lib/crypto/openssl/hash_provider/hash_md5.c | 14 +- src/lib/crypto/openssl/hash_provider/hash_sha1.c | 14 +- src/lib/crypto/openssl/hmac.c | 73 ++------- 29 files changed, 297 insertions(+), 490 deletions(-) diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 04e3310..d16642e 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -667,8 +667,7 @@ struct krb5_hash_provider { char hash_name[8]; size_t hashsize, blocksize; - /* this takes multiple inputs to avoid lots of copying. */ - krb5_error_code (*hash)(unsigned int icount, const krb5_data *input, + krb5_error_code (*hash)(const krb5_crypto_iov *data, size_t num_data, krb5_data *output); }; @@ -703,23 +702,14 @@ void krb5int_nfold(unsigned int inbits, const unsigned char *in, unsigned int outbits, unsigned char *out); krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash, - 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_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, - krb5_data *output); + const krb5_keyblock *keyblock, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output); krb5_error_code krb5int_pbkdf2_hmac_sha1(const krb5_data *, unsigned long, const krb5_data *, const krb5_data *); diff --git a/src/lib/crypto/builtin/hash_provider/Makefile.in b/src/lib/crypto/builtin/hash_provider/Makefile.in index da6240c..36ec412 100644 --- a/src/lib/crypto/builtin/hash_provider/Makefile.in +++ b/src/lib/crypto/builtin/hash_provider/Makefile.in @@ -1,7 +1,7 @@ mydir=lib/crypto/builtin/hash_provider BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../../krb/crc32 -I$(srcdir)/../md4 \ - -I$(srcdir)/../md5 -I$(srcdir)/../sha1 + -I$(srcdir)/../md5 -I$(srcdir)/../sha1 -I$(srcdir)/../../krb DEFS= ##DOS##BUILDTOP = ..\..\..\.. diff --git a/src/lib/crypto/builtin/hash_provider/hash_crc32.c b/src/lib/crypto/builtin/hash_provider/hash_crc32.c index 58efffe..c9cafb0 100644 --- a/src/lib/crypto/builtin/hash_provider/hash_crc32.c +++ b/src/lib/crypto/builtin/hash_provider/hash_crc32.c @@ -28,23 +28,27 @@ #include "k5-int.h" #include "crc-32.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_crc32_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_crc32_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { unsigned long c; unsigned int i; if (output->length != CRC32_CKSUM_LENGTH) - return(KRB5_CRYPTO_INTERNAL); + return KRB5_CRYPTO_INTERNAL; c = 0; - for (i=0; idata.data, iov->data.length, &c); + } store_32_le(c, output->data); - return(0); + return 0; } const struct krb5_hash_provider krb5int_hash_crc32 = { diff --git a/src/lib/crypto/builtin/hash_provider/hash_md4.c b/src/lib/crypto/builtin/hash_provider/hash_md4.c index 3a7d0d4..85f18f6 100644 --- a/src/lib/crypto/builtin/hash_provider/hash_md4.c +++ b/src/lib/crypto/builtin/hash_provider/hash_md4.c @@ -28,10 +28,10 @@ #include "k5-int.h" #include "rsa-md4.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_md4_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_md4_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_MD4_CTX ctx; unsigned int i; @@ -40,8 +40,14 @@ k5_md4_hash(unsigned int icount, const krb5_data *input, return(KRB5_CRYPTO_INTERNAL); krb5int_MD4Init(&ctx); - for (i=0; idata.data, + iov->data.length); + } + } krb5int_MD4Final(&ctx); memcpy(output->data, ctx.digest, RSA_MD4_CKSUM_LENGTH); diff --git a/src/lib/crypto/builtin/hash_provider/hash_md5.c b/src/lib/crypto/builtin/hash_provider/hash_md5.c index 610e414..583a8fb 100644 --- a/src/lib/crypto/builtin/hash_provider/hash_md5.c +++ b/src/lib/crypto/builtin/hash_provider/hash_md5.c @@ -28,25 +28,31 @@ #include "k5-int.h" #include "rsa-md5.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_md5_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_md5_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_MD5_CTX ctx; unsigned int i; if (output->length != RSA_MD5_CKSUM_LENGTH) - return(KRB5_CRYPTO_INTERNAL); + return KRB5_CRYPTO_INTERNAL; krb5int_MD5Init(&ctx); - for (i=0; idata.data, + iov->data.length); + } + } krb5int_MD5Final(&ctx); memcpy(output->data, ctx.digest, RSA_MD5_CKSUM_LENGTH); - return(0); + return 0; } const struct krb5_hash_provider krb5int_hash_md5 = { diff --git a/src/lib/crypto/builtin/hash_provider/hash_sha1.c b/src/lib/crypto/builtin/hash_provider/hash_sha1.c index a861d4c..7a9cda5 100644 --- a/src/lib/crypto/builtin/hash_provider/hash_sha1.c +++ b/src/lib/crypto/builtin/hash_provider/hash_sha1.c @@ -28,27 +28,32 @@ #include "k5-int.h" #include "shs.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_sha1_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_sha1_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { SHS_INFO ctx; unsigned int i; if (output->length != SHS_DIGESTSIZE) - return(KRB5_CRYPTO_INTERNAL); + return KRB5_CRYPTO_INTERNAL; shsInit(&ctx); - for (i=0; idata.data, + iov->data.length); + } + } shsFinal(&ctx); - for (i=0; i<(sizeof(ctx.digest)/sizeof(ctx.digest[0])); i++) { + for (i = 0; i < sizeof(ctx.digest) / sizeof(ctx.digest[0]); i++) store_32_be(ctx.digest[i], &output->data[i*4]); - } - return(0); + return 0; } const struct krb5_hash_provider krb5int_hash_sha1 = { diff --git a/src/lib/crypto/builtin/hmac.c b/src/lib/crypto/builtin/hmac.c index 7d1f244..19ed2ef 100644 --- a/src/lib/crypto/builtin/hmac.c +++ b/src/lib/crypto/builtin/hmac.c @@ -30,17 +30,14 @@ /* * Because our built-in HMAC implementation doesn't need to invoke any - * encryption or keyed hash functions, it is simplest to define it in - * terms of keyblocks, and then supply a simple wrapper for the - * "normal" krb5_key-using interfaces. The keyblock interfaces are - * useful for the built-in arcfour code which constructs a lot of - * intermediate HMAC keys. For other back ends, it should not be - * necessary to supply the _keyblock versions of the hmac functions if - * the back end code doesn't make use of them. + * 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 code which creates + * intermediate keyblocks. */ /* - * the HMAC transform looks like: + * The HMAC transform looks like: * * H(K XOR opad, H(K XOR ipad, text)) * @@ -53,143 +50,72 @@ 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) + const krb5_keyblock *keyblock, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { - size_t hashsize, blocksize; - unsigned char *xorkey, *ihash; + unsigned char *xorkey = NULL, *ihash = NULL; unsigned int i; - krb5_data *hashin, hashout; + krb5_crypto_iov *ihash_iov, ohash_iov[2]; + krb5_data hashout; krb5_error_code ret; - hashsize = hash->hashsize; - blocksize = hash->blocksize; + if (keyblock->length > hash->blocksize) + return KRB5_CRYPTO_INTERNAL; + if (output->length < hash->hashsize) + return KRB5_BAD_MSIZE; - if (key->length > blocksize) - return(KRB5_CRYPTO_INTERNAL); - if (output->length < hashsize) - return(KRB5_BAD_MSIZE); - /* if this isn't > 0, then there won't be enough space in this - array to compute the outer hash */ - if (icount == 0) - return(KRB5_CRYPTO_INTERNAL); - - /* allocate space for the xor key, hash input vector, and inner hash */ - - if ((xorkey = (unsigned char *) malloc(blocksize)) == NULL) - return(ENOMEM); - if ((ihash = (unsigned char *) malloc(hashsize)) == NULL) { - free(xorkey); - return(ENOMEM); - } - if ((hashin = (krb5_data *)malloc(sizeof(krb5_data)*(icount+1))) == NULL) { - free(ihash); - free(xorkey); - return(ENOMEM); - } - - /* create the inner padded key */ - - memset(xorkey, 0x36, blocksize); - - for (i=0; ilength; i++) - xorkey[i] ^= key->contents[i]; - - /* compute the inner hash */ - - hashin[0].length = blocksize; - hashin[0].data = (char *) xorkey; - for (i=0; ihash))(icount+1, hashin, &hashout)))) + /* Allocate space for the xor key, hash input vector, and inner hash */ + xorkey = k5alloc(hash->blocksize, &ret); + if (xorkey == NULL) + goto cleanup; + ihash = k5alloc(hash->hashsize, &ret); + if (ihash == NULL) + goto cleanup; + ihash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret); + if (ihash_iov == NULL) goto cleanup; - /* create the outer padded key */ - - memset(xorkey, 0x5c, blocksize); - - for (i=0; ilength; i++) - xorkey[i] ^= key->contents[i]; - - /* compute the outer hash */ - - hashin[0].length = blocksize; - hashin[0].data = (char *) xorkey; - hashin[1] = hashout; - - output->length = hashsize; + /* Create the inner padded key. */ + memset(xorkey, 0x36, hash->blocksize); + for (i = 0; i < keyblock->length; i++) + xorkey[i] ^= keyblock->contents[i]; + + /* Compute the inner hash over the inner key and input data. */ + ihash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + ihash_iov[0].data = make_data(xorkey, hash->blocksize); + memcpy(ihash_iov + 1, data, num_data * sizeof(krb5_crypto_iov)); + hashout = make_data(ihash, hash->hashsize); + ret = hash->hash(ihash_iov, num_data + 1, &hashout); + if (ret != 0) + goto cleanup; - if ((ret = ((*(hash->hash))(2, hashin, output)))) + /* Create the outer padded key. */ + memset(xorkey, 0x5c, hash->blocksize); + for (i = 0; i < keyblock->length; i++) + xorkey[i] ^= keyblock->contents[i]; + + /* Compute the outer hash over the outer key and inner hash value. */ + ohash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + ohash_iov[0].data = make_data(xorkey, hash->blocksize); + ohash_iov[1].flags = KRB5_CRYPTO_TYPE_DATA; + ohash_iov[1].data = make_data(ihash, hash->hashsize); + output->length = hash->hashsize; + ret = hash->hash(ohash_iov, 2, output); + if (ret != 0) memset(output->data, 0, output->length); - /* ret is set correctly by the prior call */ - cleanup: - memset(xorkey, 0, blocksize); - memset(ihash, 0, hashsize); - - free(hashin); - free(ihash); - free(xorkey); - - return(ret); -} - -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, - krb5_data *output) -{ - krb5_data *sign_data; - size_t num_sign_data; - krb5_error_code ret; - size_t i, j; - - /* Create a checksum over all the data to be signed */ - for (i = 0, num_sign_data = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - num_sign_data++; - } - - /* XXX cleanup to avoid alloc */ - sign_data = (krb5_data *)calloc(num_sign_data, sizeof(krb5_data)); - if (sign_data == NULL) - return ENOMEM; - - for (i = 0, j = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - sign_data[j++] = iov->data; - } - - /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */ - ret = krb5int_hmac_keyblock(hash, key, num_sign_data, sign_data, output); - - free(sign_data); - + zapfree(xorkey, hash->blocksize); + zapfree(ihash, hash->hashsize); + free(ihash_iov); return ret; } krb5_error_code krb5int_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) + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { - return krb5int_hmac_iov_keyblock(hash, &key->keyblock, data, num_data, - output); + return krb5int_hmac_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 6c954d3..7ee07f0 100644 --- a/src/lib/crypto/builtin/pbkdf2.c +++ b/src/lib/crypto/builtin/pbkdf2.c @@ -221,31 +221,36 @@ hmac_sha1(krb5_key pass, krb5_data *salt, krb5_data *out) { const struct krb5_hash_provider *h = &krb5int_hash_sha1; krb5_error_code err; + krb5_crypto_iov iov; if (debug_hmac) printd(" hmac input", salt); - err = krb5int_hmac(h, pass, 1, salt, out); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *salt; + err = krb5int_hmac(h, pass, &iov, 1, out); if (err == 0 && debug_hmac) printd(" hmac output", 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) +krb5int_pbkdf2_hmac_sha1(const krb5_data *out, unsigned long count, + const krb5_data *pass, const krb5_data *salt) { const struct krb5_hash_provider *h = &krb5int_hash_sha1; krb5_keyblock keyblock; krb5_key key; char tmp[40]; krb5_data d; + krb5_crypto_iov iov; 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); + d = make_data(tmp, h->hashsize); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *pass; + err = h->hash(&iov, 1, &d); if (err) return err; keyblock.length = d.length; diff --git a/src/lib/crypto/crypto_tests/t_hmac.c b/src/lib/crypto/crypto_tests/t_hmac.c index 2bb5ff3..1056ff6 100644 --- a/src/lib/crypto/crypto_tests/t_hmac.c +++ b/src/lib/crypto/crypto_tests/t_hmac.c @@ -100,6 +100,8 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h, size_t blocksize, hashsize; krb5_error_code err; krb5_key k; + krb5_crypto_iov iov; + krb5_data d; printk(" test key", key); blocksize = h->blocksize; @@ -107,23 +109,23 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h, 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); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data(key->contents, key->length); + d = make_data(tmp, hashsize); + err = h->hash(&iov, 1, &d); if (err) { com_err(whoami, err, "hashing key before calling hmac"); exit(1); } - key->length = d2.length; - key->contents = (krb5_octet *) d2.data; + key->length = d.length; + key->contents = (krb5_octet *) d.data; printk(" pre-hashed key", key); } printd(" hmac input", in); krb5_k_create_key(NULL, key, &k); - err = krb5int_hmac(h, k, 1, in, out); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *in; + err = krb5int_hmac(h, k, &iov, 1, out); krb5_k_free_key(NULL, k); if (err == 0) printd(" hmac output", out); diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c index 539dd3f..7b95d58 100644 --- a/src/lib/crypto/krb/aead.c +++ b/src/lib/crypto/krb/aead.c @@ -53,44 +53,6 @@ krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data, return iov; } -/* Glue the IOV interface to the hash provider's old list-of-buffers. */ -krb5_error_code -krb5int_hash_iov(const struct krb5_hash_provider *hash_provider, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output) -{ - krb5_data *sign_data; - size_t num_sign_data; - krb5_error_code ret; - size_t i, j; - - /* Create a checksum over all the data to be signed */ - for (i = 0, num_sign_data = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - num_sign_data++; - } - - /* XXX cleanup to avoid alloc. */ - sign_data = calloc(num_sign_data, sizeof(krb5_data)); - if (sign_data == NULL) - return ENOMEM; - - for (i = 0, j = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - sign_data[j++] = iov->data; - } - - ret = (*hash_provider->hash)(num_sign_data, sign_data, output); - - free(sign_data); - - return ret; -} - krb5_error_code krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type, krb5_key key, @@ -117,14 +79,13 @@ krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type, if (cksum_type->keyhash->hash_iov == NULL) return KRB5_BAD_ENCTYPE; - ret = (*cksum_type->keyhash->hash_iov)(key, usage, 0, data, num_data, - cksum_data); + ret = cksum_type->keyhash->hash_iov(key, usage, 0, data, num_data, + cksum_data); } else if (cksum_type->flags & KRB5_CKSUMFLAG_DERIVE) { - ret = krb5int_dk_make_checksum_iov(cksum_type->hash, - key, usage, data, num_data, - cksum_data); + ret = krb5int_dk_make_checksum(cksum_type->hash, key, usage, data, + num_data, cksum_data); } else { - ret = krb5int_hash_iov(cksum_type->hash, data, num_data, cksum_data); + ret = cksum_type->hash->hash(data, num_data, cksum_data); } if (ret == 0) { diff --git a/src/lib/crypto/krb/aead.h b/src/lib/crypto/krb/aead.h index 33ed2fd..f5a3219 100644 --- a/src/lib/crypto/krb/aead.h +++ b/src/lib/crypto/krb/aead.h @@ -37,11 +37,6 @@ krb5int_c_locate_iov(krb5_crypto_iov *data, krb5_cryptotype type); krb5_error_code -krb5int_hash_iov(const struct krb5_hash_provider *hash_provider, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output); - -krb5_error_code krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum, krb5_key key, krb5_keyusage usage, diff --git a/src/lib/crypto/krb/arcfour/arcfour.c b/src/lib/crypto/krb/arcfour/arcfour.c index c8b478f..783b777 100644 --- a/src/lib/crypto/krb/arcfour/arcfour.c +++ b/src/lib/crypto/krb/arcfour/arcfour.c @@ -43,8 +43,9 @@ krb5int_arcfour_usage_key(const struct krb5_enc_provider *enc, krb5_keyblock *out) { char salt_buf[14]; + unsigned int salt_len; krb5_data out_data = make_data(out->contents, out->length); - krb5_data salt = make_data(salt_buf, sizeof(salt_buf)); + krb5_crypto_iov iov; krb5_keyusage ms_usage; /* Generate the salt. */ @@ -52,13 +53,16 @@ krb5int_arcfour_usage_key(const struct krb5_enc_provider *enc, if (session_keyblock->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { memcpy(salt_buf, l40, 10); store_32_le(ms_usage, salt_buf + 10); + salt_len = 14; } else { - salt.length=4; store_32_le(ms_usage, salt_buf); + salt_len = 4; } /* Compute HMAC(key, salt) to produce the usage key. */ - return krb5int_hmac_keyblock(hash, session_keyblock, 1, &salt, &out_data); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data(salt_buf, salt_len); + return krb5int_hmac_keyblock(hash, session_keyblock, &iov, 1, &out_data); } /* Derive an encryption key from a usage key and (typically) checksum. */ @@ -70,6 +74,7 @@ krb5int_arcfour_enc_key(const struct krb5_enc_provider *enc, { krb5_keyblock *trunc_keyblock = NULL; krb5_data out_data = make_data(out->contents, out->length); + krb5_crypto_iov iov; krb5_error_code ret; /* Copy usage_keyblock to trunc_keyblock and truncate if exportable. */ @@ -80,7 +85,9 @@ krb5int_arcfour_enc_key(const struct krb5_enc_provider *enc, memset(trunc_keyblock->contents + 7, 0xab, 9); /* Compute HMAC(trunc_key, checksum) to produce the encryption key. */ - ret = krb5int_hmac_keyblock(hash, trunc_keyblock, 1, checksum, &out_data); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *checksum; + ret = krb5int_hmac_keyblock(hash, trunc_keyblock, &iov, 1, &out_data); krb5int_c_free_keyblock(NULL, trunc_keyblock); return ret; } diff --git a/src/lib/crypto/krb/arcfour/arcfour_aead.c b/src/lib/crypto/krb/arcfour/arcfour_aead.c index d886235..6f82921 100644 --- a/src/lib/crypto/krb/arcfour/arcfour_aead.c +++ b/src/lib/crypto/krb/arcfour/arcfour_aead.c @@ -137,8 +137,8 @@ krb5int_arcfour_encrypt(const struct krb5_keytypes *ktp, krb5_key key, header->data.data += hash->hashsize; /* Compute the checksum using the usage key. */ - ret = krb5int_hmac_iov_keyblock(hash, usage_keyblock, data, num_data, - &checksum); + ret = krb5int_hmac_keyblock(hash, usage_keyblock, data, num_data, + &checksum); if (ret != 0) goto cleanup; @@ -219,8 +219,8 @@ krb5int_arcfour_decrypt(const struct krb5_keytypes *ktp, krb5_key key, goto cleanup; /* Compute HMAC(usage key, plaintext) to get the checksum. */ - ret = krb5int_hmac_iov_keyblock(hash, usage_keyblock, data, num_data, - &comp_checksum); + ret = krb5int_hmac_keyblock(hash, usage_keyblock, data, num_data, + &comp_checksum); if (ret != 0) goto cleanup; diff --git a/src/lib/crypto/krb/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c index 106bf15..dee4f47 100644 --- a/src/lib/crypto/krb/dk/checksum.c +++ b/src/lib/crypto/krb/dk/checksum.c @@ -35,55 +35,8 @@ krb5_error_code krb5int_dk_make_checksum(const struct krb5_hash_provider *hash, krb5_key key, krb5_keyusage usage, - const krb5_data *input, krb5_data *output) -{ - const struct krb5_keytypes *ktp; - const struct krb5_enc_provider *enc; - krb5_error_code ret; - unsigned char constantdata[K5CLENGTH]; - krb5_data datain; - krb5_key kc; - - ktp = find_enctype(key->keyblock.enctype); - if (ktp == NULL) - return KRB5_BAD_ENCTYPE; - enc = ktp->enc; - - /* - * key->length will be tested in enc->encrypt. - * output->length will be tested in krb5int_hmac. - */ - - /* Derive the key. */ - - datain.data = (char *) constantdata; - datain.length = K5CLENGTH; - - store_32_be(usage, constantdata); - - datain.data[4] = (char) 0x99; - - ret = krb5int_derive_key(enc, key, &kc, &datain); - if (ret) - return ret; - - /* hash the data */ - - datain = *input; - - ret = krb5int_hmac(hash, kc, 1, &datain, output); - if (ret) - memset(output->data, 0, output->length); - - krb5_k_free_key(NULL, kc); - return ret; -} - -krb5_error_code -krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, - krb5_key key, krb5_keyusage usage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output) + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; @@ -117,7 +70,7 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, /* Hash the data. */ - ret = krb5int_hmac_iov(hash, kc, data, num_data, output); + ret = krb5int_hmac(hash, kc, data, num_data, output); if (ret) memset(output->data, 0, output->length); diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h index 892f6b4..5e00268 100644 --- a/src/lib/crypto/krb/dk/dk.h +++ b/src/lib/crypto/krb/dk/dk.h @@ -70,18 +70,11 @@ krb5int_derive_key(const struct krb5_enc_provider *enc, krb5_error_code krb5int_dk_make_checksum(const struct krb5_hash_provider *hash, - krb5_key key, - krb5_keyusage usage, - const krb5_data *input, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, krb5_data *output); krb5_error_code -krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, - krb5_key key, krb5_keyusage usage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output); - -krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc, krb5_key inkey, krb5_data *outrnd, const krb5_data *in_constant); diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c index 59c84db..f44ae84 100644 --- a/src/lib/crypto/krb/dk/dk_aead.c +++ b/src/lib/crypto/krb/dk/dk_aead.c @@ -156,7 +156,7 @@ krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key, d2.length = hash->hashsize; d2.data = (char *)cksum; - ret = krb5int_hmac_iov(hash, ki, data, num_data, &d2); + ret = krb5int_hmac(hash, ki, data, num_data, &d2); if (ret != 0) goto cleanup; @@ -254,7 +254,7 @@ krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key, d1.length = hash->hashsize; /* non-truncated length */ d1.data = (char *)cksum; - ret = krb5int_hmac_iov(hash, ki, data, num_data, &d1); + ret = krb5int_hmac(hash, ki, data, num_data, &d1); if (ret != 0) goto cleanup; diff --git a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c index 6bfbefd..f522d0c 100644 --- a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c +++ b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c @@ -37,116 +37,94 @@ #include "../aead.h" static krb5_error_code -k5_hmac_md5_hash (krb5_key key, krb5_keyusage usage, - const krb5_data *iv, - const krb5_data *input, krb5_data *output) +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 keyblock; - krb5_key ks = NULL; - krb5_data ds, ks_constant, md5tmp; + krb5_keyblock ks; + krb5_crypto_iov iov; + krb5_data ds; krb5_MD5_CTX ctx; char t[4]; + ret = alloc_data(&ds, key->keyblock.length); + if (ret != 0) + return ret; - ds.length = key->keyblock.length; - ds.data = malloc(ds.length); - if (ds.data == NULL) - return ENOMEM; - - ks_constant.data = "signaturekey"; - ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/ - - ret = krb5int_hmac( &krb5int_hash_md5, key, 1, - &ks_constant, &ds); + /* Compute HMAC(key, "signaturekey\0") to produce the signing key ks. */ + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data("signaturekey", 13); + ret = krb5int_hmac(&krb5int_hash_md5, key, &iov, 1, &ds); if (ret) goto cleanup; + ks.length = key->keyblock.length; + ks.contents = (krb5_octet *) ds.data; - keyblock.length = key->keyblock.length; - keyblock.contents = (void *) ds.data; - ret = krb5_k_create_key(NULL, &keyblock, &ks); - if (ret) - goto cleanup; - - krb5int_MD5Init (&ctx); - ms_usage = krb5int_arcfour_translate_usage (usage); + /* Compute the MD5 value of the input. */ + krb5int_MD5Init(&ctx); + ms_usage = krb5int_arcfour_translate_usage(usage); store_32_le(ms_usage, t); - krb5int_MD5Update (&ctx, (unsigned char * ) &t, 4); - krb5int_MD5Update (&ctx, (unsigned char *) input-> data, - (unsigned int) input->length ); + krb5int_MD5Update(&ctx, (unsigned char *) &t, 4); + krb5int_MD5Update(&ctx, (unsigned char *) input->data, input->length); krb5int_MD5Final(&ctx); - md5tmp.data = (void *) ctx.digest; - md5tmp.length = 16; - ret = krb5int_hmac ( &krb5int_hash_md5, ks, 1, &md5tmp, - output); + /* Compute HMAC(ks, md5value). */ + iov.data = make_data(ctx.digest, 16); + ret = krb5int_hmac_keyblock(&krb5int_hash_md5, &ks, &iov, 1, output); cleanup: memset(&ctx, 0, sizeof(ctx)); zapfree(ds.data, ds.length); - krb5_k_free_key(NULL, ks); return ret; } static krb5_error_code -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) +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 keyblock; - krb5_key ks = NULL; - krb5_data ds, ks_constant, md5tmp; + krb5_keyblock ks; + krb5_crypto_iov iov; + krb5_data ds; krb5_MD5_CTX ctx; char t[4]; size_t i; - keyblock.contents = NULL; - keyblock.length = 0; - - ds.length = key->keyblock.length; - ds.data = malloc(ds.length); - if (ds.data == NULL) - return ENOMEM; - - ks_constant.data = "signaturekey"; - ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/ + ret = alloc_data(&ds, key->keyblock.length); + if (ret != 0) + return ret; - ret = krb5int_hmac( &krb5int_hash_md5, key, 1, - &ks_constant, &ds); + /* Compute HMAC(key, "signaturekey\0") to produce the signing key ks. */ + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data("signaturekey", 13); + ret = krb5int_hmac(&krb5int_hash_md5, key, &iov, 1, &ds); if (ret) goto cleanup; + ks.length = key->keyblock.length; + ks.contents = (krb5_octet *) ds.data; - keyblock.length = key->keyblock.length; - keyblock.contents = (void *) ds.data; - ret = krb5_k_create_key(NULL, &keyblock, &ks); - if (ret) - goto cleanup; - - krb5int_MD5Init (&ctx); - ms_usage = krb5int_arcfour_translate_usage (usage); + /* Compute the MD5 value of the input. */ + krb5int_MD5Init(&ctx); + ms_usage = krb5int_arcfour_translate_usage(usage); store_32_le(ms_usage, t); - krb5int_MD5Update (&ctx, (unsigned char * ) &t, 4); + krb5int_MD5Update(&ctx, (unsigned char *) &t, 4); for (i = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - krb5int_MD5Update (&ctx, (unsigned char *)iov->data.data, - (unsigned int)iov->data.length); + if (SIGN_IOV(&data[i])) + krb5int_MD5Update(&ctx, (unsigned char *) data[i].data.data, + data[i].data.length); } krb5int_MD5Final(&ctx); - md5tmp.data = (void *) ctx.digest; - md5tmp.length = 16; - ret = krb5int_hmac ( &krb5int_hash_md5, ks, 1, &md5tmp, - output); + + /* Compute HMAC(ks, md5value). */ + iov.data = make_data(ctx.digest, 16); + ret = krb5int_hmac_keyblock(&krb5int_hash_md5, &ks, &iov, 1, output); cleanup: memset(&ctx, 0, sizeof(ctx)); - zapfree(keyblock.contents, keyblock.length); - krb5_k_free_key(NULL, ks); + zapfree(ds.data, ds.length); return ret; } diff --git a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c index b7d53f7..39b2c18 100644 --- a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c +++ b/src/lib/crypto/krb/keyhash_provider/md5_hmac.c @@ -34,28 +34,25 @@ #include "hash_provider.h" static krb5_error_code -k5_md5_hmac_hash (krb5_key key, krb5_keyusage usage, - const krb5_data *iv, - const krb5_data *input, krb5_data *output) +k5_md5_hmac_hash(krb5_key key, krb5_keyusage usage, const krb5_data *iv, + const krb5_data *input, krb5_data *output) { krb5_keyusage ms_usage; krb5_MD5_CTX ctx; unsigned char t[4]; - krb5_data ds; + krb5_crypto_iov iov; krb5int_MD5Init(&ctx); - ms_usage = krb5int_arcfour_translate_usage (usage); + ms_usage = krb5int_arcfour_translate_usage(usage); store_32_le(ms_usage, t); krb5int_MD5Update(&ctx, t, sizeof(t)); krb5int_MD5Update(&ctx, (unsigned char *)input->data, input->length); krb5int_MD5Final(&ctx); - ds.magic = KV5M_DATA; - ds.length = 16; - ds.data = (char *)ctx.digest; - - return krb5int_hmac ( &krb5int_hash_md5, key, 1, &ds, output); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data(ctx.digest, 16); + return krb5int_hmac(&krb5int_hash_md5, key, &iov, 1, output); } const struct krb5_keyhash_provider krb5int_keyhash_md5_hmac = { diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c index f62f40a..bc69dfb 100644 --- a/src/lib/crypto/krb/make_checksum.c +++ b/src/lib/crypto/krb/make_checksum.c @@ -39,11 +39,15 @@ krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, const struct krb5_cksumtypes *ctp; const struct krb5_keytypes *ktp1, *ktp2; const struct krb5_keyhash_provider *keyhash; + krb5_crypto_iov iov; krb5_data data; krb5_octet *trunc; krb5_error_code ret; size_t cksumlen; + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *input; + for (i = 0; i < krb5int_cksumtypes_length; i++) { if (krb5int_cksumtypes_list[i].ctype == cksumtype) break; @@ -62,8 +66,7 @@ krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, if (cksum->contents == NULL) return ENOMEM; - data.length = cksum->length; - data.data = (char *) cksum->contents; + data = make_data(cksum->contents, cksum->length); if (ctp->keyhash) { /* check if key is compatible */ @@ -78,23 +81,16 @@ krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, keyhash = ctp->keyhash; if (keyhash->hash == NULL) { - krb5_crypto_iov iov[1]; - - iov[0].flags = KRB5_CRYPTO_TYPE_DATA; - iov[0].data.data = input->data; - iov[0].data.length = input->length; - assert(keyhash->hash_iov != NULL); - - ret = (*keyhash->hash_iov)(key, usage, 0, iov, 1, &data); + ret = (*keyhash->hash_iov)(key, usage, 0, &iov, 1, &data); } else { ret = (*keyhash->hash)(key, usage, 0, input, &data); } } else if (ctp->flags & KRB5_CKSUMFLAG_DERIVE) { - ret = krb5int_dk_make_checksum(ctp->hash, key, usage, input, &data); + ret = krb5int_dk_make_checksum(ctp->hash, key, usage, &iov, 1, &data); } else { /* No key is used. */ - ret = (*ctp->hash->hash)(1, input, &data); + ret = ctp->hash->hash(&iov, 1, &data); } if (!ret) { diff --git a/src/lib/crypto/krb/old/old_aead.c b/src/lib/crypto/krb/old/old_aead.c index c72faeb..f7d1f10 100644 --- a/src/lib/crypto/krb/old/old_aead.c +++ b/src/lib/crypto/krb/old/old_aead.c @@ -101,7 +101,7 @@ krb5int_old_encrypt(const struct krb5_keytypes *ktp, krb5_key key, memset(checksum.data, 0, hash->hashsize); /* Checksum the plaintext with zeroed checksum and padding. */ - ret = krb5int_hash_iov(hash, data, num_data, &checksum); + ret = hash->hash(data, num_data, &checksum); if (ret != 0) goto cleanup; @@ -179,7 +179,7 @@ krb5int_old_decrypt(const struct krb5_keytypes *ktp, krb5_key key, * back into the plaintext field we just zeroed out. Then compare it to * the saved checksum. */ - ret = krb5int_hash_iov(hash, data, num_data, &checksum); + ret = hash->hash(data, num_data, &checksum); if (memcmp(checksum.data, saved_checksum, checksum.length) != 0) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; goto cleanup; diff --git a/src/lib/crypto/krb/prf/des_prf.c b/src/lib/crypto/krb/prf/des_prf.c index 96f5e2b..a111423 100644 --- a/src/lib/crypto/krb/prf/des_prf.c +++ b/src/lib/crypto/krb/prf/des_prf.c @@ -41,12 +41,14 @@ krb5int_des_prf(const struct krb5_keytypes *ktp, krb5_key key, krb5_crypto_iov iov; krb5_error_code ret; + /* Compute a hash of the input, storing into the output buffer. */ iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = *out; - - /* Hash the input into the output buffer, then encrypt it in place. */ - ret = hash->hash(1, in, out); + iov.data = *in; + ret = hash->hash(&iov, 1, out); if (ret != 0) return ret; + + /* Encrypt the hash in place. */ + iov.data = *out; return ktp->enc->encrypt(key, NULL, &iov, 1); } diff --git a/src/lib/crypto/krb/prf/dk_prf.c b/src/lib/crypto/krb/prf/dk_prf.c index 3c9a394..9851ce7 100644 --- a/src/lib/crypto/krb/prf/dk_prf.c +++ b/src/lib/crypto/krb/prf/dk_prf.c @@ -40,27 +40,29 @@ krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key, const struct krb5_enc_provider *enc = ktp->enc; const struct krb5_hash_provider *hash = ktp->hash; krb5_crypto_iov iov; - krb5_data prfconst = make_data("prf", 3); + krb5_data cksum = empty_data(), prfconst = make_data("prf", 3); krb5_key kp = NULL; krb5_error_code ret; /* Hash the input data into an allocated buffer. */ - iov.flags = KRB5_CRYPTO_TYPE_DATA; - ret = alloc_data(&iov.data, hash->hashsize); + ret = alloc_data(&cksum, hash->hashsize); if (ret != 0) - return ret; - ret = hash->hash(1, in, &iov.data); + goto cleanup; + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *in; + ret = hash->hash(&iov, 1, &cksum); if (ret != 0) goto cleanup; - /* Truncate the hash to the closest multiple of the block size. */ - iov.data.length = (iov.data.length / enc->block_size) * enc->block_size; - /* Derive a key using the PRF constant. */ ret = krb5int_derive_key(ktp->enc, key, &kp, &prfconst); if (ret != 0) goto cleanup; + /* Truncate the hash to the closest multiple of the block size. */ + iov.data.data = cksum.data; + iov.data.length = (hash->hashsize / enc->block_size) * enc->block_size; + /* Encrypt the truncated hash in the derived key to get the output. */ ret = ktp->enc->encrypt(kp, NULL, &iov, 1); if (ret != 0) @@ -68,7 +70,7 @@ krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key, memcpy(out->data, iov.data.data, out->length); cleanup: - zapfree(iov.data.data, hash->hashsize); + zapfree(cksum.data, hash->hashsize); krb5_k_free_key(NULL, kp); return ret; } diff --git a/src/lib/crypto/krb/prf/rc4_prf.c b/src/lib/crypto/krb/prf/rc4_prf.c index 5f662d7..e34ab26 100644 --- a/src/lib/crypto/krb/prf/rc4_prf.c +++ b/src/lib/crypto/krb/prf/rc4_prf.c @@ -34,6 +34,10 @@ krb5_error_code krb5int_arcfour_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out) { + krb5_crypto_iov iov; + assert(out->length == 20); - return krb5int_hmac(&krb5int_hash_sha1, key, 1, in, out); + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *in; + return krb5int_hmac(&krb5int_hash_sha1, key, &iov, 1, out); } diff --git a/src/lib/crypto/openssl/hash_provider/Makefile.in b/src/lib/crypto/openssl/hash_provider/Makefile.in index 30737eb..b5a7dcf 100644 --- a/src/lib/crypto/openssl/hash_provider/Makefile.in +++ b/src/lib/crypto/openssl/hash_provider/Makefile.in @@ -1,7 +1,7 @@ mydir=lib/crypto/openssl/hash_provider BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../../krb/crc32 -I$(srcdir)/../md4 \ - -I$(srcdir)/../md5 -I$(srcdir)/../sha1 + -I$(srcdir)/../md5 -I$(srcdir)/../sha1 -I$(srcdir)/../../krb DEFS= ##DOS##BUILDTOP = ..\..\..\.. diff --git a/src/lib/crypto/openssl/hash_provider/hash_crc32.c b/src/lib/crypto/openssl/hash_provider/hash_crc32.c index 58efffe..68a01cb 100644 --- a/src/lib/crypto/openssl/hash_provider/hash_crc32.c +++ b/src/lib/crypto/openssl/hash_provider/hash_crc32.c @@ -28,10 +28,10 @@ #include "k5-int.h" #include "crc-32.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_crc32_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_crc32_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { unsigned long c; unsigned int i; @@ -40,8 +40,12 @@ k5_crc32_hash(unsigned int icount, const krb5_data *input, return(KRB5_CRYPTO_INTERNAL); c = 0; - for (i=0; idata.data, iov->data.length, &c); + } store_32_le(c, output->data); return(0); diff --git a/src/lib/crypto/openssl/hash_provider/hash_md4.c b/src/lib/crypto/openssl/hash_provider/hash_md4.c index 3a7d0d4..85f18f6 100644 --- a/src/lib/crypto/openssl/hash_provider/hash_md4.c +++ b/src/lib/crypto/openssl/hash_provider/hash_md4.c @@ -28,10 +28,10 @@ #include "k5-int.h" #include "rsa-md4.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_md4_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_md4_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_MD4_CTX ctx; unsigned int i; @@ -40,8 +40,14 @@ k5_md4_hash(unsigned int icount, const krb5_data *input, return(KRB5_CRYPTO_INTERNAL); krb5int_MD4Init(&ctx); - for (i=0; idata.data, + iov->data.length); + } + } krb5int_MD4Final(&ctx); memcpy(output->data, ctx.digest, RSA_MD4_CKSUM_LENGTH); diff --git a/src/lib/crypto/openssl/hash_provider/hash_md5.c b/src/lib/crypto/openssl/hash_provider/hash_md5.c index 610e414..182e6c0 100644 --- a/src/lib/crypto/openssl/hash_provider/hash_md5.c +++ b/src/lib/crypto/openssl/hash_provider/hash_md5.c @@ -28,10 +28,10 @@ #include "k5-int.h" #include "rsa-md5.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_md5_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_md5_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_MD5_CTX ctx; unsigned int i; @@ -40,8 +40,14 @@ k5_md5_hash(unsigned int icount, const krb5_data *input, return(KRB5_CRYPTO_INTERNAL); krb5int_MD5Init(&ctx); - for (i=0; idata.data, + iov->data.length); + } + } krb5int_MD5Final(&ctx); memcpy(output->data, ctx.digest, RSA_MD5_CKSUM_LENGTH); diff --git a/src/lib/crypto/openssl/hash_provider/hash_sha1.c b/src/lib/crypto/openssl/hash_provider/hash_sha1.c index a914e34..f602411 100644 --- a/src/lib/crypto/openssl/hash_provider/hash_sha1.c +++ b/src/lib/crypto/openssl/hash_provider/hash_sha1.c @@ -29,10 +29,10 @@ #include "k5-int.h" #include "shs.h" #include "hash_provider.h" +#include "aead.h" static krb5_error_code -k5_sha1_hash(unsigned int icount, const krb5_data *input, - krb5_data *output) +k5_sha1_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { SHS_INFO ctx; unsigned int i; @@ -41,8 +41,14 @@ k5_sha1_hash(unsigned int icount, const krb5_data *input, return(KRB5_CRYPTO_INTERNAL); shsInit(&ctx); - for (i=0; idata.data, + iov->data.length); + } + } shsFinal(&ctx); if (ctx.digestLen > 0 && ctx.digestLen <= output->length){ diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c index 425223d..7ef3d3f 100644 --- a/src/lib/crypto/openssl/hmac.c +++ b/src/lib/crypto/openssl/hmac.c @@ -83,8 +83,9 @@ map_digest(const struct krb5_hash_provider *hash) 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) + const krb5_keyblock *keyblock, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { unsigned int i = 0, md_len = 0; unsigned char md[EVP_MAX_MD_SIZE]; @@ -94,22 +95,21 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, hashsize = hash->hashsize; blocksize = hash->blocksize; - if (key->length > blocksize) + if (keyblock->length > blocksize) return(KRB5_CRYPTO_INTERNAL); if (output->length < hashsize) return(KRB5_BAD_MSIZE); - /* if this isn't > 0, then there won't be enough space in this - array to compute the outer hash */ - if (icount == 0) - return(KRB5_CRYPTO_INTERNAL); if (!map_digest(hash)) return(KRB5_CRYPTO_INTERNAL); // unsupported alg HMAC_CTX_init(&c); - HMAC_Init(&c, key->contents, key->length, map_digest(hash)); - for ( i = 0; i < icount; i++ ) { - HMAC_Update(&c,(const unsigned char*)input[i].data, input[i].length); + HMAC_Init(&c, keyblock->contents, keyblock->length, map_digest(hash)); + for (i = 0; i < num_data; i++) { + krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + HMAC_Update(&c, (unsigned char*) iov->data.data, iov->data.length); } HMAC_Final(&c,(unsigned char *)md, &md_len); if ( md_len <= output->length) { @@ -123,56 +123,9 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, } 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, - krb5_data *output) -{ - krb5_data *sign_data; - size_t num_sign_data; - krb5_error_code ret; - size_t i, j; - - /* Create a checksum over all the data to be signed */ - for (i = 0, num_sign_data = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - num_sign_data++; - } - - /* XXX cleanup to avoid alloc */ - sign_data = (krb5_data *)calloc(num_sign_data, sizeof(krb5_data)); - if (sign_data == NULL) - return ENOMEM; - - for (i = 0, j = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (SIGN_IOV(iov)) - sign_data[j++] = iov->data; - } - - /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */ - ret = krb5int_hmac_keyblock(hash, key, num_sign_data, sign_data, output); - - free(sign_data); - - return ret; -} - -krb5_error_code krb5int_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) + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { - return krb5int_hmac_iov_keyblock(hash, &key->keyblock, data, num_data, - output); + return krb5int_hmac_keyblock(hash, &key->keyblock, data, num_data, output); } -- cgit v1.1