Somehow I missed this file during my previous checkin... New 3des random
authorRichard Basch <probe@mit.edu>
Tue, 7 May 1996 23:06:19 +0000 (23:06 +0000)
committerRichard Basch <probe@mit.edu>
Tue, 7 May 1996 23:06:19 +0000 (23:06 +0000)
function support

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7920 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/crypto/des/init_rkey.c

index 883271e82478f63bd5f84bc8a15e9a503a216938..2cb85215f9dc631eb5f72dc210e57e60d572763b 100644 (file)
         sequence information.
  */
 
+#ifndef min
+#define min(a,b) (((a) > (b)) ? (b) : (a))
+#endif
+
 krb5_error_code
-mit_des_init_random_key (seedblock, seed)
+mit_des_init_random_key (eblock, seedblock, state)
+    const krb5_encrypt_block * eblock;
     const krb5_keyblock * seedblock;
-    krb5_pointer * seed;
+    krb5_pointer * state;
 {
-    mit_des_random_key_seed * p_seed;
-    if ((seedblock->enctype != ENCTYPE_DES_CBC_CRC) &&
-       (seedblock->enctype != ENCTYPE_DES_CBC_MD4) && 
-       (seedblock->enctype != ENCTYPE_DES_CBC_MD5) && 
-       (seedblock->enctype != ENCTYPE_DES_CBC_RAW) &&
-       (seedblock->enctype != ENCTYPE_DES3_CBC_MD5) && 
-       (seedblock->enctype != ENCTYPE_DES3_CBC_RAW))
+    mit_des_random_state * p_state = 0;
+    krb5_keyblock *new_key;
+    krb5_enctype enctype = eblock->crypto_entry->proto_enctype;
+    krb5_error_code kret = 0;
+    krb5_address **addrs = 0;
+    krb5_data seed;
+    struct tval {
+       krb5_int32 seconds;
+       krb5_int32 microseconds;
+    } timenow;
+
+    switch (enctype)
+    {
+    case ENCTYPE_DES_CBC_CRC:
+    case ENCTYPE_DES_CBC_MD4:
+    case ENCTYPE_DES_CBC_MD5:
+    case ENCTYPE_DES_CBC_RAW:
+       enctype = ENCTYPE_DES_CBC_RAW;
+       break;
+
+    case ENCTYPE_DES3_CBC_MD5:
+    case ENCTYPE_DES3_CBC_RAW:
+       enctype = ENCTYPE_DES3_CBC_RAW;
+       break;
+
+    default:
        return KRB5_BAD_ENCTYPE;
-    if ( !(p_seed = (mit_des_random_key_seed *) 
-          malloc(sizeof(mit_des_random_key_seed))) ) 
-       return ENOMEM;
-    memset((char *)p_seed, 0, sizeof(mit_des_random_key_seed) );
-    mit_des_init_random_number_generator(seedblock->contents, p_seed);
-    *seed = (krb5_pointer) p_seed;
+    }
+
+    p_state = (mit_des_random_state *) malloc(sizeof(mit_des_random_state));
+    *state = (krb5_pointer) p_state;
+
+    if (! p_state) {
+       kret = ENOMEM;
+       goto cleanup;
+    }
+
+    memset(p_state, 0, sizeof(*p_state));
+    p_state->eblock.crypto_entry = krb5_enctype_array[enctype]->system;
+    p_state->sequence.length = p_state->eblock.crypto_entry->keysize;
+    p_state->sequence.data = (krb5_pointer) malloc(p_state->sequence.length);
+
+    if (! p_state->sequence.data) {
+       kret = ENOMEM;
+       goto cleanup;
+    }
+
+    /*
+     * Generate a temporary value that is based on the
+     * input seed and the hostid (sequence number)
+     * such that it gives no useful information about the input.
+     *
+     * Then use the temporary value as the new seed and the current
+     * time as a sequence number to give us a stream that was not
+     * previously used.
+     *
+     * This result will be the seed for the random number stream
+     * (the sequence number will start at zero).
+     */
+
+    /* seed = input */
+    seed.data = seedblock->contents;
+    seed.length = seedblock->length;
+    kret = mit_des_set_random_generator_seed(&seed, p_state);
+    if (kret) goto cleanup;
+
+    /* sequence = hostid */
+    if (!krb5_crypto_os_localaddr(&addrs) && addrs && *addrs) {
+       memcpy((char *)p_state->sequence.data, (char *)addrs[0]->contents,
+             min(p_state->sequence.length, addrs[0]->length));
+       /* XXX may not do all of the sequence number. */
+    }
+    if (addrs) {
+       /* can't use krb5_free_addresses due to circular dependencies in
+          libraries */
+       register krb5_address **addr2;
+       for (addr2 = addrs; *addr2; addr2++) {
+           krb5_xfree((*addr2)->contents);
+           krb5_xfree(*addr2);
+       }
+       krb5_xfree(addrs);
+    }
+
+    /* tmp.seed = random(input,hostid) */
+    kret = mit_des_random_key(NULL, p_state, &new_key);
+    if (kret) goto cleanup;
+    seed.data = new_key->contents;
+    seed.length = new_key->length;
+    kret = mit_des_set_random_generator_seed(&seed, p_state);
+    (void) memset(new_key->contents, 0, new_key->length);
+    krb5_xfree(new_key->contents);
+    krb5_xfree(new_key);
+    if (kret) goto cleanup;
+
+    /* sequence = time */
+    (void) krb5_crypto_us_timeofday(&timenow.seconds,
+                                   &timenow.microseconds);
+    memcpy((char *)p_state->sequence.data, (char *)&timenow, sizeof(timenow));
+
+    /* seed = random(tmp.seed, time) */
+    kret = mit_des_random_key(NULL, p_state, &new_key);
+    if (kret) goto cleanup;
+    seed.data = new_key->contents;
+    seed.length = new_key->length;
+    kret = mit_des_set_random_generator_seed(&seed, p_state);
+    (void) memset(new_key->contents, 0, new_key->length);
+    krb5_xfree(new_key->contents);
+    krb5_xfree(new_key);
+    if (kret) goto cleanup;
+    
     return 0;
+
+cleanup:
+    if (kret)
+       mit_des_finish_random_key(eblock, state);
+    return kret;
 }