93eefb03bb35d799870b1a9ec57d76d3a561cd0a
[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 /* the following are really void but cc86 doesnt allow it */
48 static int make_key_sched();
49
50 #ifdef AFS_DUX40_ENV
51 #pragma weak des_key_sched = afs_des_key_sched
52 int
53 afs_des_key_sched(register des_cblock k, des_key_schedule schedule)
54 #else
55 int
56 des_key_sched(register des_cblock k, des_key_schedule schedule)
57 #endif
58 {
59     /* better pass 8 bytes, length not checked here */
60
61     register int i, j, n;       /* i = r10, j = r9, n = r8 */
62     register unsigned int temp; /*  r7 */
63     register char *p_char;      /* r6 */
64     key k_char;
65     i = 8;
66     n = 0;
67     p_char = k_char;
68
69     INC_RXKAD_STATS(des_key_scheds);
70 #ifdef lint
71     n = n;                      /* fool it in case of VAXASM */
72 #endif
73 #ifdef DEBUG
74     if (des_debug)
75         fprintf(stderr, "\n\ninput key, left to right = ");
76 #endif
77
78     if (!des_check_key_parity(k))       /* bad parity --> return -1 */
79         return (-1);
80
81     do {
82         /* get next input key byte */
83 #ifdef DEBUG
84         if (des_debug)
85             fprintf(stderr, "%02x ", *k & 0xff);
86 #endif
87         temp = (unsigned int)((unsigned char)*k++);
88         j = 8;
89
90         do {
91 #ifndef VAXASM
92             *p_char++ = (int)temp & 01;
93             temp = temp >> 1;
94 #else
95             asm("bicb3  $-2,r7,(r8)+[r6]");
96             asm("rotl   $-1,r7,r7");
97 #endif
98         } while (--j > 0);
99     } while (--i > 0);
100
101 #ifdef DEBUG
102     if (des_debug) {
103         p_char = k_char;
104         fprintf(stderr, "\nKey bits, from zero to 63");
105         for (i = 0; i <= 7; i++) {
106             fprintf(stderr, "\n\t");
107             for (j = 0; j <= 7; j++)
108                 fprintf(stderr, "%d ", *p_char++);
109         }
110     }
111 #else
112 #ifdef lint
113     p_char = p_char;
114 #endif
115 #endif
116
117     /* check against weak keys */
118     k -= sizeof(des_cblock);
119
120     if (des_is_weak_key(k))
121         return (-2);
122
123     make_key_sched(k_char, schedule);
124
125     /* if key was good, return 0 */
126     return 0;
127 }
128
129 static int
130 make_key_sched(register key Key, des_key_schedule Schedule)
131 {
132     /*
133      * The key has been converted to an array to make this run faster;
134      * on a microvax 2, this routine takes about 3.5ms.  The code and
135      * size of the arrays has been played with to get it as fast as
136      * possible.
137      *
138      * Don't change the order of the declarations below without
139      * checking the assembler code to make sure that things are still
140      * where it expects them.
141      */
142
143     /* r10, unroll by AUTH_DES_ITER */
144     register int iter = AUTH_DES_ITER;
145     register afs_uint32 *k;     /* r9 */
146     register int *kp;           /* r8 */
147     register afs_uint32 temp;   /* r7 */
148
149     kp = (int *)key_perm;
150     k = (afs_uint32 *) Schedule;
151
152     do {
153         /*
154          * create the Key schedule
155          *
156          * put into lsb first order (lsb is bit 0)
157          */
158
159         /*
160          * On the uvax2, this C code below is as fast as straight
161          * assembler, so just use C code below.
162          */
163         temp = 0;
164 #ifdef LSBFIRST
165 #define BIT(x)  x
166 #else
167 #ifdef notdef
168 #define BIT(x) rev_swap_bit_pos_0(x)
169 #else
170 #define BIT(x)  x
171 #endif
172 #endif
173         if ((unsigned)Key[(int)*kp++])
174             temp |= (1 << BIT(0));
175         if ((unsigned)Key[(int)*kp++])
176             temp |= (1 << BIT(1));
177         if ((unsigned)Key[(int)*kp++])
178             temp |= (1 << BIT(2));
179         if ((unsigned)Key[(int)*kp++])
180             temp |= (1 << BIT(3));
181         if ((unsigned)Key[(int)*kp++])
182             temp |= (1 << BIT(4));
183         if ((unsigned)Key[(int)*kp++])
184             temp |= (1 << BIT(5));
185         if ((unsigned)Key[(int)*kp++])
186             temp |= (1 << BIT(6));
187         if ((unsigned)Key[(int)*kp++])
188             temp |= (1 << BIT(7));
189
190         if ((unsigned)Key[(int)*kp++])
191             temp |= (1 << BIT(8));
192         if ((unsigned)Key[(int)*kp++])
193             temp |= (1 << BIT(9));
194         if ((unsigned)Key[(int)*kp++])
195             temp |= (1 << BIT(10));
196         if ((unsigned)Key[(int)*kp++])
197             temp |= (1 << BIT(11));
198         if ((unsigned)Key[(int)*kp++])
199             temp |= (1 << BIT(12));
200         if ((unsigned)Key[(int)*kp++])
201             temp |= (1 << BIT(13));
202         if ((unsigned)Key[(int)*kp++])
203             temp |= (1 << BIT(14));
204         if ((unsigned)Key[(int)*kp++])
205             temp |= (1 << BIT(15));
206
207         if ((unsigned)Key[(int)*kp++])
208             temp |= (1 << BIT(16));
209         if ((unsigned)Key[(int)*kp++])
210             temp |= (1 << BIT(17));
211         if ((unsigned)Key[(int)*kp++])
212             temp |= (1 << BIT(18));
213         if ((unsigned)Key[(int)*kp++])
214             temp |= (1 << BIT(19));
215         if ((unsigned)Key[(int)*kp++])
216             temp |= (1 << BIT(20));
217         if ((unsigned)Key[(int)*kp++])
218             temp |= (1 << BIT(21));
219         if ((unsigned)Key[(int)*kp++])
220             temp |= (1 << BIT(22));
221         if ((unsigned)Key[(int)*kp++])
222             temp |= (1 << BIT(23));
223
224         if ((unsigned)Key[(int)*kp++])
225             temp |= (1 << BIT(24));
226         if ((unsigned)Key[(int)*kp++])
227             temp |= (1 << BIT(25));
228         if ((unsigned)Key[(int)*kp++])
229             temp |= (1 << BIT(26));
230         if ((unsigned)Key[(int)*kp++])
231             temp |= (1 << BIT(27));
232         if ((unsigned)Key[(int)*kp++])
233             temp |= (1 << BIT(28));
234         if ((unsigned)Key[(int)*kp++])
235             temp |= (1 << BIT(29));
236         if ((unsigned)Key[(int)*kp++])
237             temp |= (1 << BIT(30));
238         if ((unsigned)Key[(int)*kp++])
239             temp |= (1 << BIT(31));
240
241         *k++ = temp;
242         temp = 0;
243
244         if ((unsigned)Key[(int)*kp++])
245             temp |= (1 << BIT(0));
246         if ((unsigned)Key[(int)*kp++])
247             temp |= (1 << BIT(1));
248         if ((unsigned)Key[(int)*kp++])
249             temp |= (1 << BIT(2));
250         if ((unsigned)Key[(int)*kp++])
251             temp |= (1 << BIT(3));
252         if ((unsigned)Key[(int)*kp++])
253             temp |= (1 << BIT(4));
254         if ((unsigned)Key[(int)*kp++])
255             temp |= (1 << BIT(5));
256         if ((unsigned)Key[(int)*kp++])
257             temp |= (1 << BIT(6));
258         if ((unsigned)Key[(int)*kp++])
259             temp |= (1 << BIT(7));
260
261         if ((unsigned)Key[(int)*kp++])
262             temp |= (1 << BIT(8));
263         if ((unsigned)Key[(int)*kp++])
264             temp |= (1 << BIT(9));
265         if ((unsigned)Key[(int)*kp++])
266             temp |= (1 << BIT(10));
267         if ((unsigned)Key[(int)*kp++])
268             temp |= (1 << BIT(11));
269         if ((unsigned)Key[(int)*kp++])
270             temp |= (1 << BIT(12));
271         if ((unsigned)Key[(int)*kp++])
272             temp |= (1 << BIT(13));
273         if ((unsigned)Key[(int)*kp++])
274             temp |= (1 << BIT(14));
275         if ((unsigned)Key[(int)*kp++])
276             temp |= (1 << BIT(15));
277
278         *k++ = temp;
279
280     } while (--iter > 0);
281
282 #ifdef DEBUG
283     if (des_debug) {
284         int i;
285         char *n;
286         int q;
287         fprintf(stderr, "\nKey Schedule, left to right");
288         for (i = 0; i < AUTH_DES_ITER; i++) {
289             n = (char *)&Schedule[i];
290             fprintf(stderr, "\n");
291             for (q = 0; q <= 7; q++)
292                 fprintf(stderr, "%02x ", *n++ & 0xff);
293         }
294         fprintf(stderr, "\n");
295     }
296 #endif
297
298     return (0);
299 }