2 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
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.
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.
54 #include <krb5-types.h>
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]);
64 #include "des-tables.h"
66 #define ROTATE_LEFT28(x,one) \
68 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
70 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
78 DES_set_odd_parity(DES_cblock
*key
)
81 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
82 (*key
)[i
] = odd_parity
[(*key
)[i
]];
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}
111 DES_is_weak_key(DES_cblock
*key
)
115 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++) {
116 if (memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0)
128 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
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];
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];
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);
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);
158 for (i
= 0; i
< 16; i
++) {
161 ROTATE_LEFT28(c
, shifts
[i
]);
162 ROTATE_LEFT28(d
, shifts
[i
]);
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)];
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
);
192 DES_set_key_checked(DES_cblock
*key
, DES_key_schedule
*ks
)
194 if (DES_is_weak_key(key
)) {
195 memset(ks
, 0, sizeof(*ks
));
198 return DES_set_key(key
, ks
);
202 * Compatibility function for eay libdes
206 DES_key_sched(DES_cblock
*key
, DES_key_schedule
*ks
)
208 return DES_set_key(key
, ks
);
216 load(const unsigned char *b
, uint32_t v
[2])
229 store(const uint32_t v
[2], unsigned char *b
)
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;
246 DES_encrypt(uint32_t u
[2], DES_key_schedule
*ks
, int forward_encrypt
)
249 desx(u
, ks
, forward_encrypt
);
258 DES_ecb_encrypt(DES_cblock
*input
, DES_cblock
*output
,
259 DES_key_schedule
*ks
, int forward_encrypt
)
263 DES_encrypt(u
, ks
, forward_encrypt
);
272 DES_cbc_encrypt(const void *in
, void *out
, long length
,
273 DES_key_schedule
*ks
, DES_cblock
*iv
, int forward_encrypt
)
275 const unsigned char *input
= in
;
276 unsigned char *output
= out
;
282 if (forward_encrypt
) {
283 while (length
>= DES_CBLOCK_LEN
) {
285 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
286 DES_encrypt(u
, ks
, 1);
287 uiv
[0] = u
[0]; uiv
[1] = u
[1];
290 length
-= DES_CBLOCK_LEN
;
291 input
+= DES_CBLOCK_LEN
;
292 output
+= DES_CBLOCK_LEN
;
295 unsigned char tmp
[DES_CBLOCK_LEN
];
296 memcpy(tmp
, input
, length
);
297 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
299 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
300 DES_encrypt(u
, ks
, 1);
305 while (length
>= DES_CBLOCK_LEN
) {
307 t
[0] = u
[0]; t
[1] = u
[1];
308 DES_encrypt(u
, ks
, 0);
309 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
311 uiv
[0] = t
[0]; uiv
[1] = t
[1];
313 length
-= DES_CBLOCK_LEN
;
314 input
+= DES_CBLOCK_LEN
;
315 output
+= DES_CBLOCK_LEN
;
318 unsigned char tmp
[DES_CBLOCK_LEN
];
319 memcpy(tmp
, input
, length
);
320 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
322 DES_encrypt(u
, ks
, 0);
323 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
327 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
335 DES_pcbc_encrypt(const void *in
, void *out
, long length
,
336 DES_key_schedule
*ks
, DES_cblock
*iv
, int forward_encrypt
)
338 const unsigned char *input
= in
;
339 unsigned char *output
= out
;
345 if (forward_encrypt
) {
347 while (length
>= DES_CBLOCK_LEN
) {
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];
355 length
-= DES_CBLOCK_LEN
;
356 input
+= DES_CBLOCK_LEN
;
357 output
+= DES_CBLOCK_LEN
;
360 unsigned char tmp
[DES_CBLOCK_LEN
];
361 memcpy(tmp
, input
, length
);
362 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
364 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
365 DES_encrypt(u
, ks
, 1);
370 while (length
>= DES_CBLOCK_LEN
) {
372 t
[0] = u
[0]; t
[1] = u
[1];
373 DES_encrypt(u
, ks
, 0);
374 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
376 uiv
[0] = t
[0] ^ u
[0]; uiv
[1] = t
[1] ^ u
[1];
378 length
-= DES_CBLOCK_LEN
;
379 input
+= DES_CBLOCK_LEN
;
380 output
+= DES_CBLOCK_LEN
;
383 unsigned char tmp
[DES_CBLOCK_LEN
];
384 memcpy(tmp
, input
, length
);
385 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
387 DES_encrypt(u
, ks
, 0);
388 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
391 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
399 _des3_encrypt(uint32_t u
[2], DES_key_schedule
*ks1
, DES_key_schedule
*ks2
,
400 DES_key_schedule
*ks3
, int forward_encrypt
)
403 if (forward_encrypt
) {
404 desx(u
, ks1
, 1); /* IP + FP cancel out each other */
420 DES_ecb3_encrypt(DES_cblock
*input
,
422 DES_key_schedule
*ks1
,
423 DES_key_schedule
*ks2
,
424 DES_key_schedule
*ks3
,
429 _des3_encrypt(u
, ks1
, ks2
, ks3
, forward_encrypt
);
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
)
444 const unsigned char *input
= in
;
445 unsigned char *output
= out
;
451 if (forward_encrypt
) {
452 while (length
>= DES_CBLOCK_LEN
) {
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];
459 length
-= DES_CBLOCK_LEN
;
460 input
+= DES_CBLOCK_LEN
;
461 output
+= DES_CBLOCK_LEN
;
464 unsigned char tmp
[DES_CBLOCK_LEN
];
465 memcpy(tmp
, input
, length
);
466 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
468 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
469 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
474 while (length
>= DES_CBLOCK_LEN
) {
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];
480 uiv
[0] = t
[0]; uiv
[1] = t
[1];
482 length
-= DES_CBLOCK_LEN
;
483 input
+= DES_CBLOCK_LEN
;
484 output
+= DES_CBLOCK_LEN
;
487 unsigned char tmp
[DES_CBLOCK_LEN
];
488 memcpy(tmp
, input
, length
);
489 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
491 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
492 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
497 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
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
)
509 const unsigned char *input
= in
;
510 unsigned char *output
= out
;
511 unsigned char tmp
[DES_CBLOCK_LEN
];
516 assert(*num
>= 0 && *num
< DES_CBLOCK_LEN
);
518 if (forward_encrypt
) {
523 DES_encrypt(uiv
, ks
, 1);
525 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
526 output
[i
] = tmp
[i
] ^ input
[i
];
528 if (i
== DES_CBLOCK_LEN
)
533 if (i
== DES_CBLOCK_LEN
)
544 DES_encrypt(uiv
, ks
, 1);
547 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
549 output
[i
] = tmp
[i
] ^ input
[i
];
555 if (i
== DES_CBLOCK_LEN
) {
570 DES_cbc_cksum(const void *in
, DES_cblock
*output
,
571 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
)
573 const unsigned char *input
= in
;
575 uint32_t u
[2] = { 0, 0 };
579 while (length
>= DES_CBLOCK_LEN
) {
581 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
582 DES_encrypt(u
, ks
, 1);
583 uiv
[0] = u
[0]; uiv
[1] = u
[1];
585 length
-= DES_CBLOCK_LEN
;
586 input
+= DES_CBLOCK_LEN
;
589 unsigned char tmp
[DES_CBLOCK_LEN
];
590 memcpy(tmp
, input
, length
);
591 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
593 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
594 DES_encrypt(u
, ks
, 1);
599 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
608 bitswap8(unsigned char b
)
612 for (i
= 0; i
< 8; i
++) {
613 r
= r
<< 1 | (b
& 1);
620 DES_string_to_key(const char *str
, DES_cblock
*key
)
622 const unsigned char *s
;
627 memset(key
, 0, sizeof(*key
));
629 s
= (const unsigned char *)str
;
632 for (i
= 0; i
< len
; i
++) {
634 k
[i
% 8] ^= s
[i
] << 1;
636 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
638 DES_set_odd_parity(key
);
639 if (DES_is_weak_key(key
))
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
))
654 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
659 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
661 DES_string_to_key(buf
, key
);
673 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
674 uint32_t u
[2] = { 1, 0 };
679 if (u
[0] != 1 || u
[1] != 0)
684 if (memcmp(k
, k2
, 8) != 0)
690 * A portable, public domain, version of the Data Encryption Standard.
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.
698 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
699 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
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
};
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
};
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
};
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
};
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
};
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
};
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
};
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
};
851 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
854 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
856 v
[0] ^= (work
<< 16);
857 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
860 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
863 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
864 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
867 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
875 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
876 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
879 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
880 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
883 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
886 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
888 v
[0] ^= (work
<< 16);
889 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
895 desx(uint32_t block
[2], DES_key_schedule
*ks
, int forward_encrypt
)
898 uint32_t fval
, work
, right
, left
;
904 if (forward_encrypt
) {
907 for( round
= 0; round
< 8; round
++ ) {
908 work
= (right
<< 28) | (right
>> 4);
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
];
920 work
= (left
<< 28) | (left
>> 4);
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
];
936 for( round
= 0; round
< 8; round
++ ) {
937 work
= (right
<< 28) | (right
>> 4);
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
];
949 work
= (left
<< 28) | (left
>> 4);
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
];