r8302: import mini HEIMDAL into the tree
[tprouty/samba.git] / source / heimdal / lib / des / des.c
1 /*
2  * Copyright (c) 2005 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * The document that got me started for real was "Efficient
36  * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
37  * I never got to the PC1 transformation was working, instead I used
38  * table-lookup was used for all key schedule setup. The document was
39  * very useful since it de-mystified other implementations for me.
40  *
41  * The core DES function (SBOX + P transformation) is from Richard
42  * Outerbridge public domain DES implementation. My sanity is saved
43  * thanks to his work. Thank you Richard.
44  */
45
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 RCSID("$Id: des.c,v 1.14 2005/06/18 22:47:17 lha Exp $");
49 #endif
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <krb5-types.h>
55
56 #include "des.h"
57
58 static void desx(uint32_t [2], DES_key_schedule *, int);
59 static void IP(uint32_t [2]);
60 static void FP(uint32_t [2]);
61
62 #include "des-tables.h"
63
64 #define ROTATE_LEFT28(x,one)                            \
65     if (one) {                                          \
66         x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27);    \
67     } else {                                            \
68         x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);    \
69     }
70
71 /*
72  *
73  */
74
75 int
76 DES_set_odd_parity(DES_cblock *key)
77 {
78     int i;
79     for (i = 0; i < DES_CBLOCK_LEN; i++)
80         (*key)[i] = odd_parity[(*key)[i]];
81     return 0;
82 }
83
84 /*
85  *
86  */
87
88 /* FIPS 74 */
89 static DES_cblock weak_keys[] = {
90     {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
91     {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
92     {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
93     {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
94     {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
95     {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
96     {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
97     {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
98     {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
99     {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
100     {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
101     {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
102     {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
103     {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
104     {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
105     {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
106 };
107
108 int
109 DES_is_weak_key(DES_cblock *key)
110 {
111     int i;
112
113     for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
114         if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
115             return 1;
116     }
117     return 0;
118 }
119
120
121 /*
122  *
123  */
124
125 int
126 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
127 {
128     uint32_t t1, t2;
129     uint32_t c, d;
130     int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
131     uint32_t *k = &ks->ks[0];
132     int i;
133
134     t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
135     t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
136
137     c =   (pc1_c_3[(t1 >> (5            )) & 0x7] << 3)
138         | (pc1_c_3[(t1 >> (5 + 8        )) & 0x7] << 2)
139         | (pc1_c_3[(t1 >> (5 + 8 + 8    )) & 0x7] << 1)
140         | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
141         | (pc1_c_4[(t2 >> (4            )) & 0xf] << 3)
142         | (pc1_c_4[(t2 >> (4 + 8        )) & 0xf] << 2)
143         | (pc1_c_4[(t2 >> (4 + 8 + 8    )) & 0xf] << 1)
144         | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
145
146     
147     d =   (pc1_d_3[(t2 >> (1            )) & 0x7] << 3)
148         | (pc1_d_3[(t2 >> (1 + 8        )) & 0x7] << 2)
149         | (pc1_d_3[(t2 >> (1 + 8 + 8    )) & 0x7] << 1)
150         | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
151         | (pc1_d_4[(t1 >> (1            )) & 0xf] << 3)
152         | (pc1_d_4[(t1 >> (1 + 8        )) & 0xf] << 2)
153         | (pc1_d_4[(t1 >> (1 + 8 + 8    )) & 0xf] << 1)
154         | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
155
156     for (i = 0; i < 16; i++) {
157         uint32_t kc, kd;
158         
159         ROTATE_LEFT28(c, shifts[i]);
160         ROTATE_LEFT28(d, shifts[i]);
161         
162         kc = pc2_c_1[(c >> 22) & 0x3f] |
163             pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
164             pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
165             pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
166         kd = pc2_d_1[(d >> 22) & 0x3f] |
167             pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
168             pc2_d_3[ (d >> 7 ) & 0x3f] |
169             pc2_d_4[((d >> 1 ) & 0x3c) | ((d      ) & 0x3)];
170
171         /* Change to byte order used by the S boxes */
172         *k  =    (kc & 0x00fc0000L) << 6;
173         *k |=    (kc & 0x00000fc0L) << 10;
174         *k |=    (kd & 0x00fc0000L) >> 10;
175         *k++  |= (kd & 0x00000fc0L) >> 6;
176         *k  =    (kc & 0x0003f000L) << 12;
177         *k |=    (kc & 0x0000003fL) << 16;
178         *k |=    (kd & 0x0003f000L) >> 4;
179         *k++  |= (kd & 0x0000003fL);
180     }
181
182     return 0;
183 }
184
185 /*
186  *
187  */
188
189 int
190 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
191 {
192     if (DES_is_weak_key(key)) {
193         memset(ks, 0, sizeof(*ks));
194         return 1;
195     }
196     return DES_set_key(key, ks);
197 }
198
199 /*
200  * Compatibility function for eay libdes
201  */
202
203 int
204 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
205 {
206     return DES_set_key(key, ks);
207 }
208
209 /*
210  *
211  */
212
213 static void
214 load(const unsigned char *b, uint32_t v[2])
215 {
216     v[0] =  b[0] << 24;
217     v[0] |= b[1] << 16;
218     v[0] |= b[2] << 8;
219     v[0] |= b[3] << 0;
220     v[1] =  b[4] << 24;
221     v[1] |= b[5] << 16;
222     v[1] |= b[6] << 8;
223     v[1] |= b[7] << 0;
224 }
225
226 static void
227 store(const uint32_t v[2], unsigned char *b)
228 {
229     b[0] = (v[0] >> 24) & 0xff;
230     b[1] = (v[0] >> 16) & 0xff;
231     b[2] = (v[0] >>  8) & 0xff;
232     b[3] = (v[0] >>  0) & 0xff;
233     b[4] = (v[1] >> 24) & 0xff;
234     b[5] = (v[1] >> 16) & 0xff;
235     b[6] = (v[1] >>  8) & 0xff;
236     b[7] = (v[1] >>  0) & 0xff;
237 }
238
239 /*
240  *
241  */
242
243 void
244 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt)
245 {
246     IP(u);
247     desx(u, ks, forward_encrypt);
248     FP(u);
249 }
250
251 /*
252  *
253  */
254
255 void
256 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
257                 DES_key_schedule *ks, int forward_encrypt)
258 {
259     uint32_t u[2];
260     load(*input, u);
261     DES_encrypt(u, ks, forward_encrypt);
262     store(u, *output);
263 }
264
265 /*
266  *
267  */
268
269 void
270 DES_cbc_encrypt(unsigned char *input, unsigned char *output, long length,
271                 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
272 {
273     uint32_t u[2];
274     uint32_t uiv[2];
275
276     load(*iv, uiv);
277
278     if (forward_encrypt) {
279         while (length >= DES_CBLOCK_LEN) {
280             load(input, u);
281             u[0] ^= uiv[0]; u[1] ^= uiv[1];
282             DES_encrypt(u, ks, 1);
283             uiv[0] = u[0]; uiv[1] = u[1];
284             store(u, output);
285
286             length -= DES_CBLOCK_LEN;
287             input += DES_CBLOCK_LEN;
288             output += DES_CBLOCK_LEN;
289         }
290         if (length) {
291             unsigned char tmp[DES_CBLOCK_LEN];
292             memcpy(tmp, input, length);
293             memset(tmp + length, 0, DES_CBLOCK_LEN - length);
294             load(tmp, u);
295             u[0] ^= uiv[0]; u[1] ^= uiv[1];
296             DES_encrypt(u, ks, 1);
297             store(u, output);
298         }
299     } else {
300         uint32_t t[2];
301         while (length >= DES_CBLOCK_LEN) {
302             load(input, u);
303             t[0] = u[0]; t[1] = u[1];
304             DES_encrypt(u, ks, 0);
305             u[0] ^= uiv[0]; u[1] ^= uiv[1];
306             store(u, output);
307             uiv[0] = t[0]; uiv[1] = t[1];
308
309             length -= DES_CBLOCK_LEN;
310             input += DES_CBLOCK_LEN;
311             output += DES_CBLOCK_LEN;
312         }
313         if (length) {
314             unsigned char tmp[DES_CBLOCK_LEN];
315             memcpy(tmp, input, length);
316             memset(tmp + length, 0, DES_CBLOCK_LEN - length);
317             load(tmp, u);
318             DES_encrypt(u, ks, 0);
319             u[0] ^= uiv[0]; u[1] ^= uiv[1];
320             store(u, output);
321         }
322     }
323     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
324 }
325
326 /*
327  *
328  */
329
330 void
331 DES_pcbc_encrypt(unsigned char *input, unsigned char *output, long length,
332                  DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
333 {
334     uint32_t u[2];
335     uint32_t uiv[2];
336
337     load(*iv, uiv);
338
339     if (forward_encrypt) {
340         uint32_t t[2];
341         while (length >= DES_CBLOCK_LEN) {
342             load(input, u);
343             t[0] = u[0]; t[1] = u[1];
344             u[0] ^= uiv[0]; u[1] ^= uiv[1];
345             DES_encrypt(u, ks, 1);
346             uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
347             store(u, output);
348
349             length -= DES_CBLOCK_LEN;
350             input += DES_CBLOCK_LEN;
351             output += DES_CBLOCK_LEN;
352         }
353         if (length) {
354             unsigned char tmp[DES_CBLOCK_LEN];
355             memcpy(tmp, input, length);
356             memset(tmp + length, 0, DES_CBLOCK_LEN - length);
357             load(tmp, u);
358             u[0] ^= uiv[0]; u[1] ^= uiv[1];
359             DES_encrypt(u, ks, 1);
360             store(u, output);
361         }
362     } else {
363         uint32_t t[2];
364         while (length >= DES_CBLOCK_LEN) {
365             load(input, u);
366             t[0] = u[0]; t[1] = u[1];
367             DES_encrypt(u, ks, 0);
368             u[0] ^= uiv[0]; u[1] ^= uiv[1];
369             store(u, output);
370             uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
371
372             length -= DES_CBLOCK_LEN;
373             input += DES_CBLOCK_LEN;
374             output += DES_CBLOCK_LEN;
375         }
376         if (length) {
377             unsigned char tmp[DES_CBLOCK_LEN];
378             memcpy(tmp, input, length);
379             memset(tmp + length, 0, DES_CBLOCK_LEN - length);
380             load(tmp, u);
381             DES_encrypt(u, ks, 0);
382             u[0] ^= uiv[0]; u[1] ^= uiv[1];
383         }
384     }
385     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
386 }
387
388 /*
389  *
390  */
391
392 static void
393 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, 
394               DES_key_schedule *ks3, int forward_encrypt)
395 {
396     IP(u);
397     if (forward_encrypt) {
398         desx(u, ks1, 1); /* IP + FP cancel out each other */
399         desx(u, ks2, 0);
400         desx(u, ks3, 1);
401     } else {
402         desx(u, ks3, 0);
403         desx(u, ks2, 1);
404         desx(u, ks1, 0);
405     }
406     FP(u);
407 }
408
409 /*
410  *
411  */
412
413 void
414 DES_ecb3_encrypt(DES_cblock *input,
415                  DES_cblock *output,
416                  DES_key_schedule *ks1,
417                  DES_key_schedule *ks2,
418                  DES_key_schedule *ks3,
419                  int forward_encrypt)
420 {
421     uint32_t u[2];
422     load(*input, u);
423     _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);
424     store(u, *output);
425     return;
426 }
427
428 /*
429  *
430  */
431
432 void
433 DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
434                      long length, DES_key_schedule *ks1, 
435                      DES_key_schedule *ks2, DES_key_schedule *ks3,
436                      DES_cblock *iv, int forward_encrypt)
437 {
438     uint32_t u[2];
439     uint32_t uiv[2];
440
441     load(*iv, uiv);
442
443     if (forward_encrypt) {
444         while (length >= DES_CBLOCK_LEN) {
445             load(input, u);
446             u[0] ^= uiv[0]; u[1] ^= uiv[1];
447             _des3_encrypt(u, ks1, ks2, ks3, 1);
448             uiv[0] = u[0]; uiv[1] = u[1];
449             store(u, output);
450
451             length -= DES_CBLOCK_LEN;
452             input += DES_CBLOCK_LEN;
453             output += DES_CBLOCK_LEN;
454         }
455         if (length) {
456             unsigned char tmp[DES_CBLOCK_LEN];
457             memcpy(tmp, input, length);
458             memset(tmp + length, 0, DES_CBLOCK_LEN - length);
459             load(tmp, u);
460             u[0] ^= uiv[0]; u[1] ^= uiv[1];
461             _des3_encrypt(u, ks1, ks2, ks3, 1);
462             store(u, output);
463         }
464     } else {
465         uint32_t t[2];
466         while (length >= DES_CBLOCK_LEN) {
467             load(input, u);
468             t[0] = u[0]; t[1] = u[1];
469             _des3_encrypt(u, ks1, ks2, ks3, 0);
470             u[0] ^= uiv[0]; u[1] ^= uiv[1];
471             store(u, output);
472             uiv[0] = t[0]; uiv[1] = t[1];
473
474             length -= DES_CBLOCK_LEN;
475             input += DES_CBLOCK_LEN;
476             output += DES_CBLOCK_LEN;
477         }
478         if (length) {
479             unsigned char tmp[DES_CBLOCK_LEN];
480             memcpy(tmp, input, length);
481             memset(tmp + length, 0, DES_CBLOCK_LEN - length);
482             load(tmp, u);
483             _des3_encrypt(u, ks1, ks2, ks3, 0);
484             u[0] ^= uiv[0]; u[1] ^= uiv[1];
485             store(u, output);
486         }
487     }
488     store(uiv, *iv);
489     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
490 }
491
492 /*
493  *
494  */
495
496 void
497 DES_cfb64_encrypt(unsigned char *input, unsigned char *output, 
498                   long length, DES_key_schedule *ks, DES_cblock *iv,
499                   int *num, int forward_encrypt)
500 {
501     unsigned char tmp[DES_CBLOCK_LEN];
502     uint32_t uiv[2];
503
504     load(*iv, uiv);
505
506     if (forward_encrypt) {
507         int i = *num;
508
509         while (length > 0) {
510             if (i == 0)
511                 DES_encrypt(uiv, ks, 1);
512             store(uiv, tmp);
513             for (; i < DES_CBLOCK_LEN && i < length; i++) {
514                 output[i] = tmp[i] ^ input[i];
515             }
516             if (i == DES_CBLOCK_LEN)
517                 load(output, uiv);
518             output += i;
519             input += i;
520             length -= i;
521             if (i == DES_CBLOCK_LEN)
522                 i = 0;
523         }
524         store(uiv, *iv);
525         *num = i;
526     } else {
527         int i = *num;
528         unsigned char c;
529
530         while (length > 0) {
531             if (i == 0) {
532                 DES_encrypt(uiv, ks, 1);
533                 store(uiv, tmp);
534             }
535             for (; i < DES_CBLOCK_LEN && i < length; i++) {
536                 c = input[i];
537                 output[i] = tmp[i] ^ input[i];
538                 (*iv)[i] = c;
539             }
540             output += i;
541             input += i;
542             length -= i;
543             if (i == DES_CBLOCK_LEN) {
544                 i = 0;
545                 load(*iv, uiv);
546             }
547         }
548         store(uiv, *iv);
549         *num = i;
550     }
551 }
552
553 /*
554  *
555  */
556
557 uint32_t
558 DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
559               long length, DES_key_schedule *ks, DES_cblock *iv)
560 {
561     uint32_t uiv[2];
562     uint32_t u[2] = { 0, 0 };
563
564     load(*iv, uiv);
565
566     while (length >= DES_CBLOCK_LEN) {
567         load(input, u);
568         u[0] ^= uiv[0]; u[1] ^= uiv[1];
569         DES_encrypt(u, ks, 1);
570         uiv[0] = u[0]; uiv[1] = u[1];
571         
572         length -= DES_CBLOCK_LEN;
573         input += DES_CBLOCK_LEN;
574     }
575     if (length) {
576         unsigned char tmp[DES_CBLOCK_LEN];
577         memcpy(tmp, input, length);
578         memset(tmp + length, 0, DES_CBLOCK_LEN - length);
579         load(tmp, u);
580         u[0] ^= uiv[0]; u[1] ^= uiv[1];
581         DES_encrypt(u, ks, 1);
582     }
583     if (output)
584         store(u, *output);
585
586     uiv[0] = 0; u[0] = 0; uiv[1] = 0;
587     return u[1];
588 }
589
590 /*
591  *
592  */
593
594 static unsigned char
595 bitswap8(unsigned char b)
596 {
597     unsigned char r = 0;
598     int i;
599     for (i = 0; i < 8; i++) {
600         r = r << 1 | (b & 1);
601         b = b >> 1;
602     }
603     return r;
604 }
605
606 void
607 DES_string_to_key(const char *str, DES_cblock *key)
608 {
609     const unsigned char *s;
610     unsigned char *k;
611     DES_key_schedule ks;
612     size_t i, len;
613
614     memset(key, 0, sizeof(*key));
615     k = *key;
616     s = (const unsigned char *)str;
617
618     len = strlen(str);
619     for (i = 0; i < len; i++) {
620         if ((i % 16) < 8)
621             k[i % 8] ^= s[i] << 1;
622         else
623             k[7 - (i % 8)] ^= bitswap8(s[i]);
624     }
625     DES_set_odd_parity(key);
626     if (DES_is_weak_key(key))
627         k[7] ^= 0xF0;
628     DES_set_key(key, &ks);
629     DES_cbc_cksum(s, key, len, &ks, key);
630     memset(&ks, 0, sizeof(ks));
631     DES_set_odd_parity(key);
632     if (DES_is_weak_key(key))
633         k[7] ^= 0xF0;
634 }
635
636 /*
637  *
638  */
639
640 int
641 DES_read_password(DES_cblock *key, char *prompt, int verify)
642 {
643     char buf[512];
644     int ret;
645
646     ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
647     if (ret == 0)
648         DES_string_to_key(buf, key);
649     return ret;
650 }
651
652 /*
653  *
654  */
655
656
657 void
658 _DES_ipfp_test(void)
659 {
660     DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
661     uint32_t u[2] = { 1, 0 };
662     IP(u);
663     FP(u);
664     IP(u);
665     FP(u);
666     if (u[0] != 1 || u[1] != 0)
667         abort();
668
669     load(k, u);
670     store(u, k2);
671     if (memcmp(k, k2, 8) != 0)
672         abort();
673 }    
674
675 /* D3DES (V5.09) - 
676  *
677  * A portable, public domain, version of the Data Encryption Standard.
678  *
679  * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
680  * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
681  * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
682  * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
683  * for humouring me on. 
684  *
685  * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
686  * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
687  */
688
689 static uint32_t SP1[64] = {
690     0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
691     0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
692     0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
693     0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
694     0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
695     0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
696     0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
697     0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
698     0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
699     0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
700     0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
701     0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
702     0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
703     0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
704     0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
705     0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
706
707 static uint32_t SP2[64] = {
708     0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
709     0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
710     0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
711     0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
712     0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
713     0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
714     0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
715     0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
716     0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
717     0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
718     0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
719     0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
720     0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
721     0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
722     0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
723     0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
724
725 static uint32_t SP3[64] = {
726     0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
727     0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
728     0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
729     0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
730     0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
731     0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
732     0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
733     0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
734     0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
735     0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
736     0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
737     0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
738     0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
739     0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
740     0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
741     0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
742
743 static uint32_t SP4[64] = {
744     0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
745     0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
746     0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
747     0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
748     0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
749     0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
750     0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
751     0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
752     0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
753     0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
754     0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
755     0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
756     0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
757     0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
758     0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
759     0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
760
761 static uint32_t SP5[64] = {
762     0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
763     0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
764     0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
765     0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
766     0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
767     0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
768     0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
769     0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
770     0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
771     0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
772     0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
773     0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
774     0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
775     0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
776     0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
777     0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
778
779 static uint32_t SP6[64] = {
780     0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
781     0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
782     0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
783     0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
784     0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
785     0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
786     0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
787     0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
788     0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
789     0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
790     0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
791     0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
792     0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
793     0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
794     0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
795     0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
796
797 static uint32_t SP7[64] = {
798     0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
799     0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
800     0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
801     0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
802     0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
803     0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
804     0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
805     0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
806     0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
807     0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
808     0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
809     0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
810     0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
811     0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
812     0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
813     0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
814
815 static uint32_t SP8[64] = {
816     0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
817     0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
818     0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
819     0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
820     0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
821     0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
822     0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
823     0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
824     0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
825     0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
826     0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
827     0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
828     0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
829     0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
830     0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
831     0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
832
833 static void
834 IP(uint32_t v[2])
835 {
836     uint32_t work;
837
838     work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
839     v[1] ^= work;
840     v[0] ^= (work << 4);
841     work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
842     v[1] ^= work;
843     v[0] ^= (work << 16);
844     work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
845     v[0] ^= work;
846     v[1] ^= (work << 2);
847     work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
848     v[0] ^= work;
849     v[1] ^= (work << 8);
850     v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
851     work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
852     v[0] ^= work;
853     v[1] ^= work;
854     v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
855 }
856
857 static void
858 FP(uint32_t v[2])
859 {
860     uint32_t work;
861
862     v[0] = (v[0] << 31) | (v[0] >> 1);
863     work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
864     v[1] ^= work;
865     v[0] ^= work;
866     v[1] = (v[1] << 31) | (v[1] >> 1);
867     work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
868     v[0] ^= work;
869     v[1] ^= (work << 8);
870     work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
871     v[0] ^= work;
872     v[1] ^= (work << 2);
873     work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
874     v[1] ^= work;
875     v[0] ^= (work << 16);
876     work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
877     v[1] ^= work;
878     v[0] ^= (work << 4);
879 }
880
881 static void
882 desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
883 {
884     uint32_t *keys;
885     uint32_t fval, work, right, left;
886     int round;
887
888     left = block[0];
889     right = block[1];
890
891     if (forward_encrypt) {
892         keys = &ks->ks[0];
893
894         for( round = 0; round < 8; round++ ) {
895             work  = (right << 28) | (right >> 4);
896             work ^= *keys++;
897             fval  = SP7[ work     & 0x3fL];
898             fval |= SP5[(work >>  8) & 0x3fL];
899             fval |= SP3[(work >> 16) & 0x3fL];
900             fval |= SP1[(work >> 24) & 0x3fL];
901             work  = right ^ *keys++;
902             fval |= SP8[ work     & 0x3fL];
903             fval |= SP6[(work >>  8) & 0x3fL];
904             fval |= SP4[(work >> 16) & 0x3fL];
905             fval |= SP2[(work >> 24) & 0x3fL];
906             left ^= fval;
907             work  = (left << 28) | (left >> 4);
908             work ^= *keys++;
909             fval  = SP7[ work     & 0x3fL];
910             fval |= SP5[(work >>  8) & 0x3fL];
911             fval |= SP3[(work >> 16) & 0x3fL];
912             fval |= SP1[(work >> 24) & 0x3fL];
913             work  = left ^ *keys++;
914             fval |= SP8[ work     & 0x3fL];
915             fval |= SP6[(work >>  8) & 0x3fL];
916             fval |= SP4[(work >> 16) & 0x3fL];
917             fval |= SP2[(work >> 24) & 0x3fL];
918             right ^= fval;
919         }
920     } else {
921         keys = &ks->ks[30];
922
923         for( round = 0; round < 8; round++ ) {
924             work  = (right << 28) | (right >> 4);
925             work ^= *keys++;
926             fval  = SP7[ work     & 0x3fL];
927             fval |= SP5[(work >>  8) & 0x3fL];
928             fval |= SP3[(work >> 16) & 0x3fL];
929             fval |= SP1[(work >> 24) & 0x3fL];
930             work  = right ^ *keys++;
931             fval |= SP8[ work     & 0x3fL];
932             fval |= SP6[(work >>  8) & 0x3fL];
933             fval |= SP4[(work >> 16) & 0x3fL];
934             fval |= SP2[(work >> 24) & 0x3fL];
935             left ^= fval;
936             work  = (left << 28) | (left >> 4);
937             keys -= 4;
938             work ^= *keys++;
939             fval  = SP7[ work     & 0x3fL];
940             fval |= SP5[(work >>  8) & 0x3fL];
941             fval |= SP3[(work >> 16) & 0x3fL];
942             fval |= SP1[(work >> 24) & 0x3fL];
943             work  = left ^ *keys++;
944             fval |= SP8[ work     & 0x3fL];
945             fval |= SP6[(work >>  8) & 0x3fL];
946             fval |= SP4[(work >> 16) & 0x3fL];
947             fval |= SP2[(work >> 24) & 0x3fL];
948             right ^= fval;
949             keys -= 4;
950         }
951     }
952     block[0] = right;
953     block[1] = left;
954 }