* derive.c: provide krb5_derive_random, krb5_random2key a la rfc1510bis (not exported...
authorKen Raeburn <raeburn@mit.edu>
Fri, 22 Jun 2001 03:22:27 +0000 (03:22 +0000)
committerKen Raeburn <raeburn@mit.edu>
Fri, 22 Jun 2001 03:22:27 +0000 (03:22 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13474 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/crypto/dk/ChangeLog
src/lib/crypto/dk/derive.c

index 6ae4da7c1230b0c5fe9cb8de468390cc4f7bcc2a..63cbd02e65c432468d9e9aeca90cf42a909c5742 100644 (file)
@@ -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.
 
index 8129ae8aae640c0b253a370c62e4b2cdd61fb59f..0aabdc4ed4a9e3dd6bbf50d70dc600acc296c7ff 100644 (file)
@@ -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);
+}