diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/crypto/dk/ChangeLog | 3 | ||||
| -rw-r--r-- | src/lib/crypto/dk/derive.c | 103 |
2 files changed, 106 insertions, 0 deletions
diff --git a/src/lib/crypto/dk/ChangeLog b/src/lib/crypto/dk/ChangeLog index 6ae4da7c1..63cbd02e6 100644 --- a/src/lib/crypto/dk/ChangeLog +++ b/src/lib/crypto/dk/ChangeLog @@ -1,5 +1,8 @@ 2001-06-21 Ken Raeburn <raeburn@mit.edu> + * derive.c: Include etypes.h. + (krb5_derive_random, krb5_random2key): New functions. + * checksum.c (krb5_dk_make_checksum): Cast 0x99 to char explicitly to silence warnings. diff --git a/src/lib/crypto/dk/derive.c b/src/lib/crypto/dk/derive.c index 8129ae8aa..0aabdc4ed 100644 --- a/src/lib/crypto/dk/derive.c +++ b/src/lib/crypto/dk/derive.c @@ -112,3 +112,106 @@ krb5_derive_key(enc, inkey, outkey, in_constant) return(0); } + +krb5_error_code +krb5_derive_random(enc, inkey, outrnd, in_constant) + const struct krb5_enc_provider *enc; + const krb5_keyblock *inkey; + krb5_data *outrnd; + 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) || + (outrnd->length != keybytes)) + 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) { + free(inblockdata); + return(ENOMEM); + } + + if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { + free(outblockdata); + free(inblockdata); + return(ENOMEM); + } + + 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 */ + + memcpy (outrnd->data, rawkey, keybytes); + + /* 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); +} + +#include "etypes.h" +void +krb5_random2key (krb5_enctype enctype, krb5_data *inblock, + krb5_keyblock *outkey) +{ + int i; + const struct krb5_enc_provider *enc; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + abort (); + + enc = krb5_enctypes_list[i].enc; + + enc->make_key (inblock, outkey); +} |
