2 * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
5 * For copying and distribution information, please see the file
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
13 * Also checks parity and weak keys.
15 * Watch out for the subscripts -- most effectively start at 1 instead
16 * of at zero. Maybe some bugs in that area.
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.
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.
25 * All registers labeled imply Vax using the Ultrix or 4.2bsd compiler.
27 * Originally written 6/85 by Steve Miller, MIT Project Athena.
30 #include <afsconfig.h>
31 #include <afs/param.h>
34 #include "mit-cpyright.h"
35 #include "des_internal.h"
40 #include "des_prototypes.h"
44 /* the following are really void but cc86 doesnt allow it */
45 static int make_key_sched(key Key, des_key_schedule Schedule);
48 #pragma weak des_key_sched = afs_des_key_sched
50 afs_des_key_sched(register des_cblock k, des_key_schedule schedule)
53 des_key_sched(register des_cblock k, des_key_schedule schedule)
56 /* better pass 8 bytes, length not checked here */
58 register int i, j, n; /* i = r10, j = r9, n = r8 */
59 register unsigned int temp; /* r7 */
60 register char *p_char; /* r6 */
67 n = n; /* fool it in case of VAXASM */
71 fprintf(stderr, "\n\ninput key, left to right = ");
74 if (!des_check_key_parity(k)) /* bad parity --> return -1 */
78 /* get next input key byte */
81 fprintf(stderr, "%02x ", *k & 0xff);
83 temp = (unsigned int)((unsigned char)*k++);
88 *p_char++ = (int)temp & 01;
91 asm("bicb3 $-2,r7,(r8)+[r6]");
92 asm("rotl $-1,r7,r7");
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++);
113 /* check against weak keys */
114 k -= sizeof(des_cblock);
116 if (des_is_weak_key(k))
119 make_key_sched(k_char, schedule);
121 /* if key was good, return 0 */
126 make_key_sched(register key Key, des_key_schedule Schedule)
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
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.
139 /* r10, unroll by AUTH_DES_ITER */
140 register int iter = AUTH_DES_ITER;
141 register afs_uint32 *k; /* r9 */
142 register int *kp; /* r8 */
143 register afs_uint32 temp; /* r7 */
145 kp = (int *)key_perm;
146 k = (afs_uint32 *) Schedule;
150 * create the Key schedule
152 * put into lsb first order (lsb is bit 0)
156 * On the uvax2, this C code below is as fast as straight
157 * assembler, so just use C code below.
164 #define BIT(x) rev_swap_bit_pos_0(x)
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));
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));
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));
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));
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));
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));
276 } while (--iter > 0);
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);
290 fprintf(stderr, "\n");