standard-header-includes-20081129
[openafs.git] / src / des / des.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  * These routines perform encryption and decryption using the DES
9  * private key algorithm, or else a subset of it-- fewer inner loops.
10  * (AUTH_DES_ITER defaults to 16, may be less.)
11  *
12  * Under U.S. law, this software may not be exported outside the US
13  * without license from the U.S. Commerce department.
14  *
15  * The key schedule is passed as an arg, as well as the cleartext or
16  * ciphertext.
17  *
18  * All registers labeled imply Vax using the Ultrix or 4.2bsd
19  * compiler.
20  *
21  *
22  *      NOTE:  bit and byte numbering:
23  *                      DES algorithm is defined in terms of bits of L
24  *                      followed by bits of R.
25
26  *              bit 0  ==> lsb of L
27  *              bit 63 ==> msb of R
28  *
29  * Always work in register pairs, FROM L1,R1 TO L2,R2 to make
30  * bookkeeping easier.
31  *
32  * originally written by Steve Miller, MIT Project Athena
33  */
34 #include <mit-cpyright.h>
35
36 #include <afsconfig.h>
37 #include <afs/param.h>
38
39 RCSID
40     ("$Header$");
41
42 #ifndef KERNEL
43 #include <stdio.h>
44 #include <string.h>
45 #endif
46 #ifdef AFS_PTHREAD_ENV
47 #include <pthread.h>
48 #endif /* AFS_PTHREAD_ENV */
49 #include <des.h>
50 #include "des_internal.h"
51 #include "s_table.h"
52 #ifdef BIG
53 #include "p_table.h"
54 #endif
55
56 #include "des_prototypes.h"
57
58 #define XPRT_DES
59
60 #ifdef DEBUG
61 #define DBG_PRINT(s) if (des_debug & 2) \
62     des_debug_print(s,i,L1&0xffff,(L1>>16)&0xffff, \
63                 R1&0xffff,(R1>>16)&0xffff)
64 #else
65 #define DBG_PRINT(s)
66 #endif
67
68 /* encrypt == 0  ==> decrypt, else encrypt */
69
70 afs_int32
71 des_ecb_encrypt(void * clear, void * cipher,
72                 register des_key_schedule schedule, int encrypt)
73 {
74     /* better pass 8 bytes, length not checked here */
75
76     register afs_uint32 R1 = 0;
77     register afs_uint32 L1 = 0; /* R1 = r10, L1 = r9 */
78     register afs_uint32 R2 = 0, L2 = 0; /* R2 = r8, L2 = r7 */
79     afs_int32 i;
80     /* one more registers left on VAX, see below P_temp_p */
81 #ifdef BITS16
82     sbox_in_16_a S_in_16_a;
83     sbox_in_16_b S_in_16_b;
84     sbox_in_16_c S_in_16_c;
85     unsigned int *S_in_a_16_p = (unsigned int *)&S_in_16_a;
86     unsigned int *S_in_b_16_p = (unsigned int *)&S_in_16_b;
87     unsigned int *S_in_c_16_p = (unsigned int *)&S_in_16_c;
88 #endif
89 #ifndef BITS32
90 #ifndef BITS16
91 #error dunno how to do this machine type, you lose;
92 #endif
93 #endif
94     volatile afs_uint32 P_temp;
95     volatile unsigned char *P_temp_p = (unsigned char *)&P_temp;
96 #ifdef BITS16
97     sbox_out S_out;
98     afs_uint32 *S_out_p = (afs_uint32 *) & S_out;
99 #endif
100     afs_uint32 R_save, L_save;
101 #ifdef DEBUG
102     afs_uint32 dbg_tmp[2];
103 #endif
104     /*
105      * Use L1,R1 and L2,R2 as two sets of "64-bit" registers always
106      * work from L1,R1 input to L2,R2 output; initialize the cleartext
107      * into registers.
108      */
109 #ifdef MUSTALIGN
110 #ifdef DEBUG
111     /*
112      * If the alignment is wrong, the programmer really screwed up --
113      * we aren't even getting the right data type.  His problem.  Keep
114      * this code for debugging.
115      */
116     /* Make sure schedule is ok */
117     if ((afs_int32) schedule & 3) {
118         fprintf(stderr, "des.c schedule arg pointer not aligned\n");
119         abort();
120     }
121 #endif
122     if ((afs_uint32) clear & 3) {
123         memcpy((char *)(&L_save), (char *)clear, sizeof(L_save));
124         clear=((afs_uint32*)clear)+1;
125         memcpy((char *)(&R_save), (char *)clear, sizeof(R_save));
126         L1 = L_save;
127         R1 = R_save;
128     } else
129 #endif
130     {
131         if (clear) {
132             L1 = *((afs_uint32 *)clear);
133             clear=((afs_uint32*)clear)+1;
134         } else
135             L1 = 0;
136         if (clear)
137             R1 = *((afs_uint32 *)clear);
138         else
139             R1 = 0;
140     }
141
142 #ifdef DEBUG
143     if (des_debug & 2) {
144         printf("All values printed from low byte (bit 0)");
145         printf(" --> high byte (bit 63)\n");
146         i = 0;
147         dbg_tmp[0] = L1;
148         dbg_tmp[1] = R1;
149         printf("iter = %2d  before IP\n\t\tL1 R1 = ", i);
150         des_cblock_print_file(dbg_tmp, stdout);
151     }
152
153     DBG_PRINT("before IP");
154 #endif
155
156 /*   IP_start:*/
157
158     /* all the Initial Permutation code is in the include file */
159 #include "ip.c"
160     /* reset input to L1,R1 */
161     L1 = L2;
162     R1 = R2;
163
164     /* iterate through the inner loop */
165     for (i = 0; i <= (AUTH_DES_ITER - 1); i++) {
166
167 #ifdef DEBUG
168         if (des_debug & 2) {
169             dbg_tmp[0] = L1;
170             dbg_tmp[1] = R1;
171             printf("iter = %2d  start loop\n\t\tL1 R1 = ", i);
172             des_cblock_print_file(dbg_tmp, stdout);
173             DBG_PRINT("start loop");
174         }
175 #endif
176
177         R_save = R1;
178         L_save = L1;
179
180 /*   E_start:*/
181         /* apply the E permutation from R1 to L2, R2 */
182 #ifndef VAXASM
183 #ifdef SLOW_E
184 #include "e.c"
185 #else /* Bill's fast E */
186         L2 = (R1 << 1);
187         if (R1 & (1 << 31))
188             L2 |= 1 << 0;
189         L2 &= 077;
190         L2 |= (R1 << 3) & 07700;
191         L2 |= (R1 << 5) & 0770000;
192         L2 |= (R1 << 7) & 077000000;
193         L2 |= (R1 << 9) & 07700000000;
194         L2 |= (R1 << 11) & 030000000000;
195
196         /* now from right to right */
197
198         R2 = ((R1 >> 17) & 0176000);
199         if (R1 & (1 << 0))
200             R2 |= 1 << 15;
201
202         R2 |= ((R1 >> 21) & 017);
203         R2 |= ((R1 >> 19) & 01760);
204 #endif /* SLOW_E */
205 #else /* VAXASM */
206         /* E operations */
207         /* right to left */
208         asm("   rotl    $1,r10,r7");
209         L2 &= 077;
210         L2 |= (R1 << 3) & 07700;
211         L2 |= (R1 << 5) & 0770000;
212         L2 |= (R1 << 7) & 077000000;
213         L2 |= (R1 << 9) & 07700000000;
214         L2 |= (R1 << 11) & 030000000000;
215
216         asm("   rotl    $-17,r10,r8");
217         R2 &= 0176000;
218         asm("   rotl    $-21,r10,r0");
219         asm("   bicl2   $-16,r0");
220         asm("  bisl2    r0,r8");
221         asm("   rotl    $-19,r10,r0");
222         asm("   bicl2   $-1009,r0");
223         asm("  bisl2    r0,r8");
224
225 #endif
226
227         /* reset input to L1,R1 */
228         L1 = L2;
229         R1 = R2;
230
231 #ifdef DEBUG
232         if (des_debug & 2) {
233             dbg_tmp[0] = L1;
234             dbg_tmp[1] = R1;
235             DBG_PRINT("after e");
236             printf("iter = %2d  after e\n\t\tL1 R1 = ", i);
237             des_cblock_print_file(dbg_tmp, stdout);
238         }
239 #endif
240
241 /*   XOR_start:*/
242         /*
243          * XOR with the key schedule, "schedule"
244          *
245          * If this is an encryption operation, use schedule[i],
246          * otherwise use schedule [AUTH_DES_ITER-i-1]
247          *
248          * First XOR left half.
249          */
250         if (encrypt) {
251             L1 ^= *(((afs_uint32 *) & schedule[i]) + 0);
252             /* now right half */
253             R1 ^= *(((afs_uint32 *) & schedule[i]) + 1);
254         } else {
255             L1 ^= *(((afs_uint32 *) & schedule[AUTH_DES_ITER - i - 1]) + 0);
256             /* now right half */
257             R1 ^= *(((afs_uint32 *) & schedule[AUTH_DES_ITER - i - 1]) + 1);
258         }
259
260         /* dont have to reset input to L1, R1 */
261
262 #ifdef DEBUG
263         if (des_debug & 2) {
264             dbg_tmp[0] = L1;
265             dbg_tmp[1] = R1;
266             DBG_PRINT("after xor");
267             printf("iter = %2d  after xor\n\t\tL1 R1 =", i);
268             des_cblock_print_file(dbg_tmp, stdout);
269         }
270 #endif
271
272 /*   S_start:*/
273         /* apply the S selection from L1, R1 to R2 */
274
275 #ifdef notdef
276 #include "s.c"
277 #endif
278
279         /* S operations , cant use registers for bit field stuff */
280         /* from S_in to S_out */
281
282 #ifdef BITS16
283         *S_in_a_16_p = L1 & 0xffff;
284         *S_in_b_16_p = (L1 >> 16) & 0xffff;
285         *S_in_c_16_p = R1 & 0xffff;
286         (*(afs_uint32 *) & S_out) = (unsigned)S_adj[0][S_in_16_a.b0];
287         S_out.b1 = (unsigned)S_adj[1][S_in_16_a.b1];
288         /* b2 spans two words */
289         S_out.b2 = (unsigned)
290             S_adj[2][(unsigned)S_in_16_a.b2 +
291                      (((unsigned)S_in_16_b.b2) << 4)];
292         S_out.b3 = (unsigned)S_adj[3][S_in_16_b.b3];
293         S_out.b4 = (unsigned)S_adj[4][S_in_16_b.b4];
294         /* b5 spans both parts */
295         S_out.b5 = (unsigned)
296             S_adj[5][(unsigned)S_in_16_b.b5 +
297                      (((unsigned)S_in_16_c.b5) << 2)];
298         S_out.b6 = (unsigned)S_adj[6][S_in_16_c.b6];
299         S_out.b7 = (unsigned)S_adj[7][S_in_16_c.b7];
300         R1 = *S_out_p;
301 #else
302         /* is a 32 bit sys */
303 #ifndef VAXASM
304         R2 = (unsigned)S_adj[0][L1 & 077];
305         L2 = (unsigned)S_adj[1][(L1 >> 6) & 077];
306         R2 |= (L2 << 4);
307         L2 = (unsigned)S_adj[2][(L1 >> 12) & 077];
308         R2 |= (L2 << 8);
309         L2 = (unsigned)S_adj[3][(L1 >> 18) & 077];
310         R2 |= (L2 << 12);
311         L2 = (unsigned)S_adj[4][(L1 >> 24) & 077];
312         R2 |= (L2 << 16);
313         /* b5 spans both parts */
314         L2 = (unsigned)
315             S_adj[5][(unsigned)((L1 >> 30) & 03) + ((R1 & 017) << 2)];
316         R2 |= (L2 << 20);
317         L2 = (unsigned)S_adj[6][(R1 >> 4) & 077];
318         R2 |= (L2 << 24);
319         L2 = (unsigned)S_adj[7][(R1 >> 10) & 077];
320         R1 = R2 | (L2 << 28);
321         /* reset input to L1, R1 */
322 #else /* vaxasm */
323         /*
324          * this is the c code produced above, with
325          * extzv replaced by rotl
326          */
327         asm("bicl3      $-64,r9,r0");
328         asm("movzbl     _S_adj[r0],r8");
329         asm("rotl       $-6,r9,r0");
330         asm("bicl2      $-64,r0");
331         asm("movzbl     _S_adj+64[r0],r7");
332         asm("ashl       $4,r7,r0");
333         asm("bisl2      r0,r8");
334         asm("rotl       $-12,r9,r0");
335         asm("bicl2      $-64,r0");
336         asm("movzbl     _S_adj+128[r0],r7");
337         asm("ashl       $8,r7,r0");
338         asm("bisl2      r0,r8");
339         asm("rotl       $-18,r9,r0");
340         asm("bicl2      $-64,r0");
341         asm("movzbl     _S_adj+192[r0],r7");
342         asm("ashl       $12,r7,r0");
343         asm("bisl2      r0,r8");
344         asm("rotl       $-24,r9,r0");
345         asm("bicl2      $-64,r0");
346         asm("movzbl     _S_adj+256[r0],r7");
347         asm("ashl       $16,r7,r0");
348         asm("bisl2      r0,r8");
349         asm("rotl       $-30,r9,r0");
350         asm("bicl2      $-4,r0");
351         asm("bicl3      $-16,r10,r1");
352         asm("ashl       $2,r1,r1");
353         asm("addl2      r1,r0");
354         asm("movzbl     _S_adj+320[r0],r7");
355         asm("ashl       $20,r7,r0");
356         asm("bisl2      r0,r8");
357         asm("rotl       $-4,r10,r0");
358         asm("bicl2      $-64,r0");
359         asm("movzbl     _S_adj+384[r0],r7");
360         asm("ashl       $24,r7,r0");
361         asm("bisl2      r0,r8");
362         asm("rotl       $-10,r10,r0");
363         asm("bicl2      $-64,r0");
364         asm("movzbl     _S_adj+448[r0],r7");
365         asm("ashl       $28,r7,r0");
366         asm("bisl2      r8,r0");
367         asm("movl       r0,r10");
368
369 #endif /* vaxasm */
370 #endif
371
372 #ifdef DEBUG
373         if (des_debug & 2) {
374             dbg_tmp[0] = L1;
375             dbg_tmp[1] = R1;
376             DBG_PRINT("after s");
377             printf("iter = %2d  after s\n\t\tL1 R1 = ", i);
378             des_cblock_print_file(dbg_tmp, stdout);
379         }
380 #endif
381
382 /*   P_start:*/
383         /* and then the p permutation from R1 into R2 */
384 #include "p.c"
385         /* reset the input to L1, R1 */
386         R1 = R2;
387
388 #ifdef DEBUG
389         if (des_debug & 2) {
390             dbg_tmp[0] = L1;
391             dbg_tmp[1] = R1;
392             DBG_PRINT("after p");
393             printf("iter = %2d  after p\n\t\tL1 R1 = ", i);
394             des_cblock_print_file(dbg_tmp, stdout);
395         }
396 #endif
397
398         /* R1 is the output value from the f() */
399         /* move R[iter] to L[iter+1] */
400 /*   XOR_2_start:*/
401         L1 = R_save;
402         /* xor with left */
403         R1 = L_save ^ R1;
404         /* reset the input */
405     }
406
407     /* flip left and right before final permutation */
408     L2 = R1;                    /* flip */
409     R2 = L1;
410     /* reset the input */
411     L1 = L2;
412     R1 = R2;
413
414 #ifdef DEBUG
415     if (des_debug & 2) {
416         dbg_tmp[0] = L1;
417         dbg_tmp[1] = R1;
418         DBG_PRINT("before FP");
419         printf("iter = %2d  before FP\n\t\tL1 R1 = ", i);
420         des_cblock_print_file(dbg_tmp, stdout);
421     }
422 #endif
423
424 /*FP_start:*/
425     /* do the final permutation from L1R1 to L2R2 */
426     /* all the fp code is in the include file */
427 #include "fp.c"
428
429     /* copy the output to the ciphertext string;
430      * can be same as cleartext
431      */
432
433 #ifdef MUSTALIGN
434     if ((afs_int32) cipher & 3) {
435         L_save = L2;            /* cant bcopy a reg */
436         R_save = R2;
437         memcpy((char *)cipher, (char *)&L_save, sizeof(L_save));
438         cipher=((afs_uint32*)cipher)+1;
439         memcpy((char *)cipher, (char *)&R_save, sizeof(R_save));
440     } else
441 #endif
442     {
443         *((afs_uint32*)cipher)= L2;     
444         cipher = ((afs_int32 *)cipher)+1;
445         *((afs_uint32 *)cipher) = R2;
446     }
447
448 #ifdef DEBUG
449     if (des_debug & 2) {
450         L1 = L2;
451         R1 = R2;
452         dbg_tmp[0] = L1;
453         dbg_tmp[1] = R1;
454         DBG_PRINT("done");
455         printf("iter = %2d  done\n\t\tL1 R1 = ", i);
456         des_cblock_print_file(dbg_tmp, stdout);
457     }
458 #endif
459
460     /* that's it, no errors can be returned */
461     return 0;
462 }