]> andersk Git - moira.git/blob - util/gdss/lib/crypto/algorithm/random.c
e117e51b71963831913dcb6b670441a748187660
[moira.git] / util / gdss / lib / crypto / algorithm / random.c
1 /*
2  * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
3  * ALL RIGHTS RESERVED
4  *
5  * "Digital Equipment Corporation authorizes the reproduction,
6  * distribution and modification of this software subject to the following
7  * restrictions:
8  * 
9  * 1.  Any partial or whole copy of this software, or any modification
10  * thereof, must include this copyright notice in its entirety.
11  *
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.
17  *
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.
20  * 
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.
26  * 
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"
31  *
32  */
33
34 /* 
35  * NOTES:
36  *
37  *    1. This file is BSD 4.2, and possibly Ultrix specific
38  *    2. This file includes in-line DES code
39  *
40  * CONTENTS:
41  *    1. Random number generator components
42  *    2. DES MAC routine.
43  */
44  
45 #include <stdio.h>
46 #ifndef ultrix
47 #include <sys/time.h>
48 #else
49 #include <time.h>
50 #endif
51 #include <sys/types.h>
52 #include <sys/resource.h>
53 #ifdef POSIX
54 #include <sys/utsname.h>
55 #endif
56 #ifdef SOLARIS
57 #include <sys/times.h>
58 #endif
59
60 #include "DEScrypto.h"
61
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();
67
68 /*
69  * Routines to checkpoint and restore random number generator state.
70  */
71  
72 void read_rng_state ( state )
73 RNGState *state ;
74 {  
75    memcpy (state, &rng, sizeof(RNGState));
76 }
77
78 void restore_rng_state ( state )
79 RNGState *state ;
80 {
81    memcpy (&rng, state, sizeof(RNGState));
82    DES_load_key_local( &rng.key, &random_key_schedule );
83 }
84
85
86 /*
87  *
88  * Initialize random number generator based on nl characters supplied by caller.
89  * Introduce some other uncertanity based on current time and resource usage.
90  *
91  */
92 void initialize_rng_state (seed,nl)
93 unsigned char * seed;
94 int nl;
95 {  
96    struct timezone tz;
97    struct timeval tv;
98    struct rusage *rs;
99    int i;
100
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) ;
104
105    /* get whatever resource usage there is */
106 #ifdef SOLARIS
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) ;
110 #else
111    rs = (struct rusage *) malloc(sizeof(struct rusage));
112    getrusage(0,rs);
113    rs->ru_stime.tv_sec += (long) rs ;
114    DES_MAC (0, rs, sizeof(struct rusage), &rng.seed, &random_key_schedule) ;
115 #endif
116    free(rs);
117
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();
122 #ifdef POSIX
123    {
124        struct utsname name;
125        int i, sum = 0;
126
127        (void) uname(&name);
128        for (i = 0; name.nodename[i]; i++)
129          sum = (sum<<1) + name.nodename[i];
130        rng.seed.longwords[1] += sum;
131    }
132 #else
133    rng.seed.longwords[1] += gethostid();
134 #endif
135
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);
139    rng.count=0;
140 }
141
142
143 /*
144  * random_bytes
145  *
146  * Pseudo-random number sequence generator based on NBS algorithm.
147  * Writes nl pseudo-random bytes to buffer n.
148  *
149  */
150 void random_bytes (n,nl) 
151 char *n;
152 int nl;
153 {
154 for(;nl>0;nl--){
155         if ((rng.count&7)==0)      /* refresh */
156         {
157                 struct timeval tv ;
158                 struct timezone tz ;
159
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);
168         }
169         rng.count++ ;
170         *n++ = rng.current.bytes [rng.count&7];
171 }
172 }
173
174
175 static void DES_MAC (iv, inbuf, isize, mac, key_schedule)
176 KEYschedule *key_schedule;
177 char *iv, *inbuf, *mac;
178 int isize;
179 {
180         int i;
181         DESblock temp;
182
183         if(iv) memcpy(temp.bytes,iv,8) ;
184         else temp.longwords[0]=temp.longwords[1]=0;
185
186         for (;isize>=8;isize-=8) {
187             for(i=0;i<8;i++) temp.bytes[i] ^= *inbuf++ ;
188             DESencrypt_local(&temp,&temp,key_schedule);
189         }
190
191         if(isize) {
192             for(i=0;i<isize;i++) temp.bytes[i] ^= *inbuf++;
193             DESencrypt_local(&temp,&temp,key_schedule);
194         }
195
196         memcpy(mac, &temp, 8);
197 }
198
199 \f
200 /*
201  *
202  *                      D E S _ X 9 _M A C
203  *
204  *      Compute a DES based message authentication code (MAC) over the input
205  *      buffer.  This uses the definition in ANSI X9.9
206  *
207  * Inputs:
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
212  *
213  * Outputs:
214  *      mac     - Resultant MAC
215  *
216  * Return Value:
217  *
218  */
219 void DES_X9_MAC (key, inbuf, isize, mac)
220 DESblock *key;
221 char *inbuf , *mac ;
222 int isize;
223 {
224         KEYschedule key_schedule;
225
226         DES_load_key_local(key,&key_schedule);
227         DES_MAC(0,inbuf,isize,mac,&key_schedule);
228         memset(&key_schedule, 0, sizeof(KEYschedule));
229 }
230
231
This page took 0.041103 seconds and 3 git commands to generate.