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.
89 #include <krb5-types.h>
95 static void desx(uint32_t [2], DES_key_schedule
*, int);
96 static void IP(uint32_t [2]);
97 static void FP(uint32_t [2]);
99 #include "des-tables.h"
101 #define ROTATE_LEFT28(x,one) \
103 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
105 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
109 * Set the parity of the key block, used to generate a des key from a
110 * random key. See @ref des_keygen.
112 * @param key key to fixup the parity for.
113 * @ingroup hcrypto_des
117 DES_set_odd_parity(DES_cblock
*key
)
120 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
121 (*key
)[i
] = odd_parity
[(*key
)[i
]];
125 * Check if the key have correct parity.
127 * @param key key to check the parity.
128 * @return 1 on success, 0 on failure.
129 * @ingroup hcrypto_des
133 DES_check_key_parity(DES_cblock
*key
)
137 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
138 if ((*key
)[i
] != odd_parity
[(*key
)[i
]])
148 static DES_cblock weak_keys
[] = {
149 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
150 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
151 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
152 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
153 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
154 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
155 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
156 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
157 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
158 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
159 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
160 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
161 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
162 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
163 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
164 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
168 * Checks if the key is any of the weaks keys that makes DES attacks
171 * @param key key to check.
173 * @return 1 if the key is weak, 0 otherwise.
174 * @ingroup hcrypto_des
178 DES_is_weak_key(DES_cblock
*key
)
183 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++)
184 weak
^= (ct_memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0);
190 * Setup a des key schedule from a key. Deprecated function, use
191 * DES_set_key_unchecked() or DES_set_key_checked() instead.
193 * @param key a key to initialize the key schedule with.
194 * @param ks a key schedule to initialize.
196 * @return 0 on success
197 * @ingroup hcrypto_des
201 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
203 return DES_set_key_checked(key
, ks
);
207 * Setup a des key schedule from a key. The key is no longer needed
208 * after this transaction and can cleared.
210 * Does NOT check that the key is weak for or have wrong parity.
212 * @param key a key to initialize the key schedule with.
213 * @param ks a key schedule to initialize.
215 * @return 0 on success
216 * @ingroup hcrypto_des
220 DES_set_key_unchecked(DES_cblock
*key
, DES_key_schedule
*ks
)
224 int shifts
[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
225 uint32_t *k
= &ks
->ks
[0];
228 t1
= (uint32_t)((*key
)[0]) << 24
229 | (uint32_t)((*key
)[1]) << 16
230 | (uint32_t)((*key
)[2]) << 8
232 t2
= (uint32_t)((*key
)[4]) << 24
233 | (uint32_t)((*key
)[5]) << 16
234 | (uint32_t)((*key
)[6]) << 8
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])
334 v
[0] = (uint32_t)(b
[0]) << 24;
335 v
[0] |= (uint32_t)(b
[1]) << 16;
336 v
[0] |= (uint32_t)(b
[2]) << 8;
338 v
[1] = (uint32_t)(b
[4]) << 24;
339 v
[1] |= (uint32_t)(b
[5]) << 16;
340 v
[1] |= (uint32_t)(b
[6]) << 8;
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
)
731 memset(tmp
, 0, DES_CBLOCK_LEN
);
734 DES_encrypt(uiv
, ks
, 1);
737 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
739 output
[i
] = tmp
[i
] ^ input
[i
];
745 if (i
== DES_CBLOCK_LEN
) {
756 * Crete a checksum using DES in CBC encryption mode. This mode is
757 * only used for Kerberos 4, and it should stay that way.
759 * The IV must always be diffrent for diffrent input data blocks.
761 * @param in data to checksum
762 * @param output the checksum
763 * @param length length of data
764 * @param ks key schedule to use
765 * @param iv initial vector to use
767 * @ingroup hcrypto_des
771 DES_cbc_cksum(const void *in
, DES_cblock
*output
,
772 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
)
774 const unsigned char *input
= in
;
776 uint32_t u
[2] = { 0, 0 };
780 while (length
>= DES_CBLOCK_LEN
) {
782 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
783 DES_encrypt(u
, ks
, 1);
784 uiv
[0] = u
[0]; uiv
[1] = u
[1];
786 length
-= DES_CBLOCK_LEN
;
787 input
+= DES_CBLOCK_LEN
;
790 unsigned char tmp
[DES_CBLOCK_LEN
];
791 memcpy(tmp
, input
, length
);
792 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
794 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
795 DES_encrypt(u
, ks
, 1);
800 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
809 bitswap8(unsigned char b
)
813 for (i
= 0; i
< 8; i
++) {
814 r
= r
<< 1 | (b
& 1);
821 * Convert a string to a DES key. Use something like
822 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
824 * @param str The string to convert to a key
825 * @param key the resulting key
827 * @ingroup hcrypto_des
831 DES_string_to_key(const char *str
, DES_cblock
*key
)
833 const unsigned char *s
;
838 memset(key
, 0, sizeof(*key
));
840 s
= (const unsigned char *)str
;
843 for (i
= 0; i
< len
; i
++) {
845 k
[i
% 8] ^= s
[i
] << 1;
847 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
849 DES_set_odd_parity(key
);
850 if (DES_is_weak_key(key
))
852 DES_set_key(key
, &ks
);
853 DES_cbc_cksum(s
, key
, len
, &ks
, key
);
854 memset_s(&ks
, sizeof(ks
), 0, sizeof(ks
));
855 DES_set_odd_parity(key
);
856 if (DES_is_weak_key(key
))
861 * Read password from prompt and create a DES key. Internal uses
862 * DES_string_to_key(). Really, go use a really string2key function
863 * like PKCS5_PBKDF2_HMAC_SHA1().
865 * @param key key to convert to
866 * @param prompt prompt to display user
867 * @param verify prompt twice.
869 * @return 1 on success, non 1 on failure.
873 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
878 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
880 DES_string_to_key(buf
, key
);
892 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
893 uint32_t u
[2] = { 1, 0 };
898 if (u
[0] != 1 || u
[1] != 0)
903 if (memcmp(k
, k2
, 8) != 0)
909 * A portable, public domain, version of the Data Encryption Standard.
911 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
912 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
913 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
914 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
915 * for humouring me on.
917 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
918 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
921 static uint32_t SP1
[64] = {
922 0x01010400L
, 0x00000000L
, 0x00010000L
, 0x01010404L
,
923 0x01010004L
, 0x00010404L
, 0x00000004L
, 0x00010000L
,
924 0x00000400L
, 0x01010400L
, 0x01010404L
, 0x00000400L
,
925 0x01000404L
, 0x01010004L
, 0x01000000L
, 0x00000004L
,
926 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00010400L
,
927 0x00010400L
, 0x01010000L
, 0x01010000L
, 0x01000404L
,
928 0x00010004L
, 0x01000004L
, 0x01000004L
, 0x00010004L
,
929 0x00000000L
, 0x00000404L
, 0x00010404L
, 0x01000000L
,
930 0x00010000L
, 0x01010404L
, 0x00000004L
, 0x01010000L
,
931 0x01010400L
, 0x01000000L
, 0x01000000L
, 0x00000400L
,
932 0x01010004L
, 0x00010000L
, 0x00010400L
, 0x01000004L
,
933 0x00000400L
, 0x00000004L
, 0x01000404L
, 0x00010404L
,
934 0x01010404L
, 0x00010004L
, 0x01010000L
, 0x01000404L
,
935 0x01000004L
, 0x00000404L
, 0x00010404L
, 0x01010400L
,
936 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00000000L
,
937 0x00010004L
, 0x00010400L
, 0x00000000L
, 0x01010004L
};
939 static uint32_t SP2
[64] = {
940 0x80108020L
, 0x80008000L
, 0x00008000L
, 0x00108020L
,
941 0x00100000L
, 0x00000020L
, 0x80100020L
, 0x80008020L
,
942 0x80000020L
, 0x80108020L
, 0x80108000L
, 0x80000000L
,
943 0x80008000L
, 0x00100000L
, 0x00000020L
, 0x80100020L
,
944 0x00108000L
, 0x00100020L
, 0x80008020L
, 0x00000000L
,
945 0x80000000L
, 0x00008000L
, 0x00108020L
, 0x80100000L
,
946 0x00100020L
, 0x80000020L
, 0x00000000L
, 0x00108000L
,
947 0x00008020L
, 0x80108000L
, 0x80100000L
, 0x00008020L
,
948 0x00000000L
, 0x00108020L
, 0x80100020L
, 0x00100000L
,
949 0x80008020L
, 0x80100000L
, 0x80108000L
, 0x00008000L
,
950 0x80100000L
, 0x80008000L
, 0x00000020L
, 0x80108020L
,
951 0x00108020L
, 0x00000020L
, 0x00008000L
, 0x80000000L
,
952 0x00008020L
, 0x80108000L
, 0x00100000L
, 0x80000020L
,
953 0x00100020L
, 0x80008020L
, 0x80000020L
, 0x00100020L
,
954 0x00108000L
, 0x00000000L
, 0x80008000L
, 0x00008020L
,
955 0x80000000L
, 0x80100020L
, 0x80108020L
, 0x00108000L
};
957 static uint32_t SP3
[64] = {
958 0x00000208L
, 0x08020200L
, 0x00000000L
, 0x08020008L
,
959 0x08000200L
, 0x00000000L
, 0x00020208L
, 0x08000200L
,
960 0x00020008L
, 0x08000008L
, 0x08000008L
, 0x00020000L
,
961 0x08020208L
, 0x00020008L
, 0x08020000L
, 0x00000208L
,
962 0x08000000L
, 0x00000008L
, 0x08020200L
, 0x00000200L
,
963 0x00020200L
, 0x08020000L
, 0x08020008L
, 0x00020208L
,
964 0x08000208L
, 0x00020200L
, 0x00020000L
, 0x08000208L
,
965 0x00000008L
, 0x08020208L
, 0x00000200L
, 0x08000000L
,
966 0x08020200L
, 0x08000000L
, 0x00020008L
, 0x00000208L
,
967 0x00020000L
, 0x08020200L
, 0x08000200L
, 0x00000000L
,
968 0x00000200L
, 0x00020008L
, 0x08020208L
, 0x08000200L
,
969 0x08000008L
, 0x00000200L
, 0x00000000L
, 0x08020008L
,
970 0x08000208L
, 0x00020000L
, 0x08000000L
, 0x08020208L
,
971 0x00000008L
, 0x00020208L
, 0x00020200L
, 0x08000008L
,
972 0x08020000L
, 0x08000208L
, 0x00000208L
, 0x08020000L
,
973 0x00020208L
, 0x00000008L
, 0x08020008L
, 0x00020200L
};
975 static uint32_t SP4
[64] = {
976 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
977 0x00802080L
, 0x00800081L
, 0x00800001L
, 0x00002001L
,
978 0x00000000L
, 0x00802000L
, 0x00802000L
, 0x00802081L
,
979 0x00000081L
, 0x00000000L
, 0x00800080L
, 0x00800001L
,
980 0x00000001L
, 0x00002000L
, 0x00800000L
, 0x00802001L
,
981 0x00000080L
, 0x00800000L
, 0x00002001L
, 0x00002080L
,
982 0x00800081L
, 0x00000001L
, 0x00002080L
, 0x00800080L
,
983 0x00002000L
, 0x00802080L
, 0x00802081L
, 0x00000081L
,
984 0x00800080L
, 0x00800001L
, 0x00802000L
, 0x00802081L
,
985 0x00000081L
, 0x00000000L
, 0x00000000L
, 0x00802000L
,
986 0x00002080L
, 0x00800080L
, 0x00800081L
, 0x00000001L
,
987 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
988 0x00802081L
, 0x00000081L
, 0x00000001L
, 0x00002000L
,
989 0x00800001L
, 0x00002001L
, 0x00802080L
, 0x00800081L
,
990 0x00002001L
, 0x00002080L
, 0x00800000L
, 0x00802001L
,
991 0x00000080L
, 0x00800000L
, 0x00002000L
, 0x00802080L
};
993 static uint32_t SP5
[64] = {
994 0x00000100L
, 0x02080100L
, 0x02080000L
, 0x42000100L
,
995 0x00080000L
, 0x00000100L
, 0x40000000L
, 0x02080000L
,
996 0x40080100L
, 0x00080000L
, 0x02000100L
, 0x40080100L
,
997 0x42000100L
, 0x42080000L
, 0x00080100L
, 0x40000000L
,
998 0x02000000L
, 0x40080000L
, 0x40080000L
, 0x00000000L
,
999 0x40000100L
, 0x42080100L
, 0x42080100L
, 0x02000100L
,
1000 0x42080000L
, 0x40000100L
, 0x00000000L
, 0x42000000L
,
1001 0x02080100L
, 0x02000000L
, 0x42000000L
, 0x00080100L
,
1002 0x00080000L
, 0x42000100L
, 0x00000100L
, 0x02000000L
,
1003 0x40000000L
, 0x02080000L
, 0x42000100L
, 0x40080100L
,
1004 0x02000100L
, 0x40000000L
, 0x42080000L
, 0x02080100L
,
1005 0x40080100L
, 0x00000100L
, 0x02000000L
, 0x42080000L
,
1006 0x42080100L
, 0x00080100L
, 0x42000000L
, 0x42080100L
,
1007 0x02080000L
, 0x00000000L
, 0x40080000L
, 0x42000000L
,
1008 0x00080100L
, 0x02000100L
, 0x40000100L
, 0x00080000L
,
1009 0x00000000L
, 0x40080000L
, 0x02080100L
, 0x40000100L
};
1011 static uint32_t SP6
[64] = {
1012 0x20000010L
, 0x20400000L
, 0x00004000L
, 0x20404010L
,
1013 0x20400000L
, 0x00000010L
, 0x20404010L
, 0x00400000L
,
1014 0x20004000L
, 0x00404010L
, 0x00400000L
, 0x20000010L
,
1015 0x00400010L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1016 0x00000000L
, 0x00400010L
, 0x20004010L
, 0x00004000L
,
1017 0x00404000L
, 0x20004010L
, 0x00000010L
, 0x20400010L
,
1018 0x20400010L
, 0x00000000L
, 0x00404010L
, 0x20404000L
,
1019 0x00004010L
, 0x00404000L
, 0x20404000L
, 0x20000000L
,
1020 0x20004000L
, 0x00000010L
, 0x20400010L
, 0x00404000L
,
1021 0x20404010L
, 0x00400000L
, 0x00004010L
, 0x20000010L
,
1022 0x00400000L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1023 0x20000010L
, 0x20404010L
, 0x00404000L
, 0x20400000L
,
1024 0x00404010L
, 0x20404000L
, 0x00000000L
, 0x20400010L
,
1025 0x00000010L
, 0x00004000L
, 0x20400000L
, 0x00404010L
,
1026 0x00004000L
, 0x00400010L
, 0x20004010L
, 0x00000000L
,
1027 0x20404000L
, 0x20000000L
, 0x00400010L
, 0x20004010L
};
1029 static uint32_t SP7
[64] = {
1030 0x00200000L
, 0x04200002L
, 0x04000802L
, 0x00000000L
,
1031 0x00000800L
, 0x04000802L
, 0x00200802L
, 0x04200800L
,
1032 0x04200802L
, 0x00200000L
, 0x00000000L
, 0x04000002L
,
1033 0x00000002L
, 0x04000000L
, 0x04200002L
, 0x00000802L
,
1034 0x04000800L
, 0x00200802L
, 0x00200002L
, 0x04000800L
,
1035 0x04000002L
, 0x04200000L
, 0x04200800L
, 0x00200002L
,
1036 0x04200000L
, 0x00000800L
, 0x00000802L
, 0x04200802L
,
1037 0x00200800L
, 0x00000002L
, 0x04000000L
, 0x00200800L
,
1038 0x04000000L
, 0x00200800L
, 0x00200000L
, 0x04000802L
,
1039 0x04000802L
, 0x04200002L
, 0x04200002L
, 0x00000002L
,
1040 0x00200002L
, 0x04000000L
, 0x04000800L
, 0x00200000L
,
1041 0x04200800L
, 0x00000802L
, 0x00200802L
, 0x04200800L
,
1042 0x00000802L
, 0x04000002L
, 0x04200802L
, 0x04200000L
,
1043 0x00200800L
, 0x00000000L
, 0x00000002L
, 0x04200802L
,
1044 0x00000000L
, 0x00200802L
, 0x04200000L
, 0x00000800L
,
1045 0x04000002L
, 0x04000800L
, 0x00000800L
, 0x00200002L
};
1047 static uint32_t SP8
[64] = {
1048 0x10001040L
, 0x00001000L
, 0x00040000L
, 0x10041040L
,
1049 0x10000000L
, 0x10001040L
, 0x00000040L
, 0x10000000L
,
1050 0x00040040L
, 0x10040000L
, 0x10041040L
, 0x00041000L
,
1051 0x10041000L
, 0x00041040L
, 0x00001000L
, 0x00000040L
,
1052 0x10040000L
, 0x10000040L
, 0x10001000L
, 0x00001040L
,
1053 0x00041000L
, 0x00040040L
, 0x10040040L
, 0x10041000L
,
1054 0x00001040L
, 0x00000000L
, 0x00000000L
, 0x10040040L
,
1055 0x10000040L
, 0x10001000L
, 0x00041040L
, 0x00040000L
,
1056 0x00041040L
, 0x00040000L
, 0x10041000L
, 0x00001000L
,
1057 0x00000040L
, 0x10040040L
, 0x00001000L
, 0x00041040L
,
1058 0x10001000L
, 0x00000040L
, 0x10000040L
, 0x10040000L
,
1059 0x10040040L
, 0x10000000L
, 0x00040000L
, 0x10001040L
,
1060 0x00000000L
, 0x10041040L
, 0x00040040L
, 0x10000040L
,
1061 0x10040000L
, 0x10001000L
, 0x10001040L
, 0x00000000L
,
1062 0x10041040L
, 0x00041000L
, 0x00041000L
, 0x00001040L
,
1063 0x00001040L
, 0x00040040L
, 0x10000000L
, 0x10041000L
};
1070 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1072 v
[0] ^= (work
<< 4);
1073 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1075 v
[0] ^= (work
<< 16);
1076 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1078 v
[1] ^= (work
<< 2);
1079 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1081 v
[1] ^= (work
<< 8);
1082 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
1083 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
1086 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
1094 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
1095 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
1098 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
1099 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1101 v
[1] ^= (work
<< 8);
1102 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1104 v
[1] ^= (work
<< 2);
1105 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1107 v
[0] ^= (work
<< 16);
1108 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1110 v
[0] ^= (work
<< 4);
1114 desx(uint32_t block
[2], DES_key_schedule
*ks
, int encp
)
1117 uint32_t fval
, work
, right
, left
;
1126 for( round
= 0; round
< 8; round
++ ) {
1127 work
= (right
<< 28) | (right
>> 4);
1129 fval
= SP7
[ work
& 0x3fL
];
1130 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1131 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1132 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1133 work
= right
^ *keys
++;
1134 fval
|= SP8
[ work
& 0x3fL
];
1135 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1136 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1137 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1139 work
= (left
<< 28) | (left
>> 4);
1141 fval
= SP7
[ work
& 0x3fL
];
1142 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1143 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1144 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1145 work
= left
^ *keys
++;
1146 fval
|= SP8
[ work
& 0x3fL
];
1147 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1148 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1149 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1155 for( round
= 0; round
< 8; round
++ ) {
1156 work
= (right
<< 28) | (right
>> 4);
1158 fval
= SP7
[ work
& 0x3fL
];
1159 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1160 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1161 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1162 work
= right
^ *keys
++;
1163 fval
|= SP8
[ work
& 0x3fL
];
1164 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1165 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1166 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1168 work
= (left
<< 28) | (left
>> 4);
1171 fval
= SP7
[ work
& 0x3fL
];
1172 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1173 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1174 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1175 work
= left
^ *keys
++;
1176 fval
|= SP8
[ work
& 0x3fL
];
1177 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1178 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1179 fval
|= SP2
[(work
>> 24) & 0x3fL
];