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.
92 #include <krb5-types.h>
100 static void desx(uint32_t [2], DES_key_schedule
*, int);
101 static void IP(uint32_t [2]);
102 static void FP(uint32_t [2]);
104 #include "des-tables.h"
106 #define ROTATE_LEFT28(x,one) \
108 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
110 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
114 * Set the parity of the key block, used to generate a des key from a
115 * random key. See @ref des_keygen.
117 * @param key key to fixup the parity for.
118 * @ingroup hcrypto_des
122 DES_set_odd_parity(DES_cblock
*key
)
125 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
126 (*key
)[i
] = odd_parity
[(*key
)[i
]];
130 * Check if the key have correct parity.
132 * @param key key to check the parity.
133 * @return 1 on success, 0 on failure.
134 * @ingroup hcrypto_des
138 DES_check_key_parity(DES_cblock
*key
)
142 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
143 if ((*key
)[i
] != odd_parity
[(*key
)[i
]])
153 static DES_cblock weak_keys
[] = {
154 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
155 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
156 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
157 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
158 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
159 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
160 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
161 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
162 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
163 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
164 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
165 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
166 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
167 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
168 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
169 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
173 * Checks if the key is any of the weaks keys that makes DES attacks
176 * @param key key to check.
178 * @return 1 if the key is weak, 0 otherwise.
179 * @ingroup hcrypto_des
183 DES_is_weak_key(DES_cblock
*key
)
188 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++)
189 weak
^= (ct_memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0);
195 * Setup a des key schedule from a key. Deprecated function, use
196 * DES_set_key_unchecked() or DES_set_key_checked() instead.
198 * @param key a key to initialize the key schedule with.
199 * @param ks a key schedule to initialize.
201 * @return 0 on success
202 * @ingroup hcrypto_des
206 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
208 return DES_set_key_checked(key
, ks
);
212 * Setup a des key schedule from a key. The key is no longer needed
213 * after this transaction and can cleared.
215 * Does NOT check that the key is weak for or have wrong parity.
217 * @param key a key to initialize the key schedule with.
218 * @param ks a key schedule to initialize.
220 * @return 0 on success
221 * @ingroup hcrypto_des
225 DES_set_key_unchecked(DES_cblock
*key
, DES_key_schedule
*ks
)
229 int shifts
[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
230 uint32_t *k
= &ks
->ks
[0];
233 t1
= (*key
)[0] << 24 | (*key
)[1] << 16 | (*key
)[2] << 8 | (*key
)[3];
234 t2
= (*key
)[4] << 24 | (*key
)[5] << 16 | (*key
)[6] << 8 | (*key
)[7];
236 c
= (pc1_c_3
[(t1
>> (5 )) & 0x7] << 3)
237 | (pc1_c_3
[(t1
>> (5 + 8 )) & 0x7] << 2)
238 | (pc1_c_3
[(t1
>> (5 + 8 + 8 )) & 0x7] << 1)
239 | (pc1_c_3
[(t1
>> (5 + 8 + 8 + 8)) & 0x7] << 0)
240 | (pc1_c_4
[(t2
>> (4 )) & 0xf] << 3)
241 | (pc1_c_4
[(t2
>> (4 + 8 )) & 0xf] << 2)
242 | (pc1_c_4
[(t2
>> (4 + 8 + 8 )) & 0xf] << 1)
243 | (pc1_c_4
[(t2
>> (4 + 8 + 8 + 8)) & 0xf] << 0);
246 d
= (pc1_d_3
[(t2
>> (1 )) & 0x7] << 3)
247 | (pc1_d_3
[(t2
>> (1 + 8 )) & 0x7] << 2)
248 | (pc1_d_3
[(t2
>> (1 + 8 + 8 )) & 0x7] << 1)
249 | (pc1_d_3
[(t2
>> (1 + 8 + 8 + 8)) & 0x7] << 0)
250 | (pc1_d_4
[(t1
>> (1 )) & 0xf] << 3)
251 | (pc1_d_4
[(t1
>> (1 + 8 )) & 0xf] << 2)
252 | (pc1_d_4
[(t1
>> (1 + 8 + 8 )) & 0xf] << 1)
253 | (pc1_d_4
[(t1
>> (1 + 8 + 8 + 8)) & 0xf] << 0);
255 for (i
= 0; i
< 16; i
++) {
258 ROTATE_LEFT28(c
, shifts
[i
]);
259 ROTATE_LEFT28(d
, shifts
[i
]);
261 kc
= pc2_c_1
[(c
>> 22) & 0x3f] |
262 pc2_c_2
[((c
>> 16) & 0x30) | ((c
>> 15) & 0xf)] |
263 pc2_c_3
[((c
>> 9 ) & 0x3c) | ((c
>> 8 ) & 0x3)] |
264 pc2_c_4
[((c
>> 2 ) & 0x20) | ((c
>> 1) & 0x18) | (c
& 0x7)];
265 kd
= pc2_d_1
[(d
>> 22) & 0x3f] |
266 pc2_d_2
[((d
>> 15) & 0x30) | ((d
>> 14) & 0xf)] |
267 pc2_d_3
[ (d
>> 7 ) & 0x3f] |
268 pc2_d_4
[((d
>> 1 ) & 0x3c) | ((d
) & 0x3)];
270 /* Change to byte order used by the S boxes */
271 *k
= (kc
& 0x00fc0000L
) << 6;
272 *k
|= (kc
& 0x00000fc0L
) << 10;
273 *k
|= (kd
& 0x00fc0000L
) >> 10;
274 *k
++ |= (kd
& 0x00000fc0L
) >> 6;
275 *k
= (kc
& 0x0003f000L
) << 12;
276 *k
|= (kc
& 0x0000003fL
) << 16;
277 *k
|= (kd
& 0x0003f000L
) >> 4;
278 *k
++ |= (kd
& 0x0000003fL
);
285 * Just like DES_set_key_unchecked() except checking that the key is
286 * not weak for or have correct parity.
288 * @param key a key to initialize the key schedule with.
289 * @param ks a key schedule to initialize.
291 * @return 0 on success, -1 on invalid parity, -2 on weak key.
292 * @ingroup hcrypto_des
296 DES_set_key_checked(DES_cblock
*key
, DES_key_schedule
*ks
)
298 if (!DES_check_key_parity(key
)) {
299 memset(ks
, 0, sizeof(*ks
));
302 if (DES_is_weak_key(key
)) {
303 memset(ks
, 0, sizeof(*ks
));
306 return DES_set_key_unchecked(key
, ks
);
310 * Compatibility function for eay libdes, works just like
311 * DES_set_key_checked().
313 * @param key a key to initialize the key schedule with.
314 * @param ks a key schedule to initialize.
316 * @return 0 on success, -1 on invalid parity, -2 on weak key.
317 * @ingroup hcrypto_des
321 DES_key_sched(DES_cblock
*key
, DES_key_schedule
*ks
)
323 return DES_set_key_checked(key
, ks
);
331 load(const unsigned char *b
, uint32_t v
[2])
344 store(const uint32_t v
[2], unsigned char *b
)
346 b
[0] = (v
[0] >> 24) & 0xff;
347 b
[1] = (v
[0] >> 16) & 0xff;
348 b
[2] = (v
[0] >> 8) & 0xff;
349 b
[3] = (v
[0] >> 0) & 0xff;
350 b
[4] = (v
[1] >> 24) & 0xff;
351 b
[5] = (v
[1] >> 16) & 0xff;
352 b
[6] = (v
[1] >> 8) & 0xff;
353 b
[7] = (v
[1] >> 0) & 0xff;
357 * Encrypt/decrypt a block using DES. Also called ECB mode
359 * @param u data to encrypt
360 * @param ks key schedule to use
361 * @param encp if non zero, encrypt. if zero, decrypt.
363 * @ingroup hcrypto_des
367 DES_encrypt(uint32_t u
[2], DES_key_schedule
*ks
, int encp
)
375 * Encrypt/decrypt a block using DES.
377 * @param input data to encrypt
378 * @param output data to encrypt
379 * @param ks key schedule to use
380 * @param encp if non zero, encrypt. if zero, decrypt.
382 * @ingroup hcrypto_des
386 DES_ecb_encrypt(DES_cblock
*input
, DES_cblock
*output
,
387 DES_key_schedule
*ks
, int encp
)
391 DES_encrypt(u
, ks
, encp
);
396 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
398 * The IV must always be diffrent for diffrent input data blocks.
400 * @param in data to encrypt
401 * @param out data to encrypt
402 * @param length length of data
403 * @param ks key schedule to use
404 * @param iv initial vector to use
405 * @param encp if non zero, encrypt. if zero, decrypt.
407 * @ingroup hcrypto_des
411 DES_cbc_encrypt(const void *in
, void *out
, long length
,
412 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
414 const unsigned char *input
= in
;
415 unsigned char *output
= out
;
422 while (length
>= DES_CBLOCK_LEN
) {
424 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
425 DES_encrypt(u
, ks
, 1);
426 uiv
[0] = u
[0]; uiv
[1] = u
[1];
429 length
-= DES_CBLOCK_LEN
;
430 input
+= DES_CBLOCK_LEN
;
431 output
+= DES_CBLOCK_LEN
;
434 unsigned char tmp
[DES_CBLOCK_LEN
];
435 memcpy(tmp
, input
, length
);
436 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
438 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
439 DES_encrypt(u
, ks
, 1);
444 while (length
>= DES_CBLOCK_LEN
) {
446 t
[0] = u
[0]; t
[1] = u
[1];
447 DES_encrypt(u
, ks
, 0);
448 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
450 uiv
[0] = t
[0]; uiv
[1] = t
[1];
452 length
-= DES_CBLOCK_LEN
;
453 input
+= DES_CBLOCK_LEN
;
454 output
+= DES_CBLOCK_LEN
;
457 unsigned char tmp
[DES_CBLOCK_LEN
];
458 memcpy(tmp
, input
, length
);
459 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
461 DES_encrypt(u
, ks
, 0);
462 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
466 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
470 * Encrypt/decrypt a block using DES in Propagating Cipher Block
471 * Chaining mode. This mode is only used for Kerberos 4, and it should
474 * The IV must always be diffrent for diffrent input data blocks.
476 * @param in data to encrypt
477 * @param out data to encrypt
478 * @param length length of data
479 * @param ks key schedule to use
480 * @param iv initial vector to use
481 * @param encp if non zero, encrypt. if zero, decrypt.
483 * @ingroup hcrypto_des
487 DES_pcbc_encrypt(const void *in
, void *out
, long length
,
488 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
490 const unsigned char *input
= in
;
491 unsigned char *output
= out
;
499 while (length
>= DES_CBLOCK_LEN
) {
501 t
[0] = u
[0]; t
[1] = u
[1];
502 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
503 DES_encrypt(u
, ks
, 1);
504 uiv
[0] = u
[0] ^ t
[0]; uiv
[1] = u
[1] ^ t
[1];
507 length
-= DES_CBLOCK_LEN
;
508 input
+= DES_CBLOCK_LEN
;
509 output
+= DES_CBLOCK_LEN
;
512 unsigned char tmp
[DES_CBLOCK_LEN
];
513 memcpy(tmp
, input
, length
);
514 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
516 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
517 DES_encrypt(u
, ks
, 1);
522 while (length
>= DES_CBLOCK_LEN
) {
524 t
[0] = u
[0]; t
[1] = u
[1];
525 DES_encrypt(u
, ks
, 0);
526 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
528 uiv
[0] = t
[0] ^ u
[0]; uiv
[1] = t
[1] ^ u
[1];
530 length
-= DES_CBLOCK_LEN
;
531 input
+= DES_CBLOCK_LEN
;
532 output
+= DES_CBLOCK_LEN
;
535 unsigned char tmp
[DES_CBLOCK_LEN
];
536 memcpy(tmp
, input
, length
);
537 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
539 DES_encrypt(u
, ks
, 0);
540 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
543 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
551 _des3_encrypt(uint32_t u
[2], DES_key_schedule
*ks1
, DES_key_schedule
*ks2
,
552 DES_key_schedule
*ks3
, int encp
)
556 desx(u
, ks1
, 1); /* IP + FP cancel out each other */
568 * Encrypt/decrypt a block using triple DES using EDE mode,
569 * encrypt/decrypt/encrypt.
571 * @param input data to encrypt
572 * @param output data to encrypt
573 * @param ks1 key schedule to use
574 * @param ks2 key schedule to use
575 * @param ks3 key schedule to use
576 * @param encp if non zero, encrypt. if zero, decrypt.
578 * @ingroup hcrypto_des
582 DES_ecb3_encrypt(DES_cblock
*input
,
584 DES_key_schedule
*ks1
,
585 DES_key_schedule
*ks2
,
586 DES_key_schedule
*ks3
,
591 _des3_encrypt(u
, ks1
, ks2
, ks3
, encp
);
597 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
599 * The IV must always be diffrent for diffrent input data blocks.
601 * @param in data to encrypt
602 * @param out data to encrypt
603 * @param length length of data
604 * @param ks1 key schedule to use
605 * @param ks2 key schedule to use
606 * @param ks3 key schedule to use
607 * @param iv initial vector to use
608 * @param encp if non zero, encrypt. if zero, decrypt.
610 * @ingroup hcrypto_des
614 DES_ede3_cbc_encrypt(const void *in
, void *out
,
615 long length
, DES_key_schedule
*ks1
,
616 DES_key_schedule
*ks2
, DES_key_schedule
*ks3
,
617 DES_cblock
*iv
, int encp
)
619 const unsigned char *input
= in
;
620 unsigned char *output
= out
;
627 while (length
>= DES_CBLOCK_LEN
) {
629 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
630 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
631 uiv
[0] = u
[0]; uiv
[1] = u
[1];
634 length
-= DES_CBLOCK_LEN
;
635 input
+= DES_CBLOCK_LEN
;
636 output
+= DES_CBLOCK_LEN
;
639 unsigned char tmp
[DES_CBLOCK_LEN
];
640 memcpy(tmp
, input
, length
);
641 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
643 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
644 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
649 while (length
>= DES_CBLOCK_LEN
) {
651 t
[0] = u
[0]; t
[1] = u
[1];
652 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
653 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
655 uiv
[0] = t
[0]; uiv
[1] = t
[1];
657 length
-= DES_CBLOCK_LEN
;
658 input
+= DES_CBLOCK_LEN
;
659 output
+= DES_CBLOCK_LEN
;
662 unsigned char tmp
[DES_CBLOCK_LEN
];
663 memcpy(tmp
, input
, length
);
664 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
666 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
667 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
672 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
676 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
679 * The IV must always be diffrent for diffrent input data blocks.
681 * @param in data to encrypt
682 * @param out data to encrypt
683 * @param length length of data
684 * @param ks key schedule to use
685 * @param iv initial vector to use
686 * @param num offset into in cipher block encryption/decryption stop last time.
687 * @param encp if non zero, encrypt. if zero, decrypt.
689 * @ingroup hcrypto_des
693 DES_cfb64_encrypt(const void *in
, void *out
,
694 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
,
697 const unsigned char *input
= in
;
698 unsigned char *output
= out
;
699 unsigned char tmp
[DES_CBLOCK_LEN
];
704 assert(*num
>= 0 && *num
< DES_CBLOCK_LEN
);
711 DES_encrypt(uiv
, ks
, 1);
713 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
714 output
[i
] = tmp
[i
] ^ input
[i
];
716 if (i
== DES_CBLOCK_LEN
)
721 if (i
== DES_CBLOCK_LEN
)
732 DES_encrypt(uiv
, ks
, 1);
735 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
737 output
[i
] = tmp
[i
] ^ input
[i
];
743 if (i
== DES_CBLOCK_LEN
) {
754 * Crete a checksum using DES in CBC encryption mode. This mode is
755 * only used for Kerberos 4, and it should stay that way.
757 * The IV must always be diffrent for diffrent input data blocks.
759 * @param in data to checksum
760 * @param output the checksum
761 * @param length length of data
762 * @param ks key schedule to use
763 * @param iv initial vector to use
765 * @ingroup hcrypto_des
769 DES_cbc_cksum(const void *in
, DES_cblock
*output
,
770 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
)
772 const unsigned char *input
= in
;
774 uint32_t u
[2] = { 0, 0 };
778 while (length
>= DES_CBLOCK_LEN
) {
780 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
781 DES_encrypt(u
, ks
, 1);
782 uiv
[0] = u
[0]; uiv
[1] = u
[1];
784 length
-= DES_CBLOCK_LEN
;
785 input
+= DES_CBLOCK_LEN
;
788 unsigned char tmp
[DES_CBLOCK_LEN
];
789 memcpy(tmp
, input
, length
);
790 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
792 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
793 DES_encrypt(u
, ks
, 1);
798 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
807 bitswap8(unsigned char b
)
811 for (i
= 0; i
< 8; i
++) {
812 r
= r
<< 1 | (b
& 1);
819 * Convert a string to a DES key. Use something like
820 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
822 * @param str The string to convert to a key
823 * @param key the resulting key
825 * @ingroup hcrypto_des
829 DES_string_to_key(const char *str
, DES_cblock
*key
)
831 const unsigned char *s
;
836 memset(key
, 0, sizeof(*key
));
838 s
= (const unsigned char *)str
;
841 for (i
= 0; i
< len
; i
++) {
843 k
[i
% 8] ^= s
[i
] << 1;
845 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
847 DES_set_odd_parity(key
);
848 if (DES_is_weak_key(key
))
850 DES_set_key(key
, &ks
);
851 DES_cbc_cksum(s
, key
, len
, &ks
, key
);
852 memset(&ks
, 0, sizeof(ks
));
853 DES_set_odd_parity(key
);
854 if (DES_is_weak_key(key
))
859 * Read password from prompt and create a DES key. Internal uses
860 * DES_string_to_key(). Really, go use a really string2key function
861 * like PKCS5_PBKDF2_HMAC_SHA1().
863 * @param key key to convert to
864 * @param prompt prompt to display user
865 * @param verify prompt twice.
867 * @return 1 on success, non 1 on failure.
871 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
876 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
878 DES_string_to_key(buf
, key
);
890 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
891 uint32_t u
[2] = { 1, 0 };
896 if (u
[0] != 1 || u
[1] != 0)
901 if (memcmp(k
, k2
, 8) != 0)
907 * A portable, public domain, version of the Data Encryption Standard.
909 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
910 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
911 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
912 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
913 * for humouring me on.
915 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
916 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
919 static uint32_t SP1
[64] = {
920 0x01010400L
, 0x00000000L
, 0x00010000L
, 0x01010404L
,
921 0x01010004L
, 0x00010404L
, 0x00000004L
, 0x00010000L
,
922 0x00000400L
, 0x01010400L
, 0x01010404L
, 0x00000400L
,
923 0x01000404L
, 0x01010004L
, 0x01000000L
, 0x00000004L
,
924 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00010400L
,
925 0x00010400L
, 0x01010000L
, 0x01010000L
, 0x01000404L
,
926 0x00010004L
, 0x01000004L
, 0x01000004L
, 0x00010004L
,
927 0x00000000L
, 0x00000404L
, 0x00010404L
, 0x01000000L
,
928 0x00010000L
, 0x01010404L
, 0x00000004L
, 0x01010000L
,
929 0x01010400L
, 0x01000000L
, 0x01000000L
, 0x00000400L
,
930 0x01010004L
, 0x00010000L
, 0x00010400L
, 0x01000004L
,
931 0x00000400L
, 0x00000004L
, 0x01000404L
, 0x00010404L
,
932 0x01010404L
, 0x00010004L
, 0x01010000L
, 0x01000404L
,
933 0x01000004L
, 0x00000404L
, 0x00010404L
, 0x01010400L
,
934 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00000000L
,
935 0x00010004L
, 0x00010400L
, 0x00000000L
, 0x01010004L
};
937 static uint32_t SP2
[64] = {
938 0x80108020L
, 0x80008000L
, 0x00008000L
, 0x00108020L
,
939 0x00100000L
, 0x00000020L
, 0x80100020L
, 0x80008020L
,
940 0x80000020L
, 0x80108020L
, 0x80108000L
, 0x80000000L
,
941 0x80008000L
, 0x00100000L
, 0x00000020L
, 0x80100020L
,
942 0x00108000L
, 0x00100020L
, 0x80008020L
, 0x00000000L
,
943 0x80000000L
, 0x00008000L
, 0x00108020L
, 0x80100000L
,
944 0x00100020L
, 0x80000020L
, 0x00000000L
, 0x00108000L
,
945 0x00008020L
, 0x80108000L
, 0x80100000L
, 0x00008020L
,
946 0x00000000L
, 0x00108020L
, 0x80100020L
, 0x00100000L
,
947 0x80008020L
, 0x80100000L
, 0x80108000L
, 0x00008000L
,
948 0x80100000L
, 0x80008000L
, 0x00000020L
, 0x80108020L
,
949 0x00108020L
, 0x00000020L
, 0x00008000L
, 0x80000000L
,
950 0x00008020L
, 0x80108000L
, 0x00100000L
, 0x80000020L
,
951 0x00100020L
, 0x80008020L
, 0x80000020L
, 0x00100020L
,
952 0x00108000L
, 0x00000000L
, 0x80008000L
, 0x00008020L
,
953 0x80000000L
, 0x80100020L
, 0x80108020L
, 0x00108000L
};
955 static uint32_t SP3
[64] = {
956 0x00000208L
, 0x08020200L
, 0x00000000L
, 0x08020008L
,
957 0x08000200L
, 0x00000000L
, 0x00020208L
, 0x08000200L
,
958 0x00020008L
, 0x08000008L
, 0x08000008L
, 0x00020000L
,
959 0x08020208L
, 0x00020008L
, 0x08020000L
, 0x00000208L
,
960 0x08000000L
, 0x00000008L
, 0x08020200L
, 0x00000200L
,
961 0x00020200L
, 0x08020000L
, 0x08020008L
, 0x00020208L
,
962 0x08000208L
, 0x00020200L
, 0x00020000L
, 0x08000208L
,
963 0x00000008L
, 0x08020208L
, 0x00000200L
, 0x08000000L
,
964 0x08020200L
, 0x08000000L
, 0x00020008L
, 0x00000208L
,
965 0x00020000L
, 0x08020200L
, 0x08000200L
, 0x00000000L
,
966 0x00000200L
, 0x00020008L
, 0x08020208L
, 0x08000200L
,
967 0x08000008L
, 0x00000200L
, 0x00000000L
, 0x08020008L
,
968 0x08000208L
, 0x00020000L
, 0x08000000L
, 0x08020208L
,
969 0x00000008L
, 0x00020208L
, 0x00020200L
, 0x08000008L
,
970 0x08020000L
, 0x08000208L
, 0x00000208L
, 0x08020000L
,
971 0x00020208L
, 0x00000008L
, 0x08020008L
, 0x00020200L
};
973 static uint32_t SP4
[64] = {
974 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
975 0x00802080L
, 0x00800081L
, 0x00800001L
, 0x00002001L
,
976 0x00000000L
, 0x00802000L
, 0x00802000L
, 0x00802081L
,
977 0x00000081L
, 0x00000000L
, 0x00800080L
, 0x00800001L
,
978 0x00000001L
, 0x00002000L
, 0x00800000L
, 0x00802001L
,
979 0x00000080L
, 0x00800000L
, 0x00002001L
, 0x00002080L
,
980 0x00800081L
, 0x00000001L
, 0x00002080L
, 0x00800080L
,
981 0x00002000L
, 0x00802080L
, 0x00802081L
, 0x00000081L
,
982 0x00800080L
, 0x00800001L
, 0x00802000L
, 0x00802081L
,
983 0x00000081L
, 0x00000000L
, 0x00000000L
, 0x00802000L
,
984 0x00002080L
, 0x00800080L
, 0x00800081L
, 0x00000001L
,
985 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
986 0x00802081L
, 0x00000081L
, 0x00000001L
, 0x00002000L
,
987 0x00800001L
, 0x00002001L
, 0x00802080L
, 0x00800081L
,
988 0x00002001L
, 0x00002080L
, 0x00800000L
, 0x00802001L
,
989 0x00000080L
, 0x00800000L
, 0x00002000L
, 0x00802080L
};
991 static uint32_t SP5
[64] = {
992 0x00000100L
, 0x02080100L
, 0x02080000L
, 0x42000100L
,
993 0x00080000L
, 0x00000100L
, 0x40000000L
, 0x02080000L
,
994 0x40080100L
, 0x00080000L
, 0x02000100L
, 0x40080100L
,
995 0x42000100L
, 0x42080000L
, 0x00080100L
, 0x40000000L
,
996 0x02000000L
, 0x40080000L
, 0x40080000L
, 0x00000000L
,
997 0x40000100L
, 0x42080100L
, 0x42080100L
, 0x02000100L
,
998 0x42080000L
, 0x40000100L
, 0x00000000L
, 0x42000000L
,
999 0x02080100L
, 0x02000000L
, 0x42000000L
, 0x00080100L
,
1000 0x00080000L
, 0x42000100L
, 0x00000100L
, 0x02000000L
,
1001 0x40000000L
, 0x02080000L
, 0x42000100L
, 0x40080100L
,
1002 0x02000100L
, 0x40000000L
, 0x42080000L
, 0x02080100L
,
1003 0x40080100L
, 0x00000100L
, 0x02000000L
, 0x42080000L
,
1004 0x42080100L
, 0x00080100L
, 0x42000000L
, 0x42080100L
,
1005 0x02080000L
, 0x00000000L
, 0x40080000L
, 0x42000000L
,
1006 0x00080100L
, 0x02000100L
, 0x40000100L
, 0x00080000L
,
1007 0x00000000L
, 0x40080000L
, 0x02080100L
, 0x40000100L
};
1009 static uint32_t SP6
[64] = {
1010 0x20000010L
, 0x20400000L
, 0x00004000L
, 0x20404010L
,
1011 0x20400000L
, 0x00000010L
, 0x20404010L
, 0x00400000L
,
1012 0x20004000L
, 0x00404010L
, 0x00400000L
, 0x20000010L
,
1013 0x00400010L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1014 0x00000000L
, 0x00400010L
, 0x20004010L
, 0x00004000L
,
1015 0x00404000L
, 0x20004010L
, 0x00000010L
, 0x20400010L
,
1016 0x20400010L
, 0x00000000L
, 0x00404010L
, 0x20404000L
,
1017 0x00004010L
, 0x00404000L
, 0x20404000L
, 0x20000000L
,
1018 0x20004000L
, 0x00000010L
, 0x20400010L
, 0x00404000L
,
1019 0x20404010L
, 0x00400000L
, 0x00004010L
, 0x20000010L
,
1020 0x00400000L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1021 0x20000010L
, 0x20404010L
, 0x00404000L
, 0x20400000L
,
1022 0x00404010L
, 0x20404000L
, 0x00000000L
, 0x20400010L
,
1023 0x00000010L
, 0x00004000L
, 0x20400000L
, 0x00404010L
,
1024 0x00004000L
, 0x00400010L
, 0x20004010L
, 0x00000000L
,
1025 0x20404000L
, 0x20000000L
, 0x00400010L
, 0x20004010L
};
1027 static uint32_t SP7
[64] = {
1028 0x00200000L
, 0x04200002L
, 0x04000802L
, 0x00000000L
,
1029 0x00000800L
, 0x04000802L
, 0x00200802L
, 0x04200800L
,
1030 0x04200802L
, 0x00200000L
, 0x00000000L
, 0x04000002L
,
1031 0x00000002L
, 0x04000000L
, 0x04200002L
, 0x00000802L
,
1032 0x04000800L
, 0x00200802L
, 0x00200002L
, 0x04000800L
,
1033 0x04000002L
, 0x04200000L
, 0x04200800L
, 0x00200002L
,
1034 0x04200000L
, 0x00000800L
, 0x00000802L
, 0x04200802L
,
1035 0x00200800L
, 0x00000002L
, 0x04000000L
, 0x00200800L
,
1036 0x04000000L
, 0x00200800L
, 0x00200000L
, 0x04000802L
,
1037 0x04000802L
, 0x04200002L
, 0x04200002L
, 0x00000002L
,
1038 0x00200002L
, 0x04000000L
, 0x04000800L
, 0x00200000L
,
1039 0x04200800L
, 0x00000802L
, 0x00200802L
, 0x04200800L
,
1040 0x00000802L
, 0x04000002L
, 0x04200802L
, 0x04200000L
,
1041 0x00200800L
, 0x00000000L
, 0x00000002L
, 0x04200802L
,
1042 0x00000000L
, 0x00200802L
, 0x04200000L
, 0x00000800L
,
1043 0x04000002L
, 0x04000800L
, 0x00000800L
, 0x00200002L
};
1045 static uint32_t SP8
[64] = {
1046 0x10001040L
, 0x00001000L
, 0x00040000L
, 0x10041040L
,
1047 0x10000000L
, 0x10001040L
, 0x00000040L
, 0x10000000L
,
1048 0x00040040L
, 0x10040000L
, 0x10041040L
, 0x00041000L
,
1049 0x10041000L
, 0x00041040L
, 0x00001000L
, 0x00000040L
,
1050 0x10040000L
, 0x10000040L
, 0x10001000L
, 0x00001040L
,
1051 0x00041000L
, 0x00040040L
, 0x10040040L
, 0x10041000L
,
1052 0x00001040L
, 0x00000000L
, 0x00000000L
, 0x10040040L
,
1053 0x10000040L
, 0x10001000L
, 0x00041040L
, 0x00040000L
,
1054 0x00041040L
, 0x00040000L
, 0x10041000L
, 0x00001000L
,
1055 0x00000040L
, 0x10040040L
, 0x00001000L
, 0x00041040L
,
1056 0x10001000L
, 0x00000040L
, 0x10000040L
, 0x10040000L
,
1057 0x10040040L
, 0x10000000L
, 0x00040000L
, 0x10001040L
,
1058 0x00000000L
, 0x10041040L
, 0x00040040L
, 0x10000040L
,
1059 0x10040000L
, 0x10001000L
, 0x10001040L
, 0x00000000L
,
1060 0x10041040L
, 0x00041000L
, 0x00041000L
, 0x00001040L
,
1061 0x00001040L
, 0x00040040L
, 0x10000000L
, 0x10041000L
};
1068 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1070 v
[0] ^= (work
<< 4);
1071 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1073 v
[0] ^= (work
<< 16);
1074 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1076 v
[1] ^= (work
<< 2);
1077 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1079 v
[1] ^= (work
<< 8);
1080 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
1081 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
1084 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
1092 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
1093 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
1096 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
1097 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1099 v
[1] ^= (work
<< 8);
1100 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1102 v
[1] ^= (work
<< 2);
1103 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1105 v
[0] ^= (work
<< 16);
1106 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1108 v
[0] ^= (work
<< 4);
1112 desx(uint32_t block
[2], DES_key_schedule
*ks
, int encp
)
1115 uint32_t fval
, work
, right
, left
;
1124 for( round
= 0; round
< 8; round
++ ) {
1125 work
= (right
<< 28) | (right
>> 4);
1127 fval
= SP7
[ work
& 0x3fL
];
1128 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1129 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1130 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1131 work
= right
^ *keys
++;
1132 fval
|= SP8
[ work
& 0x3fL
];
1133 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1134 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1135 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1137 work
= (left
<< 28) | (left
>> 4);
1139 fval
= SP7
[ work
& 0x3fL
];
1140 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1141 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1142 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1143 work
= left
^ *keys
++;
1144 fval
|= SP8
[ work
& 0x3fL
];
1145 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1146 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1147 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1153 for( round
= 0; round
< 8; round
++ ) {
1154 work
= (right
<< 28) | (right
>> 4);
1156 fval
= SP7
[ work
& 0x3fL
];
1157 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1158 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1159 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1160 work
= right
^ *keys
++;
1161 fval
|= SP8
[ work
& 0x3fL
];
1162 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1163 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1164 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1166 work
= (left
<< 28) | (left
>> 4);
1169 fval
= SP7
[ work
& 0x3fL
];
1170 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1171 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1172 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1173 work
= left
^ *keys
++;
1174 fval
|= SP8
[ work
& 0x3fL
];
1175 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1176 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1177 fval
|= SP2
[(work
>> 24) & 0x3fL
];