summaryrefslogtreecommitdiffstats
path: root/src/lib/crypto/dk
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>1998-11-02 20:40:55 +0000
committerTom Yu <tlyu@mit.edu>1998-11-02 20:40:55 +0000
commit29e7d86639c0f939b3b0f84286a3ea2d551a976a (patch)
treea7b6bced99c4d04279e5ad833c175eed7a8744bf /src/lib/crypto/dk
parent4f48a6df86ec7a84e2dc2bedb0966d06a00bdd64 (diff)
downloadkrb5-29e7d86639c0f939b3b0f84286a3ea2d551a976a.tar.gz
krb5-29e7d86639c0f939b3b0f84286a3ea2d551a976a.tar.xz
krb5-29e7d86639c0f939b3b0f84286a3ea2d551a976a.zip
ressurect files missed by merge
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11006 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto/dk')
-rw-r--r--src/lib/crypto/dk/Makefile.in44
-rw-r--r--src/lib/crypto/dk/checksum.c104
-rw-r--r--src/lib/crypto/dk/decrypt.c151
-rw-r--r--src/lib/crypto/dk/derive.c114
-rw-r--r--src/lib/crypto/dk/dk.h61
-rw-r--r--src/lib/crypto/dk/encrypt.c167
-rw-r--r--src/lib/crypto/dk/stringtokey.c97
7 files changed, 738 insertions, 0 deletions
diff --git a/src/lib/crypto/dk/Makefile.in b/src/lib/crypto/dk/Makefile.in
new file mode 100644
index 0000000000..076b0dd66e
--- /dev/null
+++ b/src/lib/crypto/dk/Makefile.in
@@ -0,0 +1,44 @@
+thisconfigdir=./..
+BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)
+CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/..
+
+##DOS##BUILDTOP = ..\..\..
+##DOS##PREFIXDIR=dk
+##DOS##OBJFILE=..\dk.lst
+##WIN16##LIBNAME=..\crypto.lib
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf
+
+STLIBOBJS=\
+ checksum.o \
+ decrypt.o \
+ derive.o \
+ encrypt.o \
+ stringtokey.o
+
+OBJS=\
+ checksum.$(OBJEXT) \
+ decrypt.$(OBJEXT) \
+ derive.$(OBJEXT) \
+ encrypt.$(OBJEXT) \
+ stringtokey.$(OBJEXT)
+
+SRCS=\
+ $(srcdir)/checksum.c \
+ $(srcdir)/decrypt.c \
+ $(srcdir)/derive.c \
+ $(srcdir)/encrypt.c \
+ $(srcdir)/stringtokey.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix:: all-libobjs
+
+includes:: depend
+
+depend:: $(SRCS)
+
+clean-unix:: clean-libobjs
diff --git a/src/lib/crypto/dk/checksum.c b/src/lib/crypto/dk/checksum.c
new file mode 100644
index 0000000000..db64e6cb65
--- /dev/null
+++ b/src/lib/crypto/dk/checksum.c
@@ -0,0 +1,104 @@
+/*
+ * 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 "etypes.h"
+#include "dk.h"
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+krb5_error_code
+krb5_dk_make_checksum(hash, key, usage, input, output)
+ krb5_const struct krb5_hash_provider *hash;
+ krb5_const krb5_keyblock *key;
+ krb5_keyusage usage;
+ krb5_const krb5_data *input;
+ krb5_data *output;
+{
+ int i;
+ struct krb5_enc_provider *enc;
+ size_t blocksize, keybytes, keylength;
+ krb5_error_code ret;
+ unsigned char constantdata[K5CLENGTH];
+ krb5_data datain;
+ unsigned char *kcdata;
+ krb5_keyblock kc;
+
+ for (i=0; i<krb5_enctypes_length; i++) {
+ if (krb5_enctypes_list[i].etype == key->enctype)
+ break;
+ }
+
+ if (i == krb5_enctypes_length)
+ return(KRB5_BAD_ENCTYPE);
+
+ enc = krb5_enctypes_list[i].enc;
+
+ /* allocate and set to-be-derived keys */
+
+ (*(enc->block_size))(&blocksize);
+ (*(enc->keysize))(&keybytes, &keylength);
+
+ /* key->length will be tested in enc->encrypt
+ output->length will be tested in krb5_hmac */
+
+ if ((kcdata = (unsigned char *) malloc(keylength)) == NULL)
+ return(ENOMEM);
+
+ kc.contents = kcdata;
+ kc.length = keylength;
+
+ /* derive the key */
+
+ datain.data = constantdata;
+ datain.length = K5CLENGTH;
+
+ datain.data[0] = (usage>>24)&0xff;
+ datain.data[1] = (usage>>16)&0xff;
+ datain.data[2] = (usage>>8)&0xff;
+ datain.data[3] = usage&0xff;
+
+ datain.data[4] = 0x99;
+
+ if (ret = krb5_derive_key(enc, key, &kc, &datain))
+ goto cleanup;
+
+ /* hash the data */
+
+ datain = *input;
+
+ if (ret = krb5_hmac(hash, &kc, 1, &datain, output))
+ memset(output->data, 0, output->length);
+
+ /* ret is set correctly by the prior call */
+
+cleanup:
+ memset(kcdata, 0, keylength);
+
+ free(kcdata);
+
+ return(ret);
+}
diff --git a/src/lib/crypto/dk/decrypt.c b/src/lib/crypto/dk/decrypt.c
new file mode 100644
index 0000000000..9fedffbc09
--- /dev/null
+++ b/src/lib/crypto/dk/decrypt.c
@@ -0,0 +1,151 @@
+/*
+ * 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 */
+
+krb5_error_code
+krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
+ krb5_const struct krb5_enc_provider *enc;
+ krb5_const struct krb5_hash_provider *hash;
+ krb5_const krb5_keyblock *key;
+ krb5_keyusage usage;
+ krb5_const krb5_data *ivec;
+ krb5_const krb5_data *input;
+ krb5_data *output;
+{
+ krb5_error_code ret;
+ size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
+ unsigned char *plaindata, *kedata, *kidata, *cksum;
+ krb5_keyblock ke, ki;
+ krb5_data d1, d2;
+ unsigned char constantdata[K5CLENGTH];
+
+ /* allocate and set up ciphertext and to-be-derived keys */
+
+ (*(hash->hash_size))(&hashsize);
+ (*(enc->block_size))(&blocksize);
+ (*(enc->keysize))(&keybytes, &keylength);
+
+ enclen = input->length - hashsize;
+
+ if ((kedata = (unsigned char *) malloc(keylength)) == NULL)
+ return(ENOMEM);
+ if ((kidata = (unsigned char *) malloc(keylength)) == NULL) {
+ free(kedata);
+ return(ENOMEM);
+ }
+ if ((plaindata = (unsigned char *) malloc(enclen)) == NULL) {
+ free(kidata);
+ free(kedata);
+ return(ENOMEM);
+ }
+ if ((cksum = (unsigned char *) malloc(hashsize)) == NULL) {
+ free(plaindata);
+ free(kidata);
+ free(kedata);
+ return(ENOMEM);
+ }
+
+ ke.contents = kedata;
+ ke.length = keylength;
+ ki.contents = kidata;
+ ki.length = keylength;
+
+ /* derive the keys */
+
+ d1.data = constantdata;
+ d1.length = K5CLENGTH;
+
+ d1.data[0] = (usage>>24)&0xff;
+ d1.data[1] = (usage>>16)&0xff;
+ d1.data[2] = (usage>>8)&0xff;
+ d1.data[3] = usage&0xff;
+
+ d1.data[4] = 0xAA;
+
+ if (ret = krb5_derive_key(enc, key, &ke, &d1))
+ goto cleanup;
+
+ d1.data[4] = 0x55;
+
+ if (ret = krb5_derive_key(enc, key, &ki, &d1))
+ goto cleanup;
+
+ /* decrypt the ciphertext */
+
+ d1.length = enclen;
+ d1.data = input->data;
+
+ d2.length = enclen;
+ d2.data = plaindata;
+
+ if (ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2)))
+ goto cleanup;
+
+ /* verify the hash */
+
+ d1.length = hashsize;
+ d1.data = cksum;
+
+ if (ret = krb5_hmac(hash, &ki, 1, &d2, &d1))
+ goto cleanup;
+
+ if (memcmp(cksum, input->data+enclen, hashsize) != 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);
+
+ ret = 0;
+
+cleanup:
+ memset(kedata, 0, keylength);
+ memset(kidata, 0, keylength);
+ memset(plaindata, 0, enclen);
+ memset(cksum, 0, hashsize);
+
+ free(cksum);
+ free(plaindata);
+ free(kidata);
+ free(kedata);
+
+ return(ret);
+}
diff --git a/src/lib/crypto/dk/derive.c b/src/lib/crypto/dk/derive.c
new file mode 100644
index 0000000000..8765605fbc
--- /dev/null
+++ b/src/lib/crypto/dk/derive.c
@@ -0,0 +1,114 @@
+/*
+ * 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"
+
+krb5_error_code
+krb5_derive_key(enc, inkey, outkey, in_constant)
+ krb5_const struct krb5_enc_provider *enc;
+ krb5_const krb5_keyblock *inkey;
+ krb5_keyblock *outkey;
+ krb5_const krb5_data *in_constant;
+{
+ size_t blocksize, keybytes, keylength, n;
+ unsigned char *inblockdata, *outblockdata, *rawkey;
+ krb5_data inblock, outblock;
+
+ (*(enc->block_size))(&blocksize);
+ (*(enc->keysize))(&keybytes, &keylength);
+
+ if ((inkey->length != keylength) ||
+ (outkey->length != keylength))
+ return(KRB5_CRYPTO_INTERNAL);
+
+ /* allocate and set up buffers */
+
+ if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL)
+ return(ENOMEM);
+
+ if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) {
+ return(ENOMEM);
+ free(inblockdata);
+ }
+
+ if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) {
+ return(ENOMEM);
+ free(outblockdata);
+ free(inblockdata);
+ }
+
+ inblock.data = inblockdata;
+ inblock.length = blocksize;
+
+ outblock.data = outblockdata;
+ outblock.length = blocksize;
+
+ /* initialize the input block */
+
+ if (in_constant->length == inblock.length) {
+ memcpy(inblock.data, in_constant->data, inblock.length);
+ } else {
+ krb5_nfold(in_constant->length*8, in_constant->data,
+ inblock.length*8, inblock.data);
+ }
+
+ /* loop encrypting the blocks until enough key bytes are generated */
+
+ n = 0;
+ while (n < keybytes) {
+ (*(enc->encrypt))(inkey, 0, &inblock, &outblock);
+
+ 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 */
+
+ inblock.data = rawkey;
+ inblock.length = keybytes;
+
+ (*(enc->make_key))(&inblock, outkey);
+
+ /* clean memory, free resources and exit */
+
+ memset(inblockdata, 0, blocksize);
+ memset(outblockdata, 0, blocksize);
+ memset(rawkey, 0, keybytes);
+
+ free(rawkey);
+ free(outblockdata);
+ free(inblockdata);
+
+ return(0);
+}
+
diff --git a/src/lib/crypto/dk/dk.h b/src/lib/crypto/dk/dk.h
new file mode 100644
index 0000000000..e4acddabc0
--- /dev/null
+++ b/src/lib/crypto/dk/dk.h
@@ -0,0 +1,61 @@
+/*
+ * 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"
+
+void krb5_dk_encrypt_length
+KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc,
+ krb5_const struct krb5_hash_provider *hash,
+ size_t input, size_t *length));
+
+krb5_error_code krb5_dk_encrypt
+KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc,
+ krb5_const struct krb5_hash_provider *hash,
+ krb5_const krb5_keyblock *key, krb5_keyusage usage,
+ krb5_const krb5_data *ivec,
+ krb5_const krb5_data *input, krb5_data *output));
+
+krb5_error_code krb5_dk_decrypt
+KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc,
+ krb5_const struct krb5_hash_provider *hash,
+ krb5_const krb5_keyblock *key, krb5_keyusage usage,
+ krb5_const krb5_data *ivec, krb5_const krb5_data *input,
+ krb5_data *arg_output));
+
+krb5_error_code krb5_dk_string_to_key
+KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc,
+ krb5_const krb5_data *string, krb5_const krb5_data *salt,
+ krb5_keyblock *key));
+
+krb5_error_code krb5_derive_key
+KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc,
+ krb5_const krb5_keyblock *inkey,
+ krb5_keyblock *outkey, krb5_const krb5_data *in_constant));
+
+krb5_error_code krb5_dk_make_checksum
+KRB5_PROTOTYPE((krb5_const struct krb5_hash_provider *hash,
+ krb5_const krb5_keyblock *key, krb5_keyusage usage,
+ krb5_const krb5_data *input, krb5_data *output));
diff --git a/src/lib/crypto/dk/encrypt.c b/src/lib/crypto/dk/encrypt.c
new file mode 100644
index 0000000000..4a3a00b300
--- /dev/null
+++ b/src/lib/crypto/dk/encrypt.c
@@ -0,0 +1,167 @@
+/*
+ * 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
+krb5_dk_encrypt_length(enc, hash, inputlen, length)
+ krb5_const struct krb5_enc_provider *enc;
+ krb5_const struct krb5_hash_provider *hash;
+ size_t inputlen;
+ size_t *length;
+{
+ size_t blocksize, hashsize;
+
+ (*(enc->block_size))(&blocksize);
+ (*(hash->hash_size))(&hashsize);
+
+ *length = krb5_roundup(blocksize+inputlen, blocksize) + hashsize;
+}
+
+krb5_error_code
+krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
+ krb5_const struct krb5_enc_provider *enc;
+ krb5_const struct krb5_hash_provider *hash;
+ krb5_const krb5_keyblock *key;
+ krb5_keyusage usage;
+ krb5_const krb5_data *ivec;
+ krb5_const krb5_data *input;
+ krb5_data *output;
+{
+ size_t blocksize, keybytes, keylength, plainlen, enclen;
+ krb5_error_code ret;
+ unsigned char constantdata[K5CLENGTH];
+ krb5_data d1, d2;
+ unsigned char *plaintext, *kedata, *kidata;
+ krb5_keyblock ke, ki;
+
+ /* allocate and set up plaintext and to-be-derived keys */
+
+ (*(enc->block_size))(&blocksize);
+ (*(enc->keysize))(&keybytes, &keylength);
+ plainlen = krb5_roundup(blocksize+input->length, blocksize);
+
+ krb5_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);
+
+ if ((kedata = (unsigned char *) malloc(keylength)) == NULL)
+ return(ENOMEM);
+ if ((kidata = (unsigned char *) malloc(keylength)) == NULL) {
+ free(kedata);
+ return(ENOMEM);
+ }
+ if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) {
+ free(kidata);
+ free(kedata);
+ return(ENOMEM);
+ }
+
+ ke.contents = kedata;
+ ke.length = keylength;
+ ki.contents = kidata;
+ ki.length = keylength;
+
+ /* derive the keys */
+
+ d1.data = constantdata;
+ d1.length = K5CLENGTH;
+
+ d1.data[0] = (usage>>24)&0xff;
+ d1.data[1] = (usage>>16)&0xff;
+ d1.data[2] = (usage>>8)&0xff;
+ d1.data[3] = usage&0xff;
+
+ d1.data[4] = 0xAA;
+
+ if (ret = krb5_derive_key(enc, key, &ke, &d1))
+ goto cleanup;
+
+ d1.data[4] = 0x55;
+
+ if (ret = krb5_derive_key(enc, key, &ki, &d1))
+ goto cleanup;
+
+ /* put together the plaintext */
+
+ d1.length = blocksize;
+ d1.data = plaintext;
+
+ if (ret = krb5_c_random_make_octets(/* XXX */ 0, &d1))
+ 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 = plaintext;
+
+ d2.length = plainlen;
+ d2.data = output->data;
+
+ if (ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))
+ goto cleanup;
+
+ /* hash the plaintext */
+
+ d2.length = enclen - plainlen;
+ d2.data = output->data+plainlen;
+
+ output->length = enclen;
+
+ if (ret = krb5_hmac(hash, &ki, 1, &d1, &d2))
+ memset(d2.data, 0, d2.length);
+
+ /* ret is set correctly by the prior call */
+
+cleanup:
+ memset(kedata, 0, keylength);
+ memset(kidata, 0, keylength);
+ memset(plaintext, 0, plainlen);
+
+ free(plaintext);
+ free(kidata);
+ free(kedata);
+
+ return(ret);
+}
diff --git a/src/lib/crypto/dk/stringtokey.c b/src/lib/crypto/dk/stringtokey.c
new file mode 100644
index 0000000000..c033dc35a7
--- /dev/null
+++ b/src/lib/crypto/dk/stringtokey.c
@@ -0,0 +1,97 @@
+/*
+ * 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"
+
+static unsigned char kerberos[] = "kerberos";
+#define kerberos_len (sizeof(kerberos)-1)
+
+krb5_error_code
+krb5_dk_string_to_key(enc, string, salt, key)
+ krb5_const struct krb5_enc_provider *enc;
+ krb5_const krb5_data *string;
+ krb5_const krb5_data *salt;
+ krb5_keyblock *key;
+{
+ krb5_error_code ret;
+ size_t keybytes, keylength, concatlen;
+ unsigned char *concat, *foldstring, *foldkeydata;
+ krb5_data indata;
+ krb5_keyblock foldkey;
+
+ /* key->length is checked by krb5_derive_key */
+
+ (*(enc->keysize))(&keybytes, &keylength);
+
+ concatlen = string->length+(salt?salt->length:0);
+
+ if ((concat = (unsigned char *) malloc(concatlen)) == NULL)
+ return(ENOMEM);
+ if ((foldstring = (unsigned char *) malloc(keybytes)) == NULL) {
+ free(concat);
+ return(ENOMEM);
+ }
+ if ((foldkeydata = (unsigned char *) malloc(keylength)) == NULL) {
+ free(foldstring);
+ free(concat);
+ return(ENOMEM);
+ }
+
+ /* construct input string ( = string + salt), fold it, make_key it */
+
+ memcpy(concat, string->data, string->length);
+ if (salt)
+ memcpy(concat+string->length, salt->data, salt->length);
+
+ krb5_nfold(concatlen*8, concat, keybytes*8, foldstring);
+
+ indata.length = keybytes;
+ indata.data = foldstring;
+ foldkey.length = keylength;
+ foldkey.contents = foldkeydata;
+
+ (*(enc->make_key))(&indata, &foldkey);
+
+ /* now derive the key from this one */
+
+ indata.length = kerberos_len;
+ indata.data = kerberos;
+
+ if (ret = krb5_derive_key(enc, &foldkey, key, &indata))
+ memset(key->contents, 0, key->length);
+
+ /* ret is set correctly by the prior call */
+
+ memset(concat, 0, concatlen);
+ memset(foldstring, 0, keybytes);
+ memset(foldkeydata, 0, keylength);
+
+ free(foldkeydata);
+ free(foldstring);
+ free(concat);
+
+ return(ret);
+}