aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto/krb/dk
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-12-04 05:12:35 +0000
committerGreg Hudson <ghudson@mit.edu>2009-12-04 05:12:35 +0000
commit5ffa313d9f6b7c509aa0d7579273150d71ea0f95 (patch)
tree48f8d5606c919dd09d950c5cbf1609f312f2937d /src/lib/crypto/krb/dk
parentea6f77d42700352fcb2a06444d1dc00acf7c20fc (diff)
downloadkrb5-5ffa313d9f6b7c509aa0d7579273150d71ea0f95.zip
krb5-5ffa313d9f6b7c509aa0d7579273150d71ea0f95.tar.gz
krb5-5ffa313d9f6b7c509aa0d7579273150d71ea0f95.tar.bz2
Consolidate the IOV and non-IOV encryption/decryption code paths, and
drop the _iov suffix from most encryption- and decryption-related functions. The enc_provider encrypt and decrypt functions take IOVs, as do the enctype entries in etypes.c, and there are no separate encrypt_iov or decrypt_iov functions. aead_provider is gone. Enctype functions now take pointers to the enctype entry instead of pointers to the enc/hash/aead providers; this allows dk_encrypt and dk_decrypt to be polymorphic in the length function they use now that AES and DES3 can't differentiate by aead provider. aes_string_to_key needed to be moved into the krb/ fold for this since it's an enctype function; it was duplicated between builtin/ and openssl/ before. This leaves openssl/aes empty; the build system currently demands that all modules have the same directory structure, so the directory and Makefile will stick around for now. Three separate copies of the derive_random logic are also now consolidated into one. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23444 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto/krb/dk')
-rw-r--r--src/lib/crypto/krb/dk/Makefile.in6
-rw-r--r--src/lib/crypto/krb/dk/deps39
-rw-r--r--src/lib/crypto/krb/dk/derive.c165
-rw-r--r--src/lib/crypto/krb/dk/dk.h63
-rw-r--r--src/lib/crypto/krb/dk/dk_aead.c142
-rw-r--r--src/lib/crypto/krb/dk/dk_decrypt.c179
-rw-r--r--src/lib/crypto/krb/dk/dk_encrypt.c308
-rw-r--r--src/lib/crypto/krb/dk/stringtokey.c65
8 files changed, 182 insertions, 785 deletions
diff --git a/src/lib/crypto/krb/dk/Makefile.in b/src/lib/crypto/krb/dk/Makefile.in
index c87af05..8d65857 100644
--- a/src/lib/crypto/krb/dk/Makefile.in
+++ b/src/lib/crypto/krb/dk/Makefile.in
@@ -13,24 +13,18 @@ PROG_RPATH=$(KRB5_LIBDIR)
STLIBOBJS=\
checksum.o \
dk_aead.o \
- dk_decrypt.o \
- dk_encrypt.o \
derive.o \
stringtokey.o
OBJS=\
$(OUTPRE)checksum.$(OBJEXT) \
$(OUTPRE)dk_aead.$(OBJEXT) \
- $(OUTPRE)dk_decrypt.$(OBJEXT) \
- $(OUTPRE)dk_encrypt.$(OBJEXT) \
$(OUTPRE)derive.$(OBJEXT) \
$(OUTPRE)stringtokey.$(OBJEXT)
SRCS=\
$(srcdir)/checksum.c \
$(srcdir)/dk_aead.c \
- $(srcdir)/dk_decrypt.c \
- $(srcdir)/dk_encrypt.c \
$(srcdir)/derive.c \
$(srcdir)/stringtokey.c
diff --git a/src/lib/crypto/krb/dk/deps b/src/lib/crypto/krb/dk/deps
index 0de06af..1fa446a 100644
--- a/src/lib/crypto/krb/dk/deps
+++ b/src/lib/crypto/krb/dk/deps
@@ -16,7 +16,7 @@ checksum.so checksum.po $(OUTPRE)checksum.$(OBJEXT): \
dk_aead.so dk_aead.po $(OUTPRE)dk_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../aead.h \
- $(srcdir)/../cksumtypes.h $(top_srcdir)/include/k5-buf.h \
+ $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
$(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
$(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
@@ -24,46 +24,25 @@ dk_aead.so dk_aead.po $(OUTPRE)dk_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h
$(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
$(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
$(top_srcdir)/include/socket-utils.h dk.h dk_aead.c
-dk_decrypt.so dk_decrypt.po $(OUTPRE)dk_decrypt.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+derive.so derive.po $(OUTPRE)derive.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../etypes.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
$(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
$(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
$(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
$(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
$(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
$(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- dk.h dk_decrypt.c
-dk_encrypt.so dk_encrypt.po $(OUTPRE)dk_encrypt.$(OBJEXT): \
+ derive.c dk.h
+stringtokey.so stringtokey.po $(OUTPRE)stringtokey.$(OBJEXT): \
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
$(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- dk.h dk_encrypt.c
-derive.so derive.po $(OUTPRE)derive.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(COM_ERR_DEPS) $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
$(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
$(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
$(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
$(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
$(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h derive.c dk.h
-stringtokey.so stringtokey.po $(OUTPRE)stringtokey.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- dk.h stringtokey.c
+ $(top_srcdir)/include/socket-utils.h dk.h stringtokey.c
diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c
index c963c39..384a5e4 100644
--- a/src/lib/crypto/krb/dk/derive.c
+++ b/src/lib/crypto/krb/dk/derive.c
@@ -79,86 +79,86 @@ cleanup:
return ENOMEM;
}
-/*
- * Compute a derived key into the keyblock outkey. This variation on
- * krb5int_derive_key does not cache the result, as it is only used
- * directly in situations which are not expected to be repeated with
- * the same inkey and constant.
- */
krb5_error_code
-krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
- krb5_key inkey, krb5_keyblock *outkey,
- const krb5_data *in_constant)
+krb5int_derive_random(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant)
{
size_t blocksize, keybytes, n;
- unsigned char *inblockdata = NULL, *outblockdata = NULL, *rawkey = NULL;
- krb5_data inblock, outblock;
+ krb5_crypto_iov iov;
krb5_error_code ret;
blocksize = enc->block_size;
keybytes = enc->keybytes;
- if (inkey->keyblock.length != enc->keylength ||
- outkey->length != enc->keylength)
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
return KRB5_CRYPTO_INTERNAL;
- /* Allocate and set up buffers. */
- inblockdata = k5alloc(blocksize, &ret);
- if (ret)
- goto cleanup;
- outblockdata = k5alloc(blocksize, &ret);
- if (ret)
- goto cleanup;
- rawkey = k5alloc(keybytes, &ret);
+ /* Allocate encryption data buffer. */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ ret = alloc_data(&iov.data, blocksize);
if (ret)
- goto cleanup;
-
- inblock.data = (char *) inblockdata;
- inblock.length = blocksize;
-
- outblock.data = (char *) outblockdata;
- outblock.length = blocksize;
+ return ret;
/* Initialize the input block. */
-
- if (in_constant->length == inblock.length) {
- memcpy(inblock.data, in_constant->data, inblock.length);
+ if (in_constant->length == blocksize) {
+ memcpy(iov.data.data, in_constant->data, blocksize);
} else {
- krb5int_nfold(in_constant->length*8, (unsigned char *) in_constant->data,
- inblock.length*8, (unsigned char *) inblock.data);
+ krb5int_nfold(in_constant->length * 8,
+ (unsigned char *) in_constant->data,
+ blocksize * 8, (unsigned char *) iov.data.data);
}
- /* Loop encrypting the blocks until enough key bytes are generated */
-
+ /* Loop encrypting the blocks until enough key bytes are generated. */
n = 0;
while (n < keybytes) {
- ret = (*enc->encrypt)(inkey, 0, &inblock, &outblock);
+ ret = enc->encrypt(inkey, 0, &iov, 1);
if (ret)
goto cleanup;
- if ((keybytes - n) <= outblock.length) {
- memcpy(rawkey + n, outblock.data, (keybytes - n));
+ if ((keybytes - n) <= blocksize) {
+ memcpy(outrnd->data + n, iov.data.data, (keybytes - n));
break;
}
- memcpy(rawkey+n, outblock.data, outblock.length);
- memcpy(inblock.data, outblock.data, outblock.length);
- n += outblock.length;
+ memcpy(outrnd->data + n, iov.data.data, blocksize);
+ n += blocksize;
}
- /* postprocess the key */
+cleanup:
+ zapfree(iov.data.data, blocksize);
+ return ret;
+}
+
+/*
+ * Compute a derived key into the keyblock outkey. This variation on
+ * krb5int_derive_key does not cache the result, as it is only used
+ * directly in situations which are not expected to be repeated with
+ * the same inkey and constant.
+ */
+krb5_error_code
+krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_keyblock *outkey,
+ const krb5_data *in_constant)
+{
+ krb5_error_code ret;
+ krb5_data rawkey = empty_data();
- inblock.data = (char *) rawkey;
- inblock.length = keybytes;
+ /* Allocate a buffer for the raw key bytes. */
+ ret = alloc_data(&rawkey, enc->keybytes);
+ if (ret)
+ goto cleanup;
- ret = (*enc->make_key)(&inblock, outkey);
+ /* Derive pseudo-random data for the key bytes. */
+ ret = krb5int_derive_random(enc, inkey, &rawkey, in_constant);
if (ret)
goto cleanup;
+ /* Postprocess the key. */
+ ret = enc->make_key(&rawkey, outkey);
+
cleanup:
- zapfree(inblockdata, blocksize);
- zapfree(outblockdata, blocksize);
- zapfree(rawkey, keybytes);
+ zapfree(rawkey.data, enc->keybytes);
return ret;
}
@@ -200,72 +200,3 @@ cleanup:
zapfree(keyblock.contents, keyblock.length);
return ret;
}
-
-krb5_error_code
-krb5int_derive_random(const struct krb5_enc_provider *enc,
- krb5_key inkey, krb5_data *outrnd,
- const krb5_data *in_constant)
-{
- size_t blocksize, keybytes, n;
- unsigned char *inblockdata = NULL, *outblockdata = NULL, *rawkey = NULL;
- krb5_data inblock, outblock;
- krb5_error_code ret;
-
- blocksize = enc->block_size;
- keybytes = enc->keybytes;
-
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
- return KRB5_CRYPTO_INTERNAL;
-
- /* Allocate and set up buffers. */
-
- inblockdata = k5alloc(blocksize, &ret);
- if (ret)
- goto cleanup;
- outblockdata = k5alloc(blocksize, &ret);
- if (ret)
- goto cleanup;
- rawkey = k5alloc(keybytes, &ret);
- if (ret)
- goto cleanup;
-
- inblock.data = (char *) inblockdata;
- inblock.length = blocksize;
-
- outblock.data = (char *) outblockdata;
- outblock.length = blocksize;
-
- /* Initialize the input block. */
- if (in_constant->length == inblock.length) {
- memcpy(inblock.data, in_constant->data, inblock.length);
- } else {
- krb5int_nfold(in_constant->length*8, (unsigned char *) in_constant->data,
- inblock.length*8, (unsigned char *) inblock.data);
- }
-
- /* Loop encrypting the blocks until enough key bytes are generated. */
- n = 0;
- while (n < keybytes) {
- ret = (*enc->encrypt)(inkey, 0, &inblock, &outblock);
- if (ret)
- goto cleanup;
-
- if ((keybytes - n) <= outblock.length) {
- memcpy(rawkey + n, outblock.data, (keybytes - n));
- break;
- }
-
- memcpy(rawkey+n, outblock.data, outblock.length);
- memcpy(inblock.data, outblock.data, outblock.length);
- n += outblock.length;
- }
-
- /* Postprocess the key. */
- memcpy(outrnd->data, rawkey, keybytes);
-
-cleanup:
- zapfree(inblockdata, blocksize);
- zapfree(outblockdata, blocksize);
- zapfree(rawkey, keybytes);
- return ret;
-}
diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h
index 1ac3fbe..892f6b4 100644
--- a/src/lib/crypto/krb/dk/dk.h
+++ b/src/lib/crypto/krb/dk/dk.h
@@ -26,55 +26,35 @@
*/
#include "k5-int.h"
+#include "etypes.h"
-void
-krb5int_dk_encrypt_length(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t input, size_t *length);
+unsigned int
+krb5int_dk_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type);
-krb5_error_code
-krb5int_dk_encrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input, krb5_data *output);
-
-void
-krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t input, size_t *length);
+unsigned int
+krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type);
krb5_error_code
-krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input,
- krb5_data *output);
+krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data);
krb5_error_code
-krb5int_dk_decrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *arg_output);
+krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data);
krb5_error_code
-krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input,
- krb5_data *arg_output);
+krb5int_dk_string_to_key(const struct krb5_keytypes *enc,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *params, krb5_keyblock *key);
krb5_error_code
-krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
- const krb5_data *string,
- const krb5_data *salt,
- const krb5_data *params,
- krb5_keyblock *key);
+krb5int_aes_string_to_key(const struct krb5_keytypes *enc,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *params, krb5_keyblock *key);
krb5_error_code
krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
@@ -105,8 +85,3 @@ krb5_error_code
krb5int_derive_random(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *in_constant);
-
-/* AEAD */
-
-extern const struct krb5_aead_provider krb5int_aead_dk;
-extern const struct krb5_aead_provider krb5int_aead_aes;
diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c
index 1801a73..59c84db 100644
--- a/src/lib/crypto/krb/dk/dk_aead.c
+++ b/src/lib/crypto/krb/dk/dk_aead.c
@@ -34,63 +34,60 @@
/* AEAD */
-static krb5_error_code
-krb5int_dk_crypto_length(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_cryptotype type,
- unsigned int *length)
+unsigned int
+krb5int_dk_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type)
{
switch (type) {
case KRB5_CRYPTO_TYPE_HEADER:
case KRB5_CRYPTO_TYPE_PADDING:
- *length = enc->block_size;
- break;
+ return ktp->enc->block_size;
case KRB5_CRYPTO_TYPE_TRAILER:
case KRB5_CRYPTO_TYPE_CHECKSUM:
- *length = hash->hashsize;
- break;
+ return ktp->hash->hashsize;
default:
assert(0 && "invalid cryptotype passed to krb5int_dk_crypto_length");
- break;
+ return 0;
}
+}
- return 0;
+unsigned int
+krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ return ktp->enc->block_size;
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return 0;
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return 96 / 8;
+ default:
+ assert(0 && "invalid cryptotype passed to krb5int_aes_crypto_length");
+ return 0;
+ }
}
-static krb5_error_code
-krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- krb5_crypto_iov *data,
- size_t num_data)
+krb5_error_code
+krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
krb5_error_code ret;
unsigned char constantdata[K5CLENGTH];
krb5_data d1, d2;
krb5_crypto_iov *header, *trailer, *padding;
krb5_key ke = NULL, ki = NULL;
size_t i;
- unsigned int blocksize = 0;
- unsigned int plainlen = 0;
- unsigned int hmacsize = 0;
- unsigned int padsize = 0;
+ unsigned int blocksize, hmacsize, plainlen = 0, padsize = 0;
unsigned char *cksum = NULL;
/* E(Confounder | Plaintext | Pad) | Checksum */
- ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING,
- &blocksize);
- if (ret != 0)
- return ret;
-
- ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER,
- &hmacsize);
- if (ret != 0)
- return ret;
+ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
+ hmacsize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
for (i = 0; i < num_data; i++) {
krb5_crypto_iov *iov = &data[i];
@@ -164,9 +161,7 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
goto cleanup;
/* Encrypt the plaintext (header | data | padding) */
- assert(enc->encrypt_iov != NULL);
-
- ret = (*enc->encrypt_iov)(ke, ivec, data, num_data); /* updates ivec */
+ ret = enc->encrypt(ke, ivec, data, num_data);
if (ret != 0)
goto cleanup;
@@ -183,38 +178,27 @@ cleanup:
return ret;
}
-static krb5_error_code
-krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- krb5_crypto_iov *data,
- size_t num_data)
+krb5_error_code
+krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
krb5_error_code ret;
unsigned char constantdata[K5CLENGTH];
krb5_data d1;
krb5_crypto_iov *header, *trailer;
krb5_key ke = NULL, ki = NULL;
size_t i;
- unsigned int blocksize = 0; /* enc block size, not confounder len */
- unsigned int cipherlen = 0;
- unsigned int hmacsize = 0;
+ unsigned int blocksize; /* enc block size, not confounder len */
+ unsigned int hmacsize, cipherlen = 0;
unsigned char *cksum = NULL;
/* E(Confounder | Plaintext | Pad) | Checksum */
- ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING,
- &blocksize);
- if (ret != 0)
- return ret;
-
- ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER,
- &hmacsize);
- if (ret != 0)
- return ret;
+ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
+ hmacsize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
if (blocksize != 0) {
/* Check that the input data is correctly padded. */
@@ -262,9 +246,7 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
goto cleanup;
/* Decrypt the plaintext (header | data | padding). */
- assert(enc->decrypt_iov != NULL);
-
- ret = (*enc->decrypt_iov)(ke, ivec, data, num_data); /* updates ivec */
+ ret = enc->decrypt(ke, ivec, data, num_data);
if (ret != 0)
goto cleanup;
@@ -288,41 +270,3 @@ cleanup:
free(cksum);
return ret;
}
-
-const struct krb5_aead_provider krb5int_aead_dk = {
- krb5int_dk_crypto_length,
- krb5int_dk_encrypt_iov,
- krb5int_dk_decrypt_iov
-};
-
-static krb5_error_code
-krb5int_aes_crypto_length(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_cryptotype type,
- unsigned int *length)
-{
- switch (type) {
- case KRB5_CRYPTO_TYPE_HEADER:
- *length = enc->block_size;
- break;
- case KRB5_CRYPTO_TYPE_PADDING:
- *length = 0;
- break;
- case KRB5_CRYPTO_TYPE_TRAILER:
- case KRB5_CRYPTO_TYPE_CHECKSUM:
- *length = 96 / 8;
- break;
- default:
- assert(0 && "invalid cryptotype passed to krb5int_aes_crypto_length");
- break;
- }
-
- return 0;
-}
-
-const struct krb5_aead_provider krb5int_aead_aes = {
- krb5int_aes_crypto_length,
- krb5int_dk_encrypt_iov,
- krb5int_dk_decrypt_iov
-};
diff --git a/src/lib/crypto/krb/dk/dk_decrypt.c b/src/lib/crypto/krb/dk/dk_decrypt.c
deleted file mode 100644
index 4ef7e47..0000000
--- a/src/lib/crypto/krb/dk/dk_decrypt.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "k5-int.h"
-#include "dk.h"
-
-#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
-
-static krb5_error_code
-krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input,
- krb5_data *output,
- size_t hmacsize,
- int ivec_mode);
-
-krb5_error_code
-krb5int_dk_decrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output)
-{
- return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
- ivec, input, output, 0, 0);
-}
-
-krb5_error_code
-krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output)
-{
- return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
- ivec, input, output, 96 / 8, 1);
-}
-
-static krb5_error_code
-krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output, size_t hmacsize,
- int ivec_mode)
-{
- krb5_error_code ret;
- size_t hashsize, blocksize, enclen, plainlen;
- unsigned char *plaindata = NULL, *cksum = NULL, *cn;
- krb5_key ke = NULL, ki = NULL;
- krb5_data d1, d2;
- unsigned char constantdata[K5CLENGTH];
-
- hashsize = hash->hashsize;
- blocksize = enc->block_size;
-
- if (hmacsize == 0)
- hmacsize = hashsize;
- else if (hmacsize > hashsize)
- return KRB5KRB_AP_ERR_BAD_INTEGRITY;
-
- enclen = input->length - hmacsize;
-
- /* Allocate and set up ciphertext and to-be-derived keys. */
- plaindata = k5alloc(enclen, &ret);
- if (ret != 0)
- goto cleanup;
- cksum = k5alloc(hashsize, &ret);
- if (ret != 0)
- goto cleanup;
-
- /* Derive the keys. */
-
- d1.data = (char *) constantdata;
- d1.length = K5CLENGTH;
-
- store_32_be(usage, constantdata);
-
- d1.data[4] = (char) 0xAA;
-
- ret = krb5int_derive_key(enc, key, &ke, &d1);
- if (ret != 0)
- goto cleanup;
-
- d1.data[4] = 0x55;
-
- ret = krb5int_derive_key(enc, key, &ki, &d1);
- if (ret != 0)
- goto cleanup;
-
- /* decrypt the ciphertext */
-
- d1.length = enclen;
- d1.data = input->data;
-
- d2.length = enclen;
- d2.data = (char *) plaindata;
-
- ret = (*enc->decrypt)(ke, ivec, &d1, &d2);
- if (ret != 0)
- goto cleanup;
-
- if (ivec != NULL && ivec->length == blocksize) {
- if (ivec_mode == 0)
- cn = (unsigned char *) d1.data + d1.length - blocksize;
- else if (ivec_mode == 1) {
- int nblocks = (d1.length + blocksize - 1) / blocksize;
- cn = (unsigned char *) d1.data + blocksize * (nblocks - 2);
- } else
- abort();
- } else
- cn = NULL;
-
- /* Verify the hash. */
-
- d1.length = hashsize;
- d1.data = (char *) cksum;
-
- ret = krb5int_hmac(hash, ki, 1, &d2, &d1);
- if (ret != 0)
- goto cleanup;
-
- if (memcmp(cksum, input->data+enclen, hmacsize) != 0) {
- ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- goto cleanup;
- }
-
- /*
- * Because this encoding isn't self-describing wrt length, the
- * best we can do here is to compute the length minus the
- * confounder.
- */
-
- plainlen = enclen - blocksize;
-
- if (output->length < plainlen)
- return KRB5_BAD_MSIZE;
-
- output->length = plainlen;
-
- memcpy(output->data, d2.data+blocksize, output->length);
-
- if (cn != NULL)
- memcpy(ivec->data, cn, blocksize);
-
-cleanup:
- krb5_k_free_key(NULL, ke);
- krb5_k_free_key(NULL, ki);
- zapfree(plaindata, enclen);
- zapfree(cksum, hashsize);
- return ret;
-}
diff --git a/src/lib/crypto/krb/dk/dk_encrypt.c b/src/lib/crypto/krb/dk/dk_encrypt.c
deleted file mode 100644
index 29699d7..0000000
--- a/src/lib/crypto/krb/dk/dk_encrypt.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "k5-int.h"
-#include "dk.h"
-
-#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
-
-/*
- * The spec says that the confounder size and padding are specific to
- * the encryption algorithm. This code (dk_encrypt_length and
- * dk_encrypt) assume the confounder is always the blocksize, and the
- * padding is always zero bytes up to the blocksize. If these
- * assumptions ever fails, the keytype table should be extended to
- * include these bits of info.
- */
-
-void
-krb5int_dk_encrypt_length(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t inputlen, size_t *length)
-{
- size_t blocksize, hashsize;
-
- blocksize = enc->block_size;
- hashsize = hash->hashsize;
- *length = krb5_roundup(blocksize + inputlen, blocksize) + hashsize;
-}
-
-krb5_error_code
-krb5int_dk_encrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output)
-{
- size_t blocksize, plainlen, enclen;
- krb5_error_code ret;
- unsigned char constantdata[K5CLENGTH];
- krb5_data d1, d2;
- unsigned char *plaintext = NULL;
- char *cn;
- krb5_key ke = NULL, ki = NULL;
-
- blocksize = enc->block_size;
- plainlen = krb5_roundup(blocksize + input->length, blocksize);
-
- krb5int_dk_encrypt_length(enc, hash, input->length, &enclen);
-
- /* key->length, ivec will be tested in enc->encrypt. */
-
- if (output->length < enclen)
- return(KRB5_BAD_MSIZE);
-
- /* Allocate and set up plaintext and to-be-derived keys. */
-
- plaintext = malloc(plainlen);
- if (plaintext == NULL)
- return ENOMEM;
-
- /* Derive the keys. */
-
- d1.data = (char *) constantdata;
- d1.length = K5CLENGTH;
-
- store_32_be(usage, constantdata);
-
- d1.data[4] = (char) 0xAA;
-
- ret = krb5int_derive_key(enc, key, &ke, &d1);
- if (ret != 0)
- goto cleanup;
-
- d1.data[4] = 0x55;
-
- ret = krb5int_derive_key(enc, key, &ki, &d1);
- if (ret != 0)
- goto cleanup;
-
- /* Put together the plaintext. */
-
- d1.length = blocksize;
- d1.data = (char *) plaintext;
-
- ret = krb5_c_random_make_octets(/* XXX */ 0, &d1);
- if (ret != 0)
- goto cleanup;
-
- memcpy(plaintext + blocksize, input->data, input->length);
-
- memset(plaintext + blocksize + input->length, 0,
- plainlen - (blocksize + input->length));
-
- /* Encrypt the plaintext. */
-
- d1.length = plainlen;
- d1.data = (char *) plaintext;
-
- d2.length = plainlen;
- d2.data = output->data;
-
- ret = (*enc->encrypt)(ke, ivec, &d1, &d2);
- if (ret != 0)
- goto cleanup;
-
- if (ivec != NULL && ivec->length == blocksize)
- cn = d2.data + d2.length - blocksize;
- else
- cn = NULL;
-
- /* Hash the plaintext. */
-
- d2.length = enclen - plainlen;
- d2.data = output->data+plainlen;
-
- output->length = enclen;
-
- ret = krb5int_hmac(hash, ki, 1, &d1, &d2);
- if (ret != 0) {
- memset(d2.data, 0, d2.length);
- goto cleanup;
- }
-
- /* Update ivec. */
- if (cn != NULL)
- memcpy(ivec->data, cn, blocksize);
-
-cleanup:
- krb5_k_free_key(NULL, ke);
- krb5_k_free_key(NULL, ki);
- zapfree(plaintext, plainlen);
- return ret;
-}
-
-/* Not necessarily "AES", per se, but "a CBC+CTS mode block cipher
- with a 96-bit truncated HMAC". */
-void
-krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t inputlen, size_t *length)
-{
- size_t blocksize, hashsize;
-
- blocksize = enc->block_size;
- hashsize = 96 / 8;
-
- /* No roundup, since CTS requires no padding once we've hit the
- block size. */
- *length = blocksize+inputlen + hashsize;
-}
-
-static krb5_error_code
-trunc_hmac (const struct krb5_hash_provider *hash,
- krb5_key ki, unsigned int num,
- const krb5_data *input, const krb5_data *output)
-{
- size_t hashsize;
- krb5_data tmp;
- krb5_error_code ret;
-
- hashsize = hash->hashsize;
- if (hashsize < output->length)
- return KRB5_CRYPTO_INTERNAL;
- tmp.length = hashsize;
- tmp.data = malloc(hashsize);
- if (tmp.data == NULL)
- return ENOMEM;
- ret = krb5int_hmac(hash, ki, num, input, &tmp);
- if (ret == 0)
- memcpy(output->data, tmp.data, output->length);
- memset(tmp.data, 0, hashsize);
- free(tmp.data);
- return ret;
-}
-
-krb5_error_code
-krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output)
-{
- size_t blocksize, keybytes, plainlen, enclen;
- krb5_error_code ret;
- unsigned char constantdata[K5CLENGTH];
- krb5_data d1, d2;
- unsigned char *plaintext = NULL;
- char *cn;
- krb5_key ke = NULL, ki = NULL;
-
- /* allocate and set up plaintext and to-be-derived keys */
-
- blocksize = enc->block_size;
- keybytes = enc->keybytes;
- plainlen = blocksize+input->length;
-
- krb5int_aes_encrypt_length(enc, hash, input->length, &enclen);
-
- /* key->length, ivec will be tested in enc->encrypt */
-
- if (output->length < enclen)
- return KRB5_BAD_MSIZE;
-
- plaintext = malloc(plainlen);
- if (plaintext == NULL)
- return ENOMEM;
-
- /* Derive the keys. */
-
- d1.data = (char *) constantdata;
- d1.length = K5CLENGTH;
-
- store_32_be(usage, constantdata);
-
- d1.data[4] = (char) 0xAA;
-
- ret = krb5int_derive_key(enc, key, &ke, &d1);
- if (ret != 0)
- goto cleanup;
-
- d1.data[4] = 0x55;
-
- ret = krb5int_derive_key(enc, key, &ki, &d1);
- if (ret != 0)
- goto cleanup;
-
- /* put together the plaintext */
-
- d1.length = blocksize;
- d1.data = (char *) plaintext;
-
- ret = krb5_c_random_make_octets(NULL, &d1);
- if (ret != 0)
- goto cleanup;
-
- memcpy(plaintext + blocksize, input->data, input->length);
-
- /* Ciphertext stealing; there should be no more. */
- if (plainlen != blocksize + input->length)
- abort();
-
- /* Encrypt the plaintext. */
-
- d1.length = plainlen;
- d1.data = (char *) plaintext;
-
- d2.length = plainlen;
- d2.data = output->data;
-
- ret = (*enc->encrypt)(ke, ivec, &d1, &d2);
- if (ret != 0)
- goto cleanup;
-
- if (ivec != NULL && ivec->length == blocksize) {
- int nblocks = (d2.length + blocksize - 1) / blocksize;
- cn = d2.data + blocksize * (nblocks - 2);
- } else
- cn = NULL;
-
- /* Hash the plaintext. */
-
- d2.length = enclen - plainlen;
- d2.data = output->data+plainlen;
- if (d2.length != 96 / 8)
- abort();
-
- ret = trunc_hmac(hash, ki, 1, &d1, &d2);
- if (ret != 0) {
- memset(d2.data, 0, d2.length);
- goto cleanup;
- }
-
- output->length = enclen;
-
- /* Update ivec. */
- if (cn != NULL)
- memcpy(ivec->data, cn, blocksize);
-
-cleanup:
- krb5_k_free_key(NULL, ke);
- krb5_k_free_key(NULL, ki);
- zapfree(plaintext, plainlen);
- return ret;
-}
diff --git a/src/lib/crypto/krb/dk/stringtokey.c b/src/lib/crypto/krb/dk/stringtokey.c
index ff436e6..9a49187 100644
--- a/src/lib/crypto/krb/dk/stringtokey.c
+++ b/src/lib/crypto/krb/dk/stringtokey.c
@@ -31,10 +31,11 @@ static const unsigned char kerberos[] = "kerberos";
#define kerberos_len (sizeof(kerberos)-1)
krb5_error_code
-krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
+krb5int_dk_string_to_key(const struct krb5_keytypes *ktp,
const krb5_data *string, const krb5_data *salt,
const krb5_data *parms, krb5_keyblock *keyblock)
{
+ const struct krb5_enc_provider *enc = ktp->enc;
krb5_error_code ret;
size_t keybytes, keylength, concatlen;
unsigned char *concat = NULL, *foldstring = NULL, *foldkeydata = NULL;
@@ -72,7 +73,7 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc,
foldkeyblock.length = keylength;
foldkeyblock.contents = foldkeydata;
- ret = (*enc->make_key)(&indata, &foldkeyblock);
+ ret = enc->make_key(&indata, &foldkeyblock);
if (ret != 0)
goto cleanup;
@@ -96,3 +97,63 @@ cleanup:
krb5_k_free_key(NULL, foldkey);
return ret;
}
+
+
+#define DEFAULT_ITERATION_COUNT 4096 /* was 0xb000L in earlier drafts */
+#define MAX_ITERATION_COUNT 0x1000000L
+
+krb5_error_code
+krb5int_aes_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key)
+{
+ unsigned long iter_count;
+ krb5_data out;
+ static const krb5_data usage = { KV5M_DATA, 8, "kerberos" };
+ krb5_key tempkey = NULL;
+ krb5_error_code err;
+
+ if (params) {
+ unsigned char *p = (unsigned char *) params->data;
+ if (params->length != 4)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ /* The first two need casts in case 'int' is 16 bits. */
+ iter_count = load_32_be(p);
+ if (iter_count == 0) {
+ iter_count = (1UL << 16) << 16;
+ if (((iter_count >> 16) >> 16) != 1)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ }
+ } else
+ iter_count = DEFAULT_ITERATION_COUNT;
+
+ /* This is not a protocol specification constraint; this is an
+ implementation limit, which should eventually be controlled by
+ a config file. */
+ if (iter_count >= MAX_ITERATION_COUNT)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+
+ /* Use the output keyblock contents for temporary space. */
+ out.data = (char *) key->contents;
+ out.length = key->length;
+ if (out.length != 16 && out.length != 32)
+ return KRB5_CRYPTO_INTERNAL;
+
+ err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt);
+ if (err)
+ goto cleanup;
+
+ err = krb5_k_create_key (NULL, key, &tempkey);
+ if (err)
+ goto cleanup;
+
+ err = krb5int_derive_keyblock(ktp->enc, tempkey, key, &usage);
+
+cleanup:
+ if (err)
+ memset (out.data, 0, out.length);
+ krb5_k_free_key (NULL, tempkey);
+ return err;
+}