aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/k5-int.h22
-rw-r--r--src/lib/crypto/builtin/hash_provider/Makefile.in2
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_crc32.c16
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_md4.c14
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_md5.c18
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_sha1.c21
-rw-r--r--src/lib/crypto/builtin/hmac.c186
-rw-r--r--src/lib/crypto/builtin/pbkdf2.c17
-rw-r--r--src/lib/crypto/crypto_tests/t_hmac.c20
-rw-r--r--src/lib/crypto/krb/aead.c49
-rw-r--r--src/lib/crypto/krb/aead.h5
-rw-r--r--src/lib/crypto/krb/arcfour/arcfour.c15
-rw-r--r--src/lib/crypto/krb/arcfour/arcfour_aead.c8
-rw-r--r--src/lib/crypto/krb/dk/checksum.c53
-rw-r--r--src/lib/crypto/krb/dk/dk.h11
-rw-r--r--src/lib/crypto/krb/dk/dk_aead.c4
-rw-r--r--src/lib/crypto/krb/keyhash_provider/hmac_md5.c120
-rw-r--r--src/lib/crypto/krb/keyhash_provider/md5_hmac.c17
-rw-r--r--src/lib/crypto/krb/make_checksum.c20
-rw-r--r--src/lib/crypto/krb/old/old_aead.c4
-rw-r--r--src/lib/crypto/krb/prf/des_prf.c10
-rw-r--r--src/lib/crypto/krb/prf/dk_prf.c20
-rw-r--r--src/lib/crypto/krb/prf/rc4_prf.c6
-rw-r--r--src/lib/crypto/openssl/hash_provider/Makefile.in2
-rw-r--r--src/lib/crypto/openssl/hash_provider/hash_crc32.c12
-rw-r--r--src/lib/crypto/openssl/hash_provider/hash_md4.c14
-rw-r--r--src/lib/crypto/openssl/hash_provider/hash_md5.c14
-rw-r--r--src/lib/crypto/openssl/hash_provider/hash_sha1.c14
-rw-r--r--src/lib/crypto/openssl/hmac.c73
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; i<icount; i++)
- mit_crc32(input[i].data, input[i].length, &c);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov))
+ mit_crc32(iov->data.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; i<icount; i++)
- krb5int_MD4Update(&ctx, (unsigned char *) input[i].data, input[i].length);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ krb5int_MD4Update(&ctx, (unsigned char *) iov->data.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; i<icount; i++)
- krb5int_MD5Update(&ctx, (unsigned char *) input[i].data, input[i].length);
+ 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,
+ 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; i<icount; i++)
- shsUpdate(&ctx, (unsigned char *) input[i].data, input[i].length);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ shsUpdate(&ctx, (unsigned char *) iov->data.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; i<key->length; i++)
- xorkey[i] ^= key->contents[i];
-
- /* compute the inner hash */
-
- hashin[0].length = blocksize;
- hashin[0].data = (char *) xorkey;
- for (i=0; i<icount; i++)
- hashin[i+1] = input[i];
-
- hashout.length = hashsize;
- hashout.data = (char *) ihash;
-
- if ((ret = ((*(hash->hash))(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; i<key->length; 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; i<icount; i++)
- mit_crc32(input[i].data, input[i].length, &c);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov))
+ mit_crc32(iov->data.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; i<icount; i++)
- krb5int_MD4Update(&ctx, (unsigned char *) input[i].data, input[i].length);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ krb5int_MD4Update(&ctx, (unsigned char *) iov->data.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; i<icount; i++)
- krb5int_MD5Update(&ctx, (unsigned char *) input[i].data, input[i].length);
+ 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,
+ 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; i<icount; i++)
- shsUpdate(&ctx, (unsigned char *) input[i].data, input[i].length);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ shsUpdate(&ctx, (unsigned char *) iov->data.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);
}