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
47 #include <sys/types.h>
48 #include <sys/resource.h>
49 #include <sys/utsname.h>
50 #include <sys/times.h>
52 #include "DEScrypto.h"
54 static RNGState rng ; /* this needs to be saved and restored as needed */
55 static KEYschedule random_key_schedule;
56 static unsigned char scramble_key[8] = {0x01, 0x23, 0x45, 0x67,
57 0x89, 0xab, 0xcd, 0xef};
58 static void DES_MAC();
61 * Routines to checkpoint and restore random number generator state.
64 void read_rng_state ( state )
67 memcpy (state, &rng, sizeof(RNGState));
70 void restore_rng_state ( state )
73 memcpy (&rng, state, sizeof(RNGState));
74 DES_load_key_local( &rng.key, &random_key_schedule );
80 * Initialize random number generator based on nl characters supplied by caller.
81 * Introduce some other uncertanity based on current time and resource usage.
84 void initialize_rng_state (seed,nl)
94 /* start with hash of input string */
95 DES_load_key_local(scramble_key, &random_key_schedule) ;
96 DES_MAC (0, seed, nl, &rng.key, &random_key_schedule) ;
98 /* get whatever resource usage there is */
100 DES_MAC (0, &buffer, sizeof(struct tms), &rng.seed, &random_key_schedule) ;
102 /* get the current wall clock time, mix in process id */
103 gettimeofday(&tv,&tz);
104 rng.seed.longwords[0] = tv.tv_sec + getpid() + (long) &tz ;
105 rng.seed.longwords[1] = tv.tv_usec + clock();
109 for (i = 0; name.nodename[i]; i++)
110 sum = (sum<<1) + name.nodename[i];
111 rng.seed.longwords[1] += sum;
113 DES_load_key_local( &rng.key, &random_key_schedule);
114 DESencrypt_local(&rng.seed, &rng.key, &random_key_schedule);
115 DES_load_key_local( &rng.key, &random_key_schedule);
123 * Pseudo-random number sequence generator based on NBS algorithm.
124 * Writes nl pseudo-random bytes to buffer n.
127 void random_bytes (n,nl)
132 if ((rng.count&7)==0) /* refresh */
137 gettimeofday(&tv, &tz);
138 rng.current.longwords[0]= tv.tv_sec + rng.count ;
139 rng.current.longwords[1]= tv.tv_usec + clock();
140 DESencrypt_local(&rng.current,&rng.current,&random_key_schedule);
141 rng.current.longwords[0] ^= rng.seed.longwords [0] ;
142 rng.current.longwords[1] ^= rng.seed.longwords [1] ;
143 DESencrypt_local(&rng.current,&rng.seed,&random_key_schedule);
144 DESdecrypt_local(&rng.current,&rng.current,&random_key_schedule);
147 *n++ = rng.current.bytes [rng.count&7];
152 static void DES_MAC (iv, inbuf, isize, mac, key_schedule)
153 KEYschedule *key_schedule;
154 char *iv, *inbuf, *mac;
160 if(iv) memcpy(temp.bytes,iv,8) ;
161 else temp.longwords[0]=temp.longwords[1]=0;
163 for (;isize>=8;isize-=8) {
164 for(i=0;i<8;i++) temp.bytes[i] ^= *inbuf++ ;
165 DESencrypt_local(&temp,&temp,key_schedule);
169 for(i=0;i<isize;i++) temp.bytes[i] ^= *inbuf++;
170 DESencrypt_local(&temp,&temp,key_schedule);
173 memcpy(mac, &temp, 8);
181 * Compute a DES based message authentication code (MAC) over the input
182 * buffer. This uses the definition in ANSI X9.9
185 * key - input DES key
186 * inbuf - Pointer to the input buffer
187 * isize - Size of the input buffer
188 * mac - Pointer to a buffer to receive the MAC
191 * mac - Resultant MAC
196 void DES_X9_MAC (key, inbuf, isize, mac)
201 KEYschedule key_schedule;
203 DES_load_key_local(key,&key_schedule);
204 DES_MAC(0,inbuf,isize,mac,&key_schedule);
205 memset(&key_schedule, 0, sizeof(KEYschedule));