2 * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
5 * "Digital Equipment Corporation authorizes the reproduction,
6 * distribution and modification of this software subject to the following
9 * 1. Any partial or whole copy of this software, or any modification
10 * thereof, must include this copyright notice in its entirety.
12 * 2. This software is supplied "as is" with no warranty of any kind,
13 * expressed or implied, for any purpose, including any warranty of fitness
14 * or merchantibility. DIGITAL assumes no responsibility for the use or
15 * reliability of this software, nor promises to provide any form of
16 * support for it on any basis.
18 * 3. Distribution of this software is authorized only if no profit or
19 * remuneration of any kind is received in exchange for such distribution.
21 * 4. This software produces public key authentication certificates
22 * bearing an expiration date established by DIGITAL and RSA Data
23 * Security, Inc. It may cease to generate certificates after the expiration
24 * date. Any modification of this software that changes or defeats
25 * the expiration date or its effect is unauthorized.
27 * 5. Software that will renew or extend the expiration date of
28 * authentication certificates produced by this software may be obtained
29 * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
30 * 94065, (415)595-8782, or from DIGITAL"
37 * 1. This file is BSD 4.2, and possibly Ultrix specific
38 * 2. This file includes in-line DES code
41 * 1. Random number generator components
51 #include <sys/types.h>
52 #include <sys/resource.h>
54 #include <sys/utsname.h>
57 #include <sys/times.h>
60 #include "DEScrypto.h"
62 static RNGState rng ; /* this needs to be saved and restored as needed */
63 static KEYschedule random_key_schedule;
64 static unsigned char scramble_key[8] = {0x01, 0x23, 0x45, 0x67,
65 0x89, 0xab, 0xcd, 0xef};
66 static void DES_MAC();
69 * Routines to checkpoint and restore random number generator state.
72 void read_rng_state ( state )
75 memcpy (state, &rng, sizeof(RNGState));
78 void restore_rng_state ( state )
81 memcpy (&rng, state, sizeof(RNGState));
82 DES_load_key_local( &rng.key, &random_key_schedule );
88 * Initialize random number generator based on nl characters supplied by caller.
89 * Introduce some other uncertanity based on current time and resource usage.
92 void initialize_rng_state (seed,nl)
101 /* start with hash of input string */
102 DES_load_key_local(scramble_key, &random_key_schedule) ;
103 DES_MAC (0, seed, nl, &rng.key, &random_key_schedule) ;
105 /* get whatever resource usage there is */
107 rs = (struct rusage *)malloc (sizeof(struct tms));
108 (void) times((struct tms *)rs);
109 DES_MAC (0, rs, sizeof(struct tms), &rng.seed, &random_key_schedule) ;
111 rs = (struct rusage *) malloc(sizeof(struct rusage));
113 rs->ru_stime.tv_sec += (long) rs ;
114 DES_MAC (0, rs, sizeof(struct rusage), &rng.seed, &random_key_schedule) ;
118 /* get the current wall clock time, mix in process id */
119 gettimeofday(&tv,&tz);
120 rng.seed.longwords[0] = tv.tv_sec + getpid() + (long) &tz ;
121 rng.seed.longwords[1] = tv.tv_usec + clock();
128 for (i = 0; name.nodename[i]; i++)
129 sum = (sum<<1) + name.nodename[i];
130 rng.seed.longwords[1] += sum;
133 rng.seed.longwords[1] += gethostid();
136 DES_load_key_local( &rng.key, &random_key_schedule);
137 DESencrypt_local(&rng.seed, &rng.key, &random_key_schedule);
138 DES_load_key_local( &rng.key, &random_key_schedule);
146 * Pseudo-random number sequence generator based on NBS algorithm.
147 * Writes nl pseudo-random bytes to buffer n.
150 void random_bytes (n,nl)
155 if ((rng.count&7)==0) /* refresh */
160 gettimeofday(&tv, &tz);
161 rng.current.longwords[0]= tv.tv_sec + rng.count ;
162 rng.current.longwords[1]= tv.tv_usec + clock();
163 DESencrypt_local(&rng.current,&rng.current,&random_key_schedule);
164 rng.current.longwords[0] ^= rng.seed.longwords [0] ;
165 rng.current.longwords[1] ^= rng.seed.longwords [1] ;
166 DESencrypt_local(&rng.current,&rng.seed,&random_key_schedule);
167 DESdecrypt_local(&rng.current,&rng.current,&random_key_schedule);
170 *n++ = rng.current.bytes [rng.count&7];
175 static void DES_MAC (iv, inbuf, isize, mac, key_schedule)
176 KEYschedule *key_schedule;
177 char *iv, *inbuf, *mac;
183 if(iv) memcpy(temp.bytes,iv,8) ;
184 else temp.longwords[0]=temp.longwords[1]=0;
186 for (;isize>=8;isize-=8) {
187 for(i=0;i<8;i++) temp.bytes[i] ^= *inbuf++ ;
188 DESencrypt_local(&temp,&temp,key_schedule);
192 for(i=0;i<isize;i++) temp.bytes[i] ^= *inbuf++;
193 DESencrypt_local(&temp,&temp,key_schedule);
196 memcpy(mac, &temp, 8);
204 * Compute a DES based message authentication code (MAC) over the input
205 * buffer. This uses the definition in ANSI X9.9
208 * key - input DES key
209 * inbuf - Pointer to the input buffer
210 * isize - Size of the input buffer
211 * mac - Pointer to a buffer to receive the MAC
214 * mac - Resultant MAC
219 void DES_X9_MAC (key, inbuf, isize, mac)
224 KEYschedule key_schedule;
226 DES_load_key_local(key,&key_schedule);
227 DES_MAC(0,inbuf,isize,mac,&key_schedule);
228 memset(&key_schedule, 0, sizeof(KEYschedule));