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