home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / kerberosIV / des / new_rnd_key.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-25  |  6.1 KB  |  211 lines

  1. /*
  2.  * $Source: /usr/src/kerberosIV/des/RCS/new_rnd_key.c,v $
  3.  * $Author: bostic $
  4.  *
  5.  * Copyright 1988 by the Massachusetts Institute of Technology.
  6.  *
  7.  * For copying and distribution information, please see the file
  8.  * <mit-copyright.h>.
  9.  *
  10.  * New pseudo-random key generator, using DES encryption to make the
  11.  * pseudo-random cycle as hard to break as DES.
  12.  *
  13.  * Written by Mark Lillibridge, MIT Project Athena
  14.  *
  15.  * Under U.S. law, this software may not be exported outside the US
  16.  * without license from the U.S. Commerce department.
  17.  */
  18.  
  19. #ifndef    lint
  20. static char rcsid_new_rnd_key_c[] =
  21. "$Header: /usr/src/kerberosIV/des/RCS/new_rnd_key.c,v 4.2 91/02/25 15:14:22 bostic Exp $";
  22. #endif    lint
  23.  
  24. #include <mit-copyright.h>
  25.  
  26. #include <des.h>
  27. #include "des_internal.h"
  28.  
  29. extern void des_fixup_key_parity();
  30. extern int des_is_weak_key();
  31.  
  32. void des_set_random_generator_seed(), des_set_sequence_number();
  33. void des_generate_random_block();
  34.  
  35. /*
  36.  * des_new_random_key: create a random des key
  37.  *
  38.  * Requires: des_set_random_number_generater_seed must be at called least
  39.  *           once before this routine is called.
  40.  *
  41.  * Notes: the returned key has correct parity and is guarenteed not
  42.  *        to be a weak des key.  Des_generate_random_block is used to
  43.  *        provide the random bits.
  44.  */
  45. int
  46. des_new_random_key(key)
  47.      des_cblock key;
  48. {
  49.     do {
  50.     des_generate_random_block(key);
  51.     des_fixup_key_parity(key);
  52.     } while (des_is_weak_key(key));
  53.  
  54.     return(0);
  55. }
  56.  
  57. /*
  58.  * des_init_random_number_generator:
  59.  *
  60.  *    This routine takes a secret key possibly shared by a number
  61.  * of servers and uses it to generate a random number stream that is
  62.  * not shared by any of the other servers.  It does this by using the current
  63.  * process id, host id, and the current time to the nearest second.  The
  64.  * resulting stream seed is not useful information for cracking the secret
  65.  * key.   Moreover, this routine keeps no copy of the secret key.
  66.  * This routine is used for example, by the kerberos server(s) with the
  67.  * key in question being the kerberos master key.
  68.  *
  69.  * Note: this routine calls des_set_random_generator_seed.
  70.  */
  71. #ifndef BSDUNIX
  72.   you lose...   (aka, you get to implement an analog of this for your
  73.          system...)
  74. #else
  75.  
  76. #include <sys/time.h>
  77.  
  78. void des_init_random_number_generator(key)
  79.      des_cblock key;
  80. {
  81.     struct { /* This must be 64 bits exactly */
  82.     long process_id;
  83.     long host_id;
  84.     } seed;
  85.     struct timeval time; /* this must also be 64 bits exactly */
  86.     des_cblock new_key;
  87.     long gethostid();
  88.  
  89.     /*
  90.      * use a host id and process id in generating the seed to ensure
  91.      * that different servers have different streams:
  92.      */
  93.     seed.host_id = gethostid();
  94.     seed.process_id = getpid();
  95.  
  96.     /*
  97.      * Generate a tempory value that depends on the key, host_id, and
  98.      * process_id such that it gives no useful information about the key:
  99.      */
  100.     des_set_random_generator_seed(key);
  101.     des_set_sequence_number((unsigned char *)&seed);
  102.     des_new_random_key(new_key);
  103.  
  104.     /*
  105.      * use it to select a random stream:
  106.      */      
  107.     des_set_random_generator_seed(new_key);
  108.  
  109.     /*
  110.      * use a time stamp to ensure that a server started later does not reuse
  111.      * an old stream:
  112.      */
  113.     gettimeofday(&time, (struct timezone *)0);
  114.     des_set_sequence_number((unsigned char *)&time);
  115.  
  116.     /*
  117.      * use the time stamp finally to select the final seed using the
  118.      * current random number stream:
  119.      */
  120.     des_new_random_key(new_key);
  121.     des_set_random_generator_seed(new_key);
  122. }
  123.  
  124. #endif /* ifdef BSDUNIX */
  125.  
  126. /*
  127.  * This module implements a random number generator faculty such that the next
  128.  * number in any random number stream is very hard to predict without knowing
  129.  * the seed for that stream even given the preceeding random numbers.
  130.  */
  131.  
  132. /*
  133.  * The secret des key schedule for the current stream of random numbers:
  134.  */
  135. static des_key_schedule random_sequence_key;
  136.  
  137. /*
  138.  * The sequence # in the current stream of random numbers:
  139.  */
  140. static unsigned char sequence_number[8];
  141.  
  142. /*
  143.  * des_set_random_generator_seed: this routine is used to select a random
  144.  *                                number stream.  The stream that results is
  145.  *                                totally determined by the passed in key.
  146.  *                                (I.e., calling this routine again with the
  147.  *                                same key allows repeating a sequence of
  148.  *                                random numbers)
  149.  *
  150.  * Requires: key is a valid des key.  I.e., has correct parity and is not a
  151.  *           weak des key.
  152.  */
  153. void
  154. des_set_random_generator_seed(key)
  155.      des_cblock key;
  156. {
  157.     register int i;
  158.  
  159.     /* select the new stream: (note errors are not possible here...) */
  160.     des_key_sched(key, random_sequence_key);
  161.  
  162.     /* "seek" to the start of the stream: */
  163.     for (i=0; i<8; i++)
  164.       sequence_number[i] = 0;
  165. }
  166.  
  167. /*
  168.  * des_set_sequence_number: this routine is used to set the sequence number
  169.  *                          of the current random number stream.  This routine
  170.  *                          may be used to "seek" within the current random
  171.  *                          number stream.
  172.  *
  173.  * Note that des_set_random_generator_seed resets the sequence number to 0.
  174.  */
  175. void
  176. des_set_sequence_number(new_sequence_number)
  177.      des_cblock new_sequence_number;
  178. {
  179.     bcopy((char *)new_sequence_number, (char *)sequence_number,
  180.       sizeof(sequence_number));
  181. }
  182.  
  183. /*
  184.  * des_generate_random_block: routine to return the next random number
  185.  *                            from the current random number stream.
  186.  *                            The returned number is 64 bits long.
  187.  *
  188.  * Requires: des_set_random_generator_seed must have been called at least once
  189.  *           before this routine is called.
  190.  */
  191. void des_generate_random_block(block)
  192.      des_cblock block;
  193. {
  194.     int i;
  195.  
  196.     /*
  197.      * Encrypt the sequence number to get the new random block:
  198.      */
  199.     des_ecb_encrypt(sequence_number, block, random_sequence_key, 1);
  200.  
  201.     /*
  202.      * Increment the sequence number as an 8 byte unsigned number with wrap:
  203.      * (using LSB here)
  204.      */
  205.     for (i=0; i<8; i++) {
  206.     sequence_number[i] = (sequence_number[i] + 1) & 0xff;
  207.     if (sequence_number[i])
  208.       break;
  209.     }
  210. }
  211.