rxkad-stats-cleanup-20050530
[openafs.git] / src / des / key_sched.c
1 /*
2  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
3  * of Technology.
4  *
5  * For copying and distribution information, please see the file
6  * <mit-cpyright.h>.
7  *
8  * This routine computes the DES key schedule given a key.  The
9  * permutations and shifts have been done at compile time, resulting
10  * in a direct one-step mapping from the input key to the key
11  * schedule.
12  *
13  * Also checks parity and weak keys.
14  *
15  * Watch out for the subscripts -- most effectively start at 1 instead
16  * of at zero.  Maybe some bugs in that area.
17  *
18  * DON'T change the data types for arrays and such, or it will either
19  * break or run slower.  This was optimized for Uvax2.
20  *
21  * In case the user wants to cache the computed key schedule, it is
22  * passed as an arg.  Also implies that caller has explicit control
23  * over zeroing both the key schedule and the key.
24  *
25  * All registers labeled imply Vax using the Ultrix or 4.2bsd compiler.
26  *
27  * Originally written 6/85 by Steve Miller, MIT Project Athena.
28  */
29
30 #include <afsconfig.h>
31 #include <afs/param.h>
32
33 RCSID
34     ("$Header$");
35
36 #include <mit-cpyright.h>
37 #include "des_internal.h"
38 #include <stdio.h>
39
40 #include "des.h"
41 #include "key_perm.h"
42 #include "stats.h"
43 #include "des_prototypes.h"
44
45 typedef char key[64];
46
47 #ifndef AFS_PTHREAD_ENV 
48 struct rxkad_stats rxkad_stats = { { 0 } }; 
49 #endif
50
51 /* the following are really void but cc86 doesnt allow it */
52 static int make_key_sched();
53
54 #ifdef AFS_DUX40_ENV
55 #pragma weak des_key_sched = afs_des_key_sched
56 int
57 afs_des_key_sched(register des_cblock k, des_key_schedule schedule)
58 #else
59 int
60 des_key_sched(register des_cblock k, des_key_schedule schedule)
61 #endif
62 {
63     /* better pass 8 bytes, length not checked here */
64
65     register int i, j, n;       /* i = r10, j = r9, n = r8 */
66     register unsigned int temp; /*  r7 */
67     register char *p_char;      /* r6 */
68     key k_char;
69     i = 8;
70     n = 0;
71     p_char = k_char;
72
73     INC_RXKAD_STATS(des_key_scheds);
74 #ifdef lint
75     n = n;                      /* fool it in case of VAXASM */
76 #endif
77 #ifdef DEBUG
78     if (des_debug)
79         fprintf(stderr, "\n\ninput key, left to right = ");
80 #endif
81
82     if (!des_check_key_parity(k))       /* bad parity --> return -1 */
83         return (-1);
84
85     do {
86         /* get next input key byte */
87 #ifdef DEBUG
88         if (des_debug)
89             fprintf(stderr, "%02x ", *k & 0xff);
90 #endif
91         temp = (unsigned int)((unsigned char)*k++);
92         j = 8;
93
94         do {
95 #ifndef VAXASM
96             *p_char++ = (int)temp & 01;
97             temp = temp >> 1;
98 #else
99             asm("bicb3  $-2,r7,(r8)+[r6]");
100             asm("rotl   $-1,r7,r7");
101 #endif
102         } while (--j > 0);
103     } while (--i > 0);
104
105 #ifdef DEBUG
106     if (des_debug) {
107         p_char = k_char;
108         fprintf(stderr, "\nKey bits, from zero to 63");
109         for (i = 0; i <= 7; i++) {
110             fprintf(stderr, "\n\t");
111             for (j = 0; j <= 7; j++)
112                 fprintf(stderr, "%d ", *p_char++);
113         }
114     }
115 #else
116 #ifdef lint
117     p_char = p_char;
118 #endif
119 #endif
120
121     /* check against weak keys */
122     k -= sizeof(des_cblock);
123
124     if (des_is_weak_key(k))
125         return (-2);
126
127     make_key_sched(k_char, schedule);
128
129     /* if key was good, return 0 */
130     return 0;
131 }
132
133 static int
134 make_key_sched(register key Key, des_key_schedule Schedule)
135 {
136     /*
137      * The key has been converted to an array to make this run faster;
138      * on a microvax 2, this routine takes about 3.5ms.  The code and
139      * size of the arrays has been played with to get it as fast as
140      * possible.
141      *
142      * Don't change the order of the declarations below without
143      * checking the assembler code to make sure that things are still
144      * where it expects them.
145      */
146
147     /* r10, unroll by AUTH_DES_ITER */
148     register int iter = AUTH_DES_ITER;
149     register afs_uint32 *k;     /* r9 */
150     register int *kp;           /* r8 */
151     register afs_uint32 temp;   /* r7 */
152
153     kp = (int *)key_perm;
154     k = (afs_uint32 *) Schedule;
155
156     do {
157         /*
158          * create the Key schedule
159          *
160          * put into lsb first order (lsb is bit 0)
161          */
162
163         /*
164          * On the uvax2, this C code below is as fast as straight
165          * assembler, so just use C code below.
166          */
167         temp = 0;
168 #ifdef LSBFIRST
169 #define BIT(x)  x
170 #else
171 #ifdef notdef
172 #define BIT(x) rev_swap_bit_pos_0(x)
173 #else
174 #define BIT(x)  x
175 #endif
176 #endif
177         if ((unsigned)Key[(int)*kp++])
178             temp |= (1 << BIT(0));
179         if ((unsigned)Key[(int)*kp++])
180             temp |= (1 << BIT(1));
181         if ((unsigned)Key[(int)*kp++])
182             temp |= (1 << BIT(2));
183         if ((unsigned)Key[(int)*kp++])
184             temp |= (1 << BIT(3));
185         if ((unsigned)Key[(int)*kp++])
186             temp |= (1 << BIT(4));
187         if ((unsigned)Key[(int)*kp++])
188             temp |= (1 << BIT(5));
189         if ((unsigned)Key[(int)*kp++])
190             temp |= (1 << BIT(6));
191         if ((unsigned)Key[(int)*kp++])
192             temp |= (1 << BIT(7));
193
194         if ((unsigned)Key[(int)*kp++])
195             temp |= (1 << BIT(8));
196         if ((unsigned)Key[(int)*kp++])
197             temp |= (1 << BIT(9));
198         if ((unsigned)Key[(int)*kp++])
199             temp |= (1 << BIT(10));
200         if ((unsigned)Key[(int)*kp++])
201             temp |= (1 << BIT(11));
202         if ((unsigned)Key[(int)*kp++])
203             temp |= (1 << BIT(12));
204         if ((unsigned)Key[(int)*kp++])
205             temp |= (1 << BIT(13));
206         if ((unsigned)Key[(int)*kp++])
207             temp |= (1 << BIT(14));
208         if ((unsigned)Key[(int)*kp++])
209             temp |= (1 << BIT(15));
210
211         if ((unsigned)Key[(int)*kp++])
212             temp |= (1 << BIT(16));
213         if ((unsigned)Key[(int)*kp++])
214             temp |= (1 << BIT(17));
215         if ((unsigned)Key[(int)*kp++])
216             temp |= (1 << BIT(18));
217         if ((unsigned)Key[(int)*kp++])
218             temp |= (1 << BIT(19));
219         if ((unsigned)Key[(int)*kp++])
220             temp |= (1 << BIT(20));
221         if ((unsigned)Key[(int)*kp++])
222             temp |= (1 << BIT(21));
223         if ((unsigned)Key[(int)*kp++])
224             temp |= (1 << BIT(22));
225         if ((unsigned)Key[(int)*kp++])
226             temp |= (1 << BIT(23));
227
228         if ((unsigned)Key[(int)*kp++])
229             temp |= (1 << BIT(24));
230         if ((unsigned)Key[(int)*kp++])
231             temp |= (1 << BIT(25));
232         if ((unsigned)Key[(int)*kp++])
233             temp |= (1 << BIT(26));
234         if ((unsigned)Key[(int)*kp++])
235             temp |= (1 << BIT(27));
236         if ((unsigned)Key[(int)*kp++])
237             temp |= (1 << BIT(28));
238         if ((unsigned)Key[(int)*kp++])
239             temp |= (1 << BIT(29));
240         if ((unsigned)Key[(int)*kp++])
241             temp |= (1 << BIT(30));
242         if ((unsigned)Key[(int)*kp++])
243             temp |= (1 << BIT(31));
244
245         *k++ = temp;
246         temp = 0;
247
248         if ((unsigned)Key[(int)*kp++])
249             temp |= (1 << BIT(0));
250         if ((unsigned)Key[(int)*kp++])
251             temp |= (1 << BIT(1));
252         if ((unsigned)Key[(int)*kp++])
253             temp |= (1 << BIT(2));
254         if ((unsigned)Key[(int)*kp++])
255             temp |= (1 << BIT(3));
256         if ((unsigned)Key[(int)*kp++])
257             temp |= (1 << BIT(4));
258         if ((unsigned)Key[(int)*kp++])
259             temp |= (1 << BIT(5));
260         if ((unsigned)Key[(int)*kp++])
261             temp |= (1 << BIT(6));
262         if ((unsigned)Key[(int)*kp++])
263             temp |= (1 << BIT(7));
264
265         if ((unsigned)Key[(int)*kp++])
266             temp |= (1 << BIT(8));
267         if ((unsigned)Key[(int)*kp++])
268             temp |= (1 << BIT(9));
269         if ((unsigned)Key[(int)*kp++])
270             temp |= (1 << BIT(10));
271         if ((unsigned)Key[(int)*kp++])
272             temp |= (1 << BIT(11));
273         if ((unsigned)Key[(int)*kp++])
274             temp |= (1 << BIT(12));
275         if ((unsigned)Key[(int)*kp++])
276             temp |= (1 << BIT(13));
277         if ((unsigned)Key[(int)*kp++])
278             temp |= (1 << BIT(14));
279         if ((unsigned)Key[(int)*kp++])
280             temp |= (1 << BIT(15));
281
282         *k++ = temp;
283
284     } while (--iter > 0);
285
286 #ifdef DEBUG
287     if (des_debug) {
288         int i;
289         char *n;
290         int q;
291         fprintf(stderr, "\nKey Schedule, left to right");
292         for (i = 0; i < AUTH_DES_ITER; i++) {
293             n = (char *)&Schedule[i];
294             fprintf(stderr, "\n");
295             for (q = 0; q <= 7; q++)
296                 fprintf(stderr, "%02x ", *n++ & 0xff);
297         }
298         fprintf(stderr, "\n");
299     }
300 #endif
301
302     return (0);
303 }