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 * @page page_des DES - Data Encryption Standard crypto interface
37 * See the library functions here: @ref hcrypto_des
39 * DES was created by IBM, modififed by NSA and then adopted by NBS
40 * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1).
42 * Since the 19th May 2005 DES was withdrawn by NIST and should no
43 * longer be used. See @ref page_evp for replacement encryption
44 * algorithms and interfaces.
46 * Read more the iteresting history of DES on Wikipedia
47 * http://www.wikipedia.org/wiki/Data_Encryption_Standard .
49 * @section des_keygen DES key generation
51 * To generate a DES key safely you have to use the code-snippet
52 * below. This is because the DES_random_key() can fail with an
53 * abort() in case of and failure to start the random generator.
55 * There is a replacement function DES_new_random_key(), however that
56 * function does not exists in OpenSSL.
61 * if (RAND_rand(&key, sizeof(key)) != 1)
63 * DES_set_odd_parity(key);
64 * } while (DES_is_weak_key(&key));
67 * @section des_impl DES implementation history
69 * There was no complete BSD licensed, fast, GPL compatible
70 * implementation of DES, so Love wrote the part that was missing,
71 * fast key schedule setup and adapted the interface to the orignal
74 * The document that got me started for real was "Efficient
75 * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
76 * I never got to the PC1 transformation was working, instead I used
77 * table-lookup was used for all key schedule setup. The document was
78 * very useful since it de-mystified other implementations for me.
80 * The core DES function (SBOX + P transformation) is from Richard
81 * Outerbridge public domain DES implementation. My sanity is saved
82 * thanks to his work. Thank you Richard.
95 #include <krb5-types.h>
101 static void desx(uint32_t [2], DES_key_schedule
*, int);
102 static void IP(uint32_t [2]);
103 static void FP(uint32_t [2]);
105 #include "des-tables.h"
107 #define ROTATE_LEFT28(x,one) \
109 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
111 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
115 * Set the parity of the key block, used to generate a des key from a
116 * random key. See @ref des_keygen.
118 * @param key key to fixup the parity for.
119 * @ingroup hcrypto_des
123 DES_set_odd_parity(DES_cblock
*key
)
126 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
127 (*key
)[i
] = odd_parity
[(*key
)[i
]];
131 * Check if the key have correct parity.
133 * @param key key to check the parity.
134 * @return 1 on success, 0 on failure.
135 * @ingroup hcrypto_des
139 DES_check_key_parity(DES_cblock
*key
)
143 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
144 if ((*key
)[i
] != odd_parity
[(*key
)[i
]])
154 static DES_cblock weak_keys
[] = {
155 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
156 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
157 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
158 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
159 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
160 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
161 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
162 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
163 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
164 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
165 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
166 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
167 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
168 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
169 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
170 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
174 * Checks if the key is any of the weaks keys that makes DES attacks
177 * @param key key to check.
179 * @return 1 if the key is weak, 0 otherwise.
180 * @ingroup hcrypto_des
184 DES_is_weak_key(DES_cblock
*key
)
188 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++) {
189 if (memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0)
196 * Setup a des key schedule from a key. Deprecated function, use
197 * DES_set_key_unchecked() or DES_set_key_checked() instead.
199 * @param key a key to initialize the key schedule with.
200 * @param ks a key schedule to initialize.
202 * @return 0 on success
203 * @ingroup hcrypto_des
207 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
209 return DES_set_key_checked(key
, ks
);
213 * Setup a des key schedule from a key. The key is no longer needed
214 * after this transaction and can cleared.
216 * Does NOT check that the key is weak for or have wrong parity.
218 * @param key a key to initialize the key schedule with.
219 * @param ks a key schedule to initialize.
221 * @return 0 on success
222 * @ingroup hcrypto_des
226 DES_set_key_unchecked(DES_cblock
*key
, DES_key_schedule
*ks
)
230 int shifts
[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
231 uint32_t *k
= &ks
->ks
[0];
234 t1
= (*key
)[0] << 24 | (*key
)[1] << 16 | (*key
)[2] << 8 | (*key
)[3];
235 t2
= (*key
)[4] << 24 | (*key
)[5] << 16 | (*key
)[6] << 8 | (*key
)[7];
237 c
= (pc1_c_3
[(t1
>> (5 )) & 0x7] << 3)
238 | (pc1_c_3
[(t1
>> (5 + 8 )) & 0x7] << 2)
239 | (pc1_c_3
[(t1
>> (5 + 8 + 8 )) & 0x7] << 1)
240 | (pc1_c_3
[(t1
>> (5 + 8 + 8 + 8)) & 0x7] << 0)
241 | (pc1_c_4
[(t2
>> (4 )) & 0xf] << 3)
242 | (pc1_c_4
[(t2
>> (4 + 8 )) & 0xf] << 2)
243 | (pc1_c_4
[(t2
>> (4 + 8 + 8 )) & 0xf] << 1)
244 | (pc1_c_4
[(t2
>> (4 + 8 + 8 + 8)) & 0xf] << 0);
247 d
= (pc1_d_3
[(t2
>> (1 )) & 0x7] << 3)
248 | (pc1_d_3
[(t2
>> (1 + 8 )) & 0x7] << 2)
249 | (pc1_d_3
[(t2
>> (1 + 8 + 8 )) & 0x7] << 1)
250 | (pc1_d_3
[(t2
>> (1 + 8 + 8 + 8)) & 0x7] << 0)
251 | (pc1_d_4
[(t1
>> (1 )) & 0xf] << 3)
252 | (pc1_d_4
[(t1
>> (1 + 8 )) & 0xf] << 2)
253 | (pc1_d_4
[(t1
>> (1 + 8 + 8 )) & 0xf] << 1)
254 | (pc1_d_4
[(t1
>> (1 + 8 + 8 + 8)) & 0xf] << 0);
256 for (i
= 0; i
< 16; i
++) {
259 ROTATE_LEFT28(c
, shifts
[i
]);
260 ROTATE_LEFT28(d
, shifts
[i
]);
262 kc
= pc2_c_1
[(c
>> 22) & 0x3f] |
263 pc2_c_2
[((c
>> 16) & 0x30) | ((c
>> 15) & 0xf)] |
264 pc2_c_3
[((c
>> 9 ) & 0x3c) | ((c
>> 8 ) & 0x3)] |
265 pc2_c_4
[((c
>> 2 ) & 0x20) | ((c
>> 1) & 0x18) | (c
& 0x7)];
266 kd
= pc2_d_1
[(d
>> 22) & 0x3f] |
267 pc2_d_2
[((d
>> 15) & 0x30) | ((d
>> 14) & 0xf)] |
268 pc2_d_3
[ (d
>> 7 ) & 0x3f] |
269 pc2_d_4
[((d
>> 1 ) & 0x3c) | ((d
) & 0x3)];
271 /* Change to byte order used by the S boxes */
272 *k
= (kc
& 0x00fc0000L
) << 6;
273 *k
|= (kc
& 0x00000fc0L
) << 10;
274 *k
|= (kd
& 0x00fc0000L
) >> 10;
275 *k
++ |= (kd
& 0x00000fc0L
) >> 6;
276 *k
= (kc
& 0x0003f000L
) << 12;
277 *k
|= (kc
& 0x0000003fL
) << 16;
278 *k
|= (kd
& 0x0003f000L
) >> 4;
279 *k
++ |= (kd
& 0x0000003fL
);
286 * Just like DES_set_key_unchecked() except checking that the key is
287 * not weak for or have correct parity.
289 * @param key a key to initialize the key schedule with.
290 * @param ks a key schedule to initialize.
292 * @return 0 on success, -1 on invalid parity, -2 on weak key.
293 * @ingroup hcrypto_des
297 DES_set_key_checked(DES_cblock
*key
, DES_key_schedule
*ks
)
299 if (!DES_check_key_parity(key
)) {
300 memset(ks
, 0, sizeof(*ks
));
303 if (DES_is_weak_key(key
)) {
304 memset(ks
, 0, sizeof(*ks
));
307 return DES_set_key_unchecked(key
, ks
);
311 * Compatibility function for eay libdes, works just like
312 * DES_set_key_checked().
314 * @param key a key to initialize the key schedule with.
315 * @param ks a key schedule to initialize.
317 * @return 0 on success, -1 on invalid parity, -2 on weak key.
318 * @ingroup hcrypto_des
322 DES_key_sched(DES_cblock
*key
, DES_key_schedule
*ks
)
324 return DES_set_key_checked(key
, ks
);
332 load(const unsigned char *b
, uint32_t v
[2])
345 store(const uint32_t v
[2], unsigned char *b
)
347 b
[0] = (v
[0] >> 24) & 0xff;
348 b
[1] = (v
[0] >> 16) & 0xff;
349 b
[2] = (v
[0] >> 8) & 0xff;
350 b
[3] = (v
[0] >> 0) & 0xff;
351 b
[4] = (v
[1] >> 24) & 0xff;
352 b
[5] = (v
[1] >> 16) & 0xff;
353 b
[6] = (v
[1] >> 8) & 0xff;
354 b
[7] = (v
[1] >> 0) & 0xff;
358 * Encrypt/decrypt a block using DES. Also called ECB mode
360 * @param u data to encrypt
361 * @param ks key schedule to use
362 * @param encp if non zero, encrypt. if zero, decrypt.
364 * @ingroup hcrypto_des
368 DES_encrypt(uint32_t u
[2], DES_key_schedule
*ks
, int encp
)
376 * Encrypt/decrypt a block using DES.
378 * @param input data to encrypt
379 * @param output data to encrypt
380 * @param ks key schedule to use
381 * @param encp if non zero, encrypt. if zero, decrypt.
383 * @ingroup hcrypto_des
387 DES_ecb_encrypt(DES_cblock
*input
, DES_cblock
*output
,
388 DES_key_schedule
*ks
, int encp
)
392 DES_encrypt(u
, ks
, encp
);
397 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
399 * The IV must always be diffrent for diffrent input data blocks.
401 * @param in data to encrypt
402 * @param out data to encrypt
403 * @param length length of data
404 * @param ks key schedule to use
405 * @param iv initial vector to use
406 * @param encp if non zero, encrypt. if zero, decrypt.
408 * @ingroup hcrypto_des
412 DES_cbc_encrypt(const void *in
, void *out
, long length
,
413 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
415 const unsigned char *input
= in
;
416 unsigned char *output
= out
;
423 while (length
>= DES_CBLOCK_LEN
) {
425 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
426 DES_encrypt(u
, ks
, 1);
427 uiv
[0] = u
[0]; uiv
[1] = u
[1];
430 length
-= DES_CBLOCK_LEN
;
431 input
+= DES_CBLOCK_LEN
;
432 output
+= DES_CBLOCK_LEN
;
435 unsigned char tmp
[DES_CBLOCK_LEN
];
436 memcpy(tmp
, input
, length
);
437 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
439 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
440 DES_encrypt(u
, ks
, 1);
445 while (length
>= DES_CBLOCK_LEN
) {
447 t
[0] = u
[0]; t
[1] = u
[1];
448 DES_encrypt(u
, ks
, 0);
449 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
451 uiv
[0] = t
[0]; uiv
[1] = t
[1];
453 length
-= DES_CBLOCK_LEN
;
454 input
+= DES_CBLOCK_LEN
;
455 output
+= DES_CBLOCK_LEN
;
458 unsigned char tmp
[DES_CBLOCK_LEN
];
459 memcpy(tmp
, input
, length
);
460 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
462 DES_encrypt(u
, ks
, 0);
463 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
467 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
471 * Encrypt/decrypt a block using DES in Propagating Cipher Block
472 * Chaining mode. This mode is only used for Kerberos 4, and it should
475 * The IV must always be diffrent for diffrent input data blocks.
477 * @param in data to encrypt
478 * @param out data to encrypt
479 * @param length length of data
480 * @param ks key schedule to use
481 * @param iv initial vector to use
482 * @param encp if non zero, encrypt. if zero, decrypt.
484 * @ingroup hcrypto_des
488 DES_pcbc_encrypt(const void *in
, void *out
, long length
,
489 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
491 const unsigned char *input
= in
;
492 unsigned char *output
= out
;
500 while (length
>= DES_CBLOCK_LEN
) {
502 t
[0] = u
[0]; t
[1] = u
[1];
503 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
504 DES_encrypt(u
, ks
, 1);
505 uiv
[0] = u
[0] ^ t
[0]; uiv
[1] = u
[1] ^ t
[1];
508 length
-= DES_CBLOCK_LEN
;
509 input
+= DES_CBLOCK_LEN
;
510 output
+= DES_CBLOCK_LEN
;
513 unsigned char tmp
[DES_CBLOCK_LEN
];
514 memcpy(tmp
, input
, length
);
515 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
517 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
518 DES_encrypt(u
, ks
, 1);
523 while (length
>= DES_CBLOCK_LEN
) {
525 t
[0] = u
[0]; t
[1] = u
[1];
526 DES_encrypt(u
, ks
, 0);
527 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
529 uiv
[0] = t
[0] ^ u
[0]; uiv
[1] = t
[1] ^ u
[1];
531 length
-= DES_CBLOCK_LEN
;
532 input
+= DES_CBLOCK_LEN
;
533 output
+= DES_CBLOCK_LEN
;
536 unsigned char tmp
[DES_CBLOCK_LEN
];
537 memcpy(tmp
, input
, length
);
538 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
540 DES_encrypt(u
, ks
, 0);
541 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
544 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
552 _des3_encrypt(uint32_t u
[2], DES_key_schedule
*ks1
, DES_key_schedule
*ks2
,
553 DES_key_schedule
*ks3
, int encp
)
557 desx(u
, ks1
, 1); /* IP + FP cancel out each other */
569 * Encrypt/decrypt a block using triple DES using EDE mode,
570 * encrypt/decrypt/encrypt.
572 * @param input data to encrypt
573 * @param output data to encrypt
574 * @param ks1 key schedule to use
575 * @param ks2 key schedule to use
576 * @param ks3 key schedule to use
577 * @param encp if non zero, encrypt. if zero, decrypt.
579 * @ingroup hcrypto_des
583 DES_ecb3_encrypt(DES_cblock
*input
,
585 DES_key_schedule
*ks1
,
586 DES_key_schedule
*ks2
,
587 DES_key_schedule
*ks3
,
592 _des3_encrypt(u
, ks1
, ks2
, ks3
, encp
);
598 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
600 * The IV must always be diffrent for diffrent input data blocks.
602 * @param in data to encrypt
603 * @param out data to encrypt
604 * @param length length of data
605 * @param ks1 key schedule to use
606 * @param ks2 key schedule to use
607 * @param ks3 key schedule to use
608 * @param iv initial vector to use
609 * @param encp if non zero, encrypt. if zero, decrypt.
611 * @ingroup hcrypto_des
615 DES_ede3_cbc_encrypt(const void *in
, void *out
,
616 long length
, DES_key_schedule
*ks1
,
617 DES_key_schedule
*ks2
, DES_key_schedule
*ks3
,
618 DES_cblock
*iv
, int encp
)
620 const unsigned char *input
= in
;
621 unsigned char *output
= out
;
628 while (length
>= DES_CBLOCK_LEN
) {
630 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
631 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
632 uiv
[0] = u
[0]; uiv
[1] = u
[1];
635 length
-= DES_CBLOCK_LEN
;
636 input
+= DES_CBLOCK_LEN
;
637 output
+= DES_CBLOCK_LEN
;
640 unsigned char tmp
[DES_CBLOCK_LEN
];
641 memcpy(tmp
, input
, length
);
642 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
644 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
645 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
650 while (length
>= DES_CBLOCK_LEN
) {
652 t
[0] = u
[0]; t
[1] = u
[1];
653 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
654 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
656 uiv
[0] = t
[0]; uiv
[1] = t
[1];
658 length
-= DES_CBLOCK_LEN
;
659 input
+= DES_CBLOCK_LEN
;
660 output
+= DES_CBLOCK_LEN
;
663 unsigned char tmp
[DES_CBLOCK_LEN
];
664 memcpy(tmp
, input
, length
);
665 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
667 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
668 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
673 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
677 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
680 * The IV must always be diffrent for diffrent input data blocks.
682 * @param in data to encrypt
683 * @param out data to encrypt
684 * @param length length of data
685 * @param ks key schedule to use
686 * @param iv initial vector to use
687 * @param num offset into in cipher block encryption/decryption stop last time.
688 * @param encp if non zero, encrypt. if zero, decrypt.
690 * @ingroup hcrypto_des
694 DES_cfb64_encrypt(const void *in
, void *out
,
695 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
,
698 const unsigned char *input
= in
;
699 unsigned char *output
= out
;
700 unsigned char tmp
[DES_CBLOCK_LEN
];
705 assert(*num
>= 0 && *num
< DES_CBLOCK_LEN
);
712 DES_encrypt(uiv
, ks
, 1);
714 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
715 output
[i
] = tmp
[i
] ^ input
[i
];
717 if (i
== DES_CBLOCK_LEN
)
722 if (i
== DES_CBLOCK_LEN
)
733 DES_encrypt(uiv
, ks
, 1);
736 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
738 output
[i
] = tmp
[i
] ^ input
[i
];
744 if (i
== DES_CBLOCK_LEN
) {
755 * Crete a checksum using DES in CBC encryption mode. This mode is
756 * only used for Kerberos 4, and it should stay that way.
758 * The IV must always be diffrent for diffrent input data blocks.
760 * @param in data to checksum
761 * @param output the checksum
762 * @param length length of data
763 * @param ks key schedule to use
764 * @param iv initial vector to use
766 * @ingroup hcrypto_des
770 DES_cbc_cksum(const void *in
, DES_cblock
*output
,
771 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
)
773 const unsigned char *input
= in
;
775 uint32_t u
[2] = { 0, 0 };
779 while (length
>= DES_CBLOCK_LEN
) {
781 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
782 DES_encrypt(u
, ks
, 1);
783 uiv
[0] = u
[0]; uiv
[1] = u
[1];
785 length
-= DES_CBLOCK_LEN
;
786 input
+= DES_CBLOCK_LEN
;
789 unsigned char tmp
[DES_CBLOCK_LEN
];
790 memcpy(tmp
, input
, length
);
791 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
793 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
794 DES_encrypt(u
, ks
, 1);
799 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
808 bitswap8(unsigned char b
)
812 for (i
= 0; i
< 8; i
++) {
813 r
= r
<< 1 | (b
& 1);
820 * Convert a string to a DES key. Use something like
821 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
823 * @param str The string to convert to a key
824 * @param key the resulting key
826 * @ingroup hcrypto_des
830 DES_string_to_key(const char *str
, DES_cblock
*key
)
832 const unsigned char *s
;
837 memset(key
, 0, sizeof(*key
));
839 s
= (const unsigned char *)str
;
842 for (i
= 0; i
< len
; i
++) {
844 k
[i
% 8] ^= s
[i
] << 1;
846 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
848 DES_set_odd_parity(key
);
849 if (DES_is_weak_key(key
))
851 DES_set_key(key
, &ks
);
852 DES_cbc_cksum(s
, key
, len
, &ks
, key
);
853 memset(&ks
, 0, sizeof(ks
));
854 DES_set_odd_parity(key
);
855 if (DES_is_weak_key(key
))
860 * Read password from prompt and create a DES key. Internal uses
861 * DES_string_to_key(). Really, go use a really string2key function
862 * like PKCS5_PBKDF2_HMAC_SHA1().
864 * @param key key to convert to
865 * @param prompt prompt to display user
866 * @param verify prompt twice.
868 * @return 1 on success, non 1 on failure.
872 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
877 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
879 DES_string_to_key(buf
, key
);
891 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
892 uint32_t u
[2] = { 1, 0 };
897 if (u
[0] != 1 || u
[1] != 0)
902 if (memcmp(k
, k2
, 8) != 0)
908 * A portable, public domain, version of the Data Encryption Standard.
910 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
911 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
912 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
913 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
914 * for humouring me on.
916 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
917 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
920 static uint32_t SP1
[64] = {
921 0x01010400L
, 0x00000000L
, 0x00010000L
, 0x01010404L
,
922 0x01010004L
, 0x00010404L
, 0x00000004L
, 0x00010000L
,
923 0x00000400L
, 0x01010400L
, 0x01010404L
, 0x00000400L
,
924 0x01000404L
, 0x01010004L
, 0x01000000L
, 0x00000004L
,
925 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00010400L
,
926 0x00010400L
, 0x01010000L
, 0x01010000L
, 0x01000404L
,
927 0x00010004L
, 0x01000004L
, 0x01000004L
, 0x00010004L
,
928 0x00000000L
, 0x00000404L
, 0x00010404L
, 0x01000000L
,
929 0x00010000L
, 0x01010404L
, 0x00000004L
, 0x01010000L
,
930 0x01010400L
, 0x01000000L
, 0x01000000L
, 0x00000400L
,
931 0x01010004L
, 0x00010000L
, 0x00010400L
, 0x01000004L
,
932 0x00000400L
, 0x00000004L
, 0x01000404L
, 0x00010404L
,
933 0x01010404L
, 0x00010004L
, 0x01010000L
, 0x01000404L
,
934 0x01000004L
, 0x00000404L
, 0x00010404L
, 0x01010400L
,
935 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00000000L
,
936 0x00010004L
, 0x00010400L
, 0x00000000L
, 0x01010004L
};
938 static uint32_t SP2
[64] = {
939 0x80108020L
, 0x80008000L
, 0x00008000L
, 0x00108020L
,
940 0x00100000L
, 0x00000020L
, 0x80100020L
, 0x80008020L
,
941 0x80000020L
, 0x80108020L
, 0x80108000L
, 0x80000000L
,
942 0x80008000L
, 0x00100000L
, 0x00000020L
, 0x80100020L
,
943 0x00108000L
, 0x00100020L
, 0x80008020L
, 0x00000000L
,
944 0x80000000L
, 0x00008000L
, 0x00108020L
, 0x80100000L
,
945 0x00100020L
, 0x80000020L
, 0x00000000L
, 0x00108000L
,
946 0x00008020L
, 0x80108000L
, 0x80100000L
, 0x00008020L
,
947 0x00000000L
, 0x00108020L
, 0x80100020L
, 0x00100000L
,
948 0x80008020L
, 0x80100000L
, 0x80108000L
, 0x00008000L
,
949 0x80100000L
, 0x80008000L
, 0x00000020L
, 0x80108020L
,
950 0x00108020L
, 0x00000020L
, 0x00008000L
, 0x80000000L
,
951 0x00008020L
, 0x80108000L
, 0x00100000L
, 0x80000020L
,
952 0x00100020L
, 0x80008020L
, 0x80000020L
, 0x00100020L
,
953 0x00108000L
, 0x00000000L
, 0x80008000L
, 0x00008020L
,
954 0x80000000L
, 0x80100020L
, 0x80108020L
, 0x00108000L
};
956 static uint32_t SP3
[64] = {
957 0x00000208L
, 0x08020200L
, 0x00000000L
, 0x08020008L
,
958 0x08000200L
, 0x00000000L
, 0x00020208L
, 0x08000200L
,
959 0x00020008L
, 0x08000008L
, 0x08000008L
, 0x00020000L
,
960 0x08020208L
, 0x00020008L
, 0x08020000L
, 0x00000208L
,
961 0x08000000L
, 0x00000008L
, 0x08020200L
, 0x00000200L
,
962 0x00020200L
, 0x08020000L
, 0x08020008L
, 0x00020208L
,
963 0x08000208L
, 0x00020200L
, 0x00020000L
, 0x08000208L
,
964 0x00000008L
, 0x08020208L
, 0x00000200L
, 0x08000000L
,
965 0x08020200L
, 0x08000000L
, 0x00020008L
, 0x00000208L
,
966 0x00020000L
, 0x08020200L
, 0x08000200L
, 0x00000000L
,
967 0x00000200L
, 0x00020008L
, 0x08020208L
, 0x08000200L
,
968 0x08000008L
, 0x00000200L
, 0x00000000L
, 0x08020008L
,
969 0x08000208L
, 0x00020000L
, 0x08000000L
, 0x08020208L
,
970 0x00000008L
, 0x00020208L
, 0x00020200L
, 0x08000008L
,
971 0x08020000L
, 0x08000208L
, 0x00000208L
, 0x08020000L
,
972 0x00020208L
, 0x00000008L
, 0x08020008L
, 0x00020200L
};
974 static uint32_t SP4
[64] = {
975 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
976 0x00802080L
, 0x00800081L
, 0x00800001L
, 0x00002001L
,
977 0x00000000L
, 0x00802000L
, 0x00802000L
, 0x00802081L
,
978 0x00000081L
, 0x00000000L
, 0x00800080L
, 0x00800001L
,
979 0x00000001L
, 0x00002000L
, 0x00800000L
, 0x00802001L
,
980 0x00000080L
, 0x00800000L
, 0x00002001L
, 0x00002080L
,
981 0x00800081L
, 0x00000001L
, 0x00002080L
, 0x00800080L
,
982 0x00002000L
, 0x00802080L
, 0x00802081L
, 0x00000081L
,
983 0x00800080L
, 0x00800001L
, 0x00802000L
, 0x00802081L
,
984 0x00000081L
, 0x00000000L
, 0x00000000L
, 0x00802000L
,
985 0x00002080L
, 0x00800080L
, 0x00800081L
, 0x00000001L
,
986 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
987 0x00802081L
, 0x00000081L
, 0x00000001L
, 0x00002000L
,
988 0x00800001L
, 0x00002001L
, 0x00802080L
, 0x00800081L
,
989 0x00002001L
, 0x00002080L
, 0x00800000L
, 0x00802001L
,
990 0x00000080L
, 0x00800000L
, 0x00002000L
, 0x00802080L
};
992 static uint32_t SP5
[64] = {
993 0x00000100L
, 0x02080100L
, 0x02080000L
, 0x42000100L
,
994 0x00080000L
, 0x00000100L
, 0x40000000L
, 0x02080000L
,
995 0x40080100L
, 0x00080000L
, 0x02000100L
, 0x40080100L
,
996 0x42000100L
, 0x42080000L
, 0x00080100L
, 0x40000000L
,
997 0x02000000L
, 0x40080000L
, 0x40080000L
, 0x00000000L
,
998 0x40000100L
, 0x42080100L
, 0x42080100L
, 0x02000100L
,
999 0x42080000L
, 0x40000100L
, 0x00000000L
, 0x42000000L
,
1000 0x02080100L
, 0x02000000L
, 0x42000000L
, 0x00080100L
,
1001 0x00080000L
, 0x42000100L
, 0x00000100L
, 0x02000000L
,
1002 0x40000000L
, 0x02080000L
, 0x42000100L
, 0x40080100L
,
1003 0x02000100L
, 0x40000000L
, 0x42080000L
, 0x02080100L
,
1004 0x40080100L
, 0x00000100L
, 0x02000000L
, 0x42080000L
,
1005 0x42080100L
, 0x00080100L
, 0x42000000L
, 0x42080100L
,
1006 0x02080000L
, 0x00000000L
, 0x40080000L
, 0x42000000L
,
1007 0x00080100L
, 0x02000100L
, 0x40000100L
, 0x00080000L
,
1008 0x00000000L
, 0x40080000L
, 0x02080100L
, 0x40000100L
};
1010 static uint32_t SP6
[64] = {
1011 0x20000010L
, 0x20400000L
, 0x00004000L
, 0x20404010L
,
1012 0x20400000L
, 0x00000010L
, 0x20404010L
, 0x00400000L
,
1013 0x20004000L
, 0x00404010L
, 0x00400000L
, 0x20000010L
,
1014 0x00400010L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1015 0x00000000L
, 0x00400010L
, 0x20004010L
, 0x00004000L
,
1016 0x00404000L
, 0x20004010L
, 0x00000010L
, 0x20400010L
,
1017 0x20400010L
, 0x00000000L
, 0x00404010L
, 0x20404000L
,
1018 0x00004010L
, 0x00404000L
, 0x20404000L
, 0x20000000L
,
1019 0x20004000L
, 0x00000010L
, 0x20400010L
, 0x00404000L
,
1020 0x20404010L
, 0x00400000L
, 0x00004010L
, 0x20000010L
,
1021 0x00400000L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1022 0x20000010L
, 0x20404010L
, 0x00404000L
, 0x20400000L
,
1023 0x00404010L
, 0x20404000L
, 0x00000000L
, 0x20400010L
,
1024 0x00000010L
, 0x00004000L
, 0x20400000L
, 0x00404010L
,
1025 0x00004000L
, 0x00400010L
, 0x20004010L
, 0x00000000L
,
1026 0x20404000L
, 0x20000000L
, 0x00400010L
, 0x20004010L
};
1028 static uint32_t SP7
[64] = {
1029 0x00200000L
, 0x04200002L
, 0x04000802L
, 0x00000000L
,
1030 0x00000800L
, 0x04000802L
, 0x00200802L
, 0x04200800L
,
1031 0x04200802L
, 0x00200000L
, 0x00000000L
, 0x04000002L
,
1032 0x00000002L
, 0x04000000L
, 0x04200002L
, 0x00000802L
,
1033 0x04000800L
, 0x00200802L
, 0x00200002L
, 0x04000800L
,
1034 0x04000002L
, 0x04200000L
, 0x04200800L
, 0x00200002L
,
1035 0x04200000L
, 0x00000800L
, 0x00000802L
, 0x04200802L
,
1036 0x00200800L
, 0x00000002L
, 0x04000000L
, 0x00200800L
,
1037 0x04000000L
, 0x00200800L
, 0x00200000L
, 0x04000802L
,
1038 0x04000802L
, 0x04200002L
, 0x04200002L
, 0x00000002L
,
1039 0x00200002L
, 0x04000000L
, 0x04000800L
, 0x00200000L
,
1040 0x04200800L
, 0x00000802L
, 0x00200802L
, 0x04200800L
,
1041 0x00000802L
, 0x04000002L
, 0x04200802L
, 0x04200000L
,
1042 0x00200800L
, 0x00000000L
, 0x00000002L
, 0x04200802L
,
1043 0x00000000L
, 0x00200802L
, 0x04200000L
, 0x00000800L
,
1044 0x04000002L
, 0x04000800L
, 0x00000800L
, 0x00200002L
};
1046 static uint32_t SP8
[64] = {
1047 0x10001040L
, 0x00001000L
, 0x00040000L
, 0x10041040L
,
1048 0x10000000L
, 0x10001040L
, 0x00000040L
, 0x10000000L
,
1049 0x00040040L
, 0x10040000L
, 0x10041040L
, 0x00041000L
,
1050 0x10041000L
, 0x00041040L
, 0x00001000L
, 0x00000040L
,
1051 0x10040000L
, 0x10000040L
, 0x10001000L
, 0x00001040L
,
1052 0x00041000L
, 0x00040040L
, 0x10040040L
, 0x10041000L
,
1053 0x00001040L
, 0x00000000L
, 0x00000000L
, 0x10040040L
,
1054 0x10000040L
, 0x10001000L
, 0x00041040L
, 0x00040000L
,
1055 0x00041040L
, 0x00040000L
, 0x10041000L
, 0x00001000L
,
1056 0x00000040L
, 0x10040040L
, 0x00001000L
, 0x00041040L
,
1057 0x10001000L
, 0x00000040L
, 0x10000040L
, 0x10040000L
,
1058 0x10040040L
, 0x10000000L
, 0x00040000L
, 0x10001040L
,
1059 0x00000000L
, 0x10041040L
, 0x00040040L
, 0x10000040L
,
1060 0x10040000L
, 0x10001000L
, 0x10001040L
, 0x00000000L
,
1061 0x10041040L
, 0x00041000L
, 0x00041000L
, 0x00001040L
,
1062 0x00001040L
, 0x00040040L
, 0x10000000L
, 0x10041000L
};
1069 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1071 v
[0] ^= (work
<< 4);
1072 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1074 v
[0] ^= (work
<< 16);
1075 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1077 v
[1] ^= (work
<< 2);
1078 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1080 v
[1] ^= (work
<< 8);
1081 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
1082 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
1085 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
1093 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
1094 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
1097 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
1098 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1100 v
[1] ^= (work
<< 8);
1101 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1103 v
[1] ^= (work
<< 2);
1104 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1106 v
[0] ^= (work
<< 16);
1107 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1109 v
[0] ^= (work
<< 4);
1113 desx(uint32_t block
[2], DES_key_schedule
*ks
, int encp
)
1116 uint32_t fval
, work
, right
, left
;
1125 for( round
= 0; round
< 8; round
++ ) {
1126 work
= (right
<< 28) | (right
>> 4);
1128 fval
= SP7
[ work
& 0x3fL
];
1129 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1130 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1131 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1132 work
= right
^ *keys
++;
1133 fval
|= SP8
[ work
& 0x3fL
];
1134 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1135 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1136 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1138 work
= (left
<< 28) | (left
>> 4);
1140 fval
= SP7
[ work
& 0x3fL
];
1141 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1142 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1143 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1144 work
= left
^ *keys
++;
1145 fval
|= SP8
[ work
& 0x3fL
];
1146 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1147 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1148 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1154 for( round
= 0; round
< 8; round
++ ) {
1155 work
= (right
<< 28) | (right
>> 4);
1157 fval
= SP7
[ work
& 0x3fL
];
1158 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1159 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1160 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1161 work
= right
^ *keys
++;
1162 fval
|= SP8
[ work
& 0x3fL
];
1163 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1164 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1165 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1167 work
= (left
<< 28) | (left
>> 4);
1170 fval
= SP7
[ work
& 0x3fL
];
1171 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1172 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1173 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1174 work
= left
^ *keys
++;
1175 fval
|= SP8
[ work
& 0x3fL
];
1176 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1177 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1178 fval
|= SP2
[(work
>> 24) & 0x3fL
];