aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypto/builtin')
-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
7 files changed, 113 insertions, 161 deletions
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;