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