x
[heimdal.git] / lib / hcrypto / des.c
blob8be9d649cd3524d9b6a155bc60b563dc135801c9
1 /*
2 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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
31 * SUCH DAMAGE.
34 /**
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.
58 * @code
59 * DES_cblock key;
60 * do {
61 * if (RAND_rand(&key, sizeof(key)) != 1)
62 * goto failure;
63 * DES_set_odd_parity(key);
64 * } while (DES_is_weak_key(&key));
65 * @endcode
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
72 * libdes.
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.
85 #ifdef HAVE_CONFIG_H
86 #include <config.h>
87 RCSID("$Id$");
88 #endif
90 #define HC_DEPRECATED
92 #include <stdio.h>
93 #include <stdlib.h>
94 #include <string.h>
95 #include <krb5-types.h>
96 #include <assert.h>
98 #include "des.h"
99 #include "ui.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) \
108 if (one) { \
109 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
110 } else { \
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
122 void
123 DES_set_odd_parity(DES_cblock *key)
125 unsigned int i;
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
138 int HC_DEPRECATED
139 DES_check_key_parity(DES_cblock *key)
141 unsigned int i;
143 for (i = 0; i < DES_CBLOCK_LEN; i++)
144 if ((*key)[i] != odd_parity[(*key)[i]])
145 return 0;
146 return 1;
153 /* FIPS 74 */
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
175 * trival.
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)
186 int i;
188 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
189 if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
190 return 1;
192 return 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
206 int HC_DEPRECATED
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)
228 uint32_t t1, t2;
229 uint32_t c, d;
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];
232 int i;
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++) {
257 uint32_t kc, kd;
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);
282 return 0;
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));
301 return -1;
303 if (DES_is_weak_key(key)) {
304 memset(ks, 0, sizeof(*ks));
305 return -2;
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);
331 static void
332 load(const unsigned char *b, uint32_t v[2])
334 v[0] = b[0] << 24;
335 v[0] |= b[1] << 16;
336 v[0] |= b[2] << 8;
337 v[0] |= b[3] << 0;
338 v[1] = b[4] << 24;
339 v[1] |= b[5] << 16;
340 v[1] |= b[6] << 8;
341 v[1] |= b[7] << 0;
344 static void
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
367 void
368 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
370 IP(u);
371 desx(u, ks, encp);
372 FP(u);
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
386 void
387 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
388 DES_key_schedule *ks, int encp)
390 uint32_t u[2];
391 load(*input, u);
392 DES_encrypt(u, ks, encp);
393 store(u, *output);
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
411 void
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;
417 uint32_t u[2];
418 uint32_t uiv[2];
420 load(*iv, uiv);
422 if (encp) {
423 while (length >= DES_CBLOCK_LEN) {
424 load(input, u);
425 u[0] ^= uiv[0]; u[1] ^= uiv[1];
426 DES_encrypt(u, ks, 1);
427 uiv[0] = u[0]; uiv[1] = u[1];
428 store(u, output);
430 length -= DES_CBLOCK_LEN;
431 input += DES_CBLOCK_LEN;
432 output += DES_CBLOCK_LEN;
434 if (length) {
435 unsigned char tmp[DES_CBLOCK_LEN];
436 memcpy(tmp, input, length);
437 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
438 load(tmp, u);
439 u[0] ^= uiv[0]; u[1] ^= uiv[1];
440 DES_encrypt(u, ks, 1);
441 store(u, output);
443 } else {
444 uint32_t t[2];
445 while (length >= DES_CBLOCK_LEN) {
446 load(input, u);
447 t[0] = u[0]; t[1] = u[1];
448 DES_encrypt(u, ks, 0);
449 u[0] ^= uiv[0]; u[1] ^= uiv[1];
450 store(u, output);
451 uiv[0] = t[0]; uiv[1] = t[1];
453 length -= DES_CBLOCK_LEN;
454 input += DES_CBLOCK_LEN;
455 output += DES_CBLOCK_LEN;
457 if (length) {
458 unsigned char tmp[DES_CBLOCK_LEN];
459 memcpy(tmp, input, length);
460 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
461 load(tmp, u);
462 DES_encrypt(u, ks, 0);
463 u[0] ^= uiv[0]; u[1] ^= uiv[1];
464 store(u, output);
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
473 * stay that way.
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
487 void
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;
493 uint32_t u[2];
494 uint32_t uiv[2];
496 load(*iv, uiv);
498 if (encp) {
499 uint32_t t[2];
500 while (length >= DES_CBLOCK_LEN) {
501 load(input, u);
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];
506 store(u, output);
508 length -= DES_CBLOCK_LEN;
509 input += DES_CBLOCK_LEN;
510 output += DES_CBLOCK_LEN;
512 if (length) {
513 unsigned char tmp[DES_CBLOCK_LEN];
514 memcpy(tmp, input, length);
515 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
516 load(tmp, u);
517 u[0] ^= uiv[0]; u[1] ^= uiv[1];
518 DES_encrypt(u, ks, 1);
519 store(u, output);
521 } else {
522 uint32_t t[2];
523 while (length >= DES_CBLOCK_LEN) {
524 load(input, u);
525 t[0] = u[0]; t[1] = u[1];
526 DES_encrypt(u, ks, 0);
527 u[0] ^= uiv[0]; u[1] ^= uiv[1];
528 store(u, output);
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;
535 if (length) {
536 unsigned char tmp[DES_CBLOCK_LEN];
537 memcpy(tmp, input, length);
538 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
539 load(tmp, u);
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;
551 static void
552 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
553 DES_key_schedule *ks3, int encp)
555 IP(u);
556 if (encp) {
557 desx(u, ks1, 1); /* IP + FP cancel out each other */
558 desx(u, ks2, 0);
559 desx(u, ks3, 1);
560 } else {
561 desx(u, ks3, 0);
562 desx(u, ks2, 1);
563 desx(u, ks1, 0);
565 FP(u);
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
582 void
583 DES_ecb3_encrypt(DES_cblock *input,
584 DES_cblock *output,
585 DES_key_schedule *ks1,
586 DES_key_schedule *ks2,
587 DES_key_schedule *ks3,
588 int encp)
590 uint32_t u[2];
591 load(*input, u);
592 _des3_encrypt(u, ks1, ks2, ks3, encp);
593 store(u, *output);
594 return;
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
614 void
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;
622 uint32_t u[2];
623 uint32_t uiv[2];
625 load(*iv, uiv);
627 if (encp) {
628 while (length >= DES_CBLOCK_LEN) {
629 load(input, u);
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];
633 store(u, output);
635 length -= DES_CBLOCK_LEN;
636 input += DES_CBLOCK_LEN;
637 output += DES_CBLOCK_LEN;
639 if (length) {
640 unsigned char tmp[DES_CBLOCK_LEN];
641 memcpy(tmp, input, length);
642 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
643 load(tmp, u);
644 u[0] ^= uiv[0]; u[1] ^= uiv[1];
645 _des3_encrypt(u, ks1, ks2, ks3, 1);
646 store(u, output);
648 } else {
649 uint32_t t[2];
650 while (length >= DES_CBLOCK_LEN) {
651 load(input, u);
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];
655 store(u, output);
656 uiv[0] = t[0]; uiv[1] = t[1];
658 length -= DES_CBLOCK_LEN;
659 input += DES_CBLOCK_LEN;
660 output += DES_CBLOCK_LEN;
662 if (length) {
663 unsigned char tmp[DES_CBLOCK_LEN];
664 memcpy(tmp, input, length);
665 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
666 load(tmp, u);
667 _des3_encrypt(u, ks1, ks2, ks3, 0);
668 u[0] ^= uiv[0]; u[1] ^= uiv[1];
669 store(u, output);
672 store(uiv, *iv);
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
678 * feedback.
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
693 void
694 DES_cfb64_encrypt(const void *in, void *out,
695 long length, DES_key_schedule *ks, DES_cblock *iv,
696 int *num, int encp)
698 const unsigned char *input = in;
699 unsigned char *output = out;
700 unsigned char tmp[DES_CBLOCK_LEN];
701 uint32_t uiv[2];
703 load(*iv, uiv);
705 assert(*num >= 0 && *num < DES_CBLOCK_LEN);
707 if (encp) {
708 int i = *num;
710 while (length > 0) {
711 if (i == 0)
712 DES_encrypt(uiv, ks, 1);
713 store(uiv, tmp);
714 for (; i < DES_CBLOCK_LEN && i < length; i++) {
715 output[i] = tmp[i] ^ input[i];
717 if (i == DES_CBLOCK_LEN)
718 load(output, uiv);
719 output += i;
720 input += i;
721 length -= i;
722 if (i == DES_CBLOCK_LEN)
723 i = 0;
725 store(uiv, *iv);
726 *num = i;
727 } else {
728 int i = *num;
729 unsigned char c;
731 while (length > 0) {
732 if (i == 0) {
733 DES_encrypt(uiv, ks, 1);
734 store(uiv, tmp);
736 for (; i < DES_CBLOCK_LEN && i < length; i++) {
737 c = input[i];
738 output[i] = tmp[i] ^ input[i];
739 (*iv)[i] = c;
741 output += i;
742 input += i;
743 length -= i;
744 if (i == DES_CBLOCK_LEN) {
745 i = 0;
746 load(*iv, uiv);
749 store(uiv, *iv);
750 *num = i;
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
769 uint32_t
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;
774 uint32_t uiv[2];
775 uint32_t u[2] = { 0, 0 };
777 load(*iv, uiv);
779 while (length >= DES_CBLOCK_LEN) {
780 load(input, u);
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;
788 if (length) {
789 unsigned char tmp[DES_CBLOCK_LEN];
790 memcpy(tmp, input, length);
791 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
792 load(tmp, u);
793 u[0] ^= uiv[0]; u[1] ^= uiv[1];
794 DES_encrypt(u, ks, 1);
796 if (output)
797 store(u, *output);
799 uiv[0] = 0; u[0] = 0; uiv[1] = 0;
800 return u[1];
807 static unsigned char
808 bitswap8(unsigned char b)
810 unsigned char r = 0;
811 int i;
812 for (i = 0; i < 8; i++) {
813 r = r << 1 | (b & 1);
814 b = b >> 1;
816 return r;
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
829 void
830 DES_string_to_key(const char *str, DES_cblock *key)
832 const unsigned char *s;
833 unsigned char *k;
834 DES_key_schedule ks;
835 size_t i, len;
837 memset(key, 0, sizeof(*key));
838 k = *key;
839 s = (const unsigned char *)str;
841 len = strlen(str);
842 for (i = 0; i < len; i++) {
843 if ((i % 16) < 8)
844 k[i % 8] ^= s[i] << 1;
845 else
846 k[7 - (i % 8)] ^= bitswap8(s[i]);
848 DES_set_odd_parity(key);
849 if (DES_is_weak_key(key))
850 k[7] ^= 0xF0;
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))
856 k[7] ^= 0xF0;
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)
874 char buf[512];
875 int ret;
877 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
878 if (ret == 1)
879 DES_string_to_key(buf, key);
880 return ret;
888 void
889 _DES_ipfp_test(void)
891 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
892 uint32_t u[2] = { 1, 0 };
893 IP(u);
894 FP(u);
895 IP(u);
896 FP(u);
897 if (u[0] != 1 || u[1] != 0)
898 abort();
900 load(k, u);
901 store(u, k2);
902 if (memcmp(k, k2, 8) != 0)
903 abort();
906 /* D3DES (V5.09) -
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 };
1064 static void
1065 IP(uint32_t v[2])
1067 uint32_t work;
1069 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1070 v[1] ^= work;
1071 v[0] ^= (work << 4);
1072 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1073 v[1] ^= work;
1074 v[0] ^= (work << 16);
1075 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1076 v[0] ^= work;
1077 v[1] ^= (work << 2);
1078 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1079 v[0] ^= work;
1080 v[1] ^= (work << 8);
1081 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
1082 work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
1083 v[0] ^= work;
1084 v[1] ^= work;
1085 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
1088 static void
1089 FP(uint32_t v[2])
1091 uint32_t work;
1093 v[0] = (v[0] << 31) | (v[0] >> 1);
1094 work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1095 v[1] ^= work;
1096 v[0] ^= work;
1097 v[1] = (v[1] << 31) | (v[1] >> 1);
1098 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1099 v[0] ^= work;
1100 v[1] ^= (work << 8);
1101 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1102 v[0] ^= work;
1103 v[1] ^= (work << 2);
1104 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1105 v[1] ^= work;
1106 v[0] ^= (work << 16);
1107 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1108 v[1] ^= work;
1109 v[0] ^= (work << 4);
1112 static void
1113 desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1115 uint32_t *keys;
1116 uint32_t fval, work, right, left;
1117 int round;
1119 left = block[0];
1120 right = block[1];
1122 if (encp) {
1123 keys = &ks->ks[0];
1125 for( round = 0; round < 8; round++ ) {
1126 work = (right << 28) | (right >> 4);
1127 work ^= *keys++;
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];
1137 left ^= fval;
1138 work = (left << 28) | (left >> 4);
1139 work ^= *keys++;
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];
1149 right ^= fval;
1151 } else {
1152 keys = &ks->ks[30];
1154 for( round = 0; round < 8; round++ ) {
1155 work = (right << 28) | (right >> 4);
1156 work ^= *keys++;
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];
1166 left ^= fval;
1167 work = (left << 28) | (left >> 4);
1168 keys -= 4;
1169 work ^= *keys++;
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];
1179 right ^= fval;
1180 keys -= 4;
1183 block[0] = right;
1184 block[1] = left;