diff options
author | Tom Yu <tlyu@mit.edu> | 1998-11-02 20:40:55 +0000 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 1998-11-02 20:40:55 +0000 |
commit | 29e7d86639c0f939b3b0f84286a3ea2d551a976a (patch) | |
tree | a7b6bced99c4d04279e5ad833c175eed7a8744bf /src/lib/crypto/dk | |
parent | 4f48a6df86ec7a84e2dc2bedb0966d06a00bdd64 (diff) | |
download | krb5-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.in | 44 | ||||
-rw-r--r-- | src/lib/crypto/dk/checksum.c | 104 | ||||
-rw-r--r-- | src/lib/crypto/dk/decrypt.c | 151 | ||||
-rw-r--r-- | src/lib/crypto/dk/derive.c | 114 | ||||
-rw-r--r-- | src/lib/crypto/dk/dk.h | 61 | ||||
-rw-r--r-- | src/lib/crypto/dk/encrypt.c | 167 | ||||
-rw-r--r-- | src/lib/crypto/dk/stringtokey.c | 97 |
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); +} |