[HEIMDAL-646] malloc(0) checks for AIX
[heimdal.git] / lib / hcrypto / des.c
blobc9067d7bccb9881c5e451c4e1f259a5d45812422
1 /*
2 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 #include <config.h>
87 #define HC_DEPRECATED
89 #include <stdio.h>
90 #include <stdlib.h>
91 #include <string.h>
92 #include <krb5-types.h>
93 #include <assert.h>
95 #include "des.h"
96 #include "ui.h"
98 static void desx(uint32_t [2], DES_key_schedule *, int);
99 static void IP(uint32_t [2]);
100 static void FP(uint32_t [2]);
102 #include "des-tables.h"
104 #define ROTATE_LEFT28(x,one) \
105 if (one) { \
106 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
107 } else { \
108 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
112 * Set the parity of the key block, used to generate a des key from a
113 * random key. See @ref des_keygen.
115 * @param key key to fixup the parity for.
116 * @ingroup hcrypto_des
119 void
120 DES_set_odd_parity(DES_cblock *key)
122 unsigned int i;
123 for (i = 0; i < DES_CBLOCK_LEN; i++)
124 (*key)[i] = odd_parity[(*key)[i]];
128 * Check if the key have correct parity.
130 * @param key key to check the parity.
131 * @return 1 on success, 0 on failure.
132 * @ingroup hcrypto_des
135 int HC_DEPRECATED
136 DES_check_key_parity(DES_cblock *key)
138 unsigned int i;
140 for (i = 0; i < DES_CBLOCK_LEN; i++)
141 if ((*key)[i] != odd_parity[(*key)[i]])
142 return 0;
143 return 1;
150 /* FIPS 74 */
151 static DES_cblock weak_keys[] = {
152 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
153 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
154 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
155 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
156 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
157 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
158 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
159 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
160 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
161 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
162 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
163 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
164 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
165 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
166 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
167 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
171 * Checks if the key is any of the weaks keys that makes DES attacks
172 * trival.
174 * @param key key to check.
176 * @return 1 if the key is weak, 0 otherwise.
177 * @ingroup hcrypto_des
181 DES_is_weak_key(DES_cblock *key)
183 int i;
185 /* Not constant time size if the key is weak, the app should not use it. */
186 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
187 if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
188 return 1;
190 return 0;
194 * Setup a des key schedule from a key. Deprecated function, use
195 * DES_set_key_unchecked() or DES_set_key_checked() instead.
197 * @param key a key to initialize the key schedule with.
198 * @param ks a key schedule to initialize.
200 * @return 0 on success
201 * @ingroup hcrypto_des
204 int HC_DEPRECATED
205 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
207 return DES_set_key_checked(key, ks);
211 * Setup a des key schedule from a key. The key is no longer needed
212 * after this transaction and can cleared.
214 * Does NOT check that the key is weak for or have wrong parity.
216 * @param key a key to initialize the key schedule with.
217 * @param ks a key schedule to initialize.
219 * @return 0 on success
220 * @ingroup hcrypto_des
224 DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
226 uint32_t t1, t2;
227 uint32_t c, d;
228 int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
229 uint32_t *k = &ks->ks[0];
230 int i;
232 t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
233 t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
235 c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
236 | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
237 | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
238 | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
239 | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
240 | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
241 | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
242 | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
245 d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
246 | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
247 | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
248 | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
249 | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
250 | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
251 | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
252 | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
254 for (i = 0; i < 16; i++) {
255 uint32_t kc, kd;
257 ROTATE_LEFT28(c, shifts[i]);
258 ROTATE_LEFT28(d, shifts[i]);
260 kc = pc2_c_1[(c >> 22) & 0x3f] |
261 pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
262 pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
263 pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
264 kd = pc2_d_1[(d >> 22) & 0x3f] |
265 pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
266 pc2_d_3[ (d >> 7 ) & 0x3f] |
267 pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
269 /* Change to byte order used by the S boxes */
270 *k = (kc & 0x00fc0000L) << 6;
271 *k |= (kc & 0x00000fc0L) << 10;
272 *k |= (kd & 0x00fc0000L) >> 10;
273 *k++ |= (kd & 0x00000fc0L) >> 6;
274 *k = (kc & 0x0003f000L) << 12;
275 *k |= (kc & 0x0000003fL) << 16;
276 *k |= (kd & 0x0003f000L) >> 4;
277 *k++ |= (kd & 0x0000003fL);
280 return 0;
284 * Just like DES_set_key_unchecked() except checking that the key is
285 * not weak for or have correct parity.
287 * @param key a key to initialize the key schedule with.
288 * @param ks a key schedule to initialize.
290 * @return 0 on success, -1 on invalid parity, -2 on weak key.
291 * @ingroup hcrypto_des
295 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
297 if (!DES_check_key_parity(key)) {
298 memset(ks, 0, sizeof(*ks));
299 return -1;
301 if (DES_is_weak_key(key)) {
302 memset(ks, 0, sizeof(*ks));
303 return -2;
305 return DES_set_key_unchecked(key, ks);
309 * Compatibility function for eay libdes, works just like
310 * DES_set_key_checked().
312 * @param key a key to initialize the key schedule with.
313 * @param ks a key schedule to initialize.
315 * @return 0 on success, -1 on invalid parity, -2 on weak key.
316 * @ingroup hcrypto_des
320 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
322 return DES_set_key_checked(key, ks);
329 static void
330 load(const unsigned char *b, uint32_t v[2])
332 v[0] = b[0] << 24;
333 v[0] |= b[1] << 16;
334 v[0] |= b[2] << 8;
335 v[0] |= b[3] << 0;
336 v[1] = b[4] << 24;
337 v[1] |= b[5] << 16;
338 v[1] |= b[6] << 8;
339 v[1] |= b[7] << 0;
342 static void
343 store(const uint32_t v[2], unsigned char *b)
345 b[0] = (v[0] >> 24) & 0xff;
346 b[1] = (v[0] >> 16) & 0xff;
347 b[2] = (v[0] >> 8) & 0xff;
348 b[3] = (v[0] >> 0) & 0xff;
349 b[4] = (v[1] >> 24) & 0xff;
350 b[5] = (v[1] >> 16) & 0xff;
351 b[6] = (v[1] >> 8) & 0xff;
352 b[7] = (v[1] >> 0) & 0xff;
356 * Encrypt/decrypt a block using DES. Also called ECB mode
358 * @param u data to encrypt
359 * @param ks key schedule to use
360 * @param encp if non zero, encrypt. if zero, decrypt.
362 * @ingroup hcrypto_des
365 void
366 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
368 IP(u);
369 desx(u, ks, encp);
370 FP(u);
374 * Encrypt/decrypt a block using DES.
376 * @param input data to encrypt
377 * @param output data to encrypt
378 * @param ks key schedule to use
379 * @param encp if non zero, encrypt. if zero, decrypt.
381 * @ingroup hcrypto_des
384 void
385 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
386 DES_key_schedule *ks, int encp)
388 uint32_t u[2];
389 load(*input, u);
390 DES_encrypt(u, ks, encp);
391 store(u, *output);
395 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
397 * The IV must always be diffrent for diffrent input data blocks.
399 * @param in data to encrypt
400 * @param out data to encrypt
401 * @param length length of data
402 * @param ks key schedule to use
403 * @param iv initial vector to use
404 * @param encp if non zero, encrypt. if zero, decrypt.
406 * @ingroup hcrypto_des
409 void
410 DES_cbc_encrypt(const void *in, void *out, long length,
411 DES_key_schedule *ks, DES_cblock *iv, int encp)
413 const unsigned char *input = in;
414 unsigned char *output = out;
415 uint32_t u[2];
416 uint32_t uiv[2];
418 load(*iv, uiv);
420 if (encp) {
421 while (length >= DES_CBLOCK_LEN) {
422 load(input, u);
423 u[0] ^= uiv[0]; u[1] ^= uiv[1];
424 DES_encrypt(u, ks, 1);
425 uiv[0] = u[0]; uiv[1] = u[1];
426 store(u, output);
428 length -= DES_CBLOCK_LEN;
429 input += DES_CBLOCK_LEN;
430 output += DES_CBLOCK_LEN;
432 if (length) {
433 unsigned char tmp[DES_CBLOCK_LEN];
434 memcpy(tmp, input, length);
435 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
436 load(tmp, u);
437 u[0] ^= uiv[0]; u[1] ^= uiv[1];
438 DES_encrypt(u, ks, 1);
439 store(u, output);
441 } else {
442 uint32_t t[2];
443 while (length >= DES_CBLOCK_LEN) {
444 load(input, u);
445 t[0] = u[0]; t[1] = u[1];
446 DES_encrypt(u, ks, 0);
447 u[0] ^= uiv[0]; u[1] ^= uiv[1];
448 store(u, output);
449 uiv[0] = t[0]; uiv[1] = t[1];
451 length -= DES_CBLOCK_LEN;
452 input += DES_CBLOCK_LEN;
453 output += DES_CBLOCK_LEN;
455 if (length) {
456 unsigned char tmp[DES_CBLOCK_LEN];
457 memcpy(tmp, input, length);
458 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
459 load(tmp, u);
460 DES_encrypt(u, ks, 0);
461 u[0] ^= uiv[0]; u[1] ^= uiv[1];
462 store(u, output);
465 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
469 * Encrypt/decrypt a block using DES in Propagating Cipher Block
470 * Chaining mode. This mode is only used for Kerberos 4, and it should
471 * stay that way.
473 * The IV must always be diffrent for diffrent input data blocks.
475 * @param in data to encrypt
476 * @param out data to encrypt
477 * @param length length of data
478 * @param ks key schedule to use
479 * @param iv initial vector to use
480 * @param encp if non zero, encrypt. if zero, decrypt.
482 * @ingroup hcrypto_des
485 void
486 DES_pcbc_encrypt(const void *in, void *out, long length,
487 DES_key_schedule *ks, DES_cblock *iv, int encp)
489 const unsigned char *input = in;
490 unsigned char *output = out;
491 uint32_t u[2];
492 uint32_t uiv[2];
494 load(*iv, uiv);
496 if (encp) {
497 uint32_t t[2];
498 while (length >= DES_CBLOCK_LEN) {
499 load(input, u);
500 t[0] = u[0]; t[1] = u[1];
501 u[0] ^= uiv[0]; u[1] ^= uiv[1];
502 DES_encrypt(u, ks, 1);
503 uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
504 store(u, output);
506 length -= DES_CBLOCK_LEN;
507 input += DES_CBLOCK_LEN;
508 output += DES_CBLOCK_LEN;
510 if (length) {
511 unsigned char tmp[DES_CBLOCK_LEN];
512 memcpy(tmp, input, length);
513 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
514 load(tmp, u);
515 u[0] ^= uiv[0]; u[1] ^= uiv[1];
516 DES_encrypt(u, ks, 1);
517 store(u, output);
519 } else {
520 uint32_t t[2];
521 while (length >= DES_CBLOCK_LEN) {
522 load(input, u);
523 t[0] = u[0]; t[1] = u[1];
524 DES_encrypt(u, ks, 0);
525 u[0] ^= uiv[0]; u[1] ^= uiv[1];
526 store(u, output);
527 uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
529 length -= DES_CBLOCK_LEN;
530 input += DES_CBLOCK_LEN;
531 output += DES_CBLOCK_LEN;
533 if (length) {
534 unsigned char tmp[DES_CBLOCK_LEN];
535 memcpy(tmp, input, length);
536 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
537 load(tmp, u);
538 DES_encrypt(u, ks, 0);
539 u[0] ^= uiv[0]; u[1] ^= uiv[1];
542 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
549 static void
550 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
551 DES_key_schedule *ks3, int encp)
553 IP(u);
554 if (encp) {
555 desx(u, ks1, 1); /* IP + FP cancel out each other */
556 desx(u, ks2, 0);
557 desx(u, ks3, 1);
558 } else {
559 desx(u, ks3, 0);
560 desx(u, ks2, 1);
561 desx(u, ks1, 0);
563 FP(u);
567 * Encrypt/decrypt a block using triple DES using EDE mode,
568 * encrypt/decrypt/encrypt.
570 * @param input data to encrypt
571 * @param output data to encrypt
572 * @param ks1 key schedule to use
573 * @param ks2 key schedule to use
574 * @param ks3 key schedule to use
575 * @param encp if non zero, encrypt. if zero, decrypt.
577 * @ingroup hcrypto_des
580 void
581 DES_ecb3_encrypt(DES_cblock *input,
582 DES_cblock *output,
583 DES_key_schedule *ks1,
584 DES_key_schedule *ks2,
585 DES_key_schedule *ks3,
586 int encp)
588 uint32_t u[2];
589 load(*input, u);
590 _des3_encrypt(u, ks1, ks2, ks3, encp);
591 store(u, *output);
592 return;
596 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
598 * The IV must always be diffrent for diffrent input data blocks.
600 * @param in data to encrypt
601 * @param out data to encrypt
602 * @param length length of data
603 * @param ks1 key schedule to use
604 * @param ks2 key schedule to use
605 * @param ks3 key schedule to use
606 * @param iv initial vector to use
607 * @param encp if non zero, encrypt. if zero, decrypt.
609 * @ingroup hcrypto_des
612 void
613 DES_ede3_cbc_encrypt(const void *in, void *out,
614 long length, DES_key_schedule *ks1,
615 DES_key_schedule *ks2, DES_key_schedule *ks3,
616 DES_cblock *iv, int encp)
618 const unsigned char *input = in;
619 unsigned char *output = out;
620 uint32_t u[2];
621 uint32_t uiv[2];
623 load(*iv, uiv);
625 if (encp) {
626 while (length >= DES_CBLOCK_LEN) {
627 load(input, u);
628 u[0] ^= uiv[0]; u[1] ^= uiv[1];
629 _des3_encrypt(u, ks1, ks2, ks3, 1);
630 uiv[0] = u[0]; uiv[1] = u[1];
631 store(u, output);
633 length -= DES_CBLOCK_LEN;
634 input += DES_CBLOCK_LEN;
635 output += DES_CBLOCK_LEN;
637 if (length) {
638 unsigned char tmp[DES_CBLOCK_LEN];
639 memcpy(tmp, input, length);
640 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
641 load(tmp, u);
642 u[0] ^= uiv[0]; u[1] ^= uiv[1];
643 _des3_encrypt(u, ks1, ks2, ks3, 1);
644 store(u, output);
646 } else {
647 uint32_t t[2];
648 while (length >= DES_CBLOCK_LEN) {
649 load(input, u);
650 t[0] = u[0]; t[1] = u[1];
651 _des3_encrypt(u, ks1, ks2, ks3, 0);
652 u[0] ^= uiv[0]; u[1] ^= uiv[1];
653 store(u, output);
654 uiv[0] = t[0]; uiv[1] = t[1];
656 length -= DES_CBLOCK_LEN;
657 input += DES_CBLOCK_LEN;
658 output += DES_CBLOCK_LEN;
660 if (length) {
661 unsigned char tmp[DES_CBLOCK_LEN];
662 memcpy(tmp, input, length);
663 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
664 load(tmp, u);
665 _des3_encrypt(u, ks1, ks2, ks3, 0);
666 u[0] ^= uiv[0]; u[1] ^= uiv[1];
667 store(u, output);
670 store(uiv, *iv);
671 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
675 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
676 * feedback.
678 * The IV must always be diffrent for diffrent input data blocks.
680 * @param in data to encrypt
681 * @param out data to encrypt
682 * @param length length of data
683 * @param ks key schedule to use
684 * @param iv initial vector to use
685 * @param num offset into in cipher block encryption/decryption stop last time.
686 * @param encp if non zero, encrypt. if zero, decrypt.
688 * @ingroup hcrypto_des
691 void
692 DES_cfb64_encrypt(const void *in, void *out,
693 long length, DES_key_schedule *ks, DES_cblock *iv,
694 int *num, int encp)
696 const unsigned char *input = in;
697 unsigned char *output = out;
698 unsigned char tmp[DES_CBLOCK_LEN];
699 uint32_t uiv[2];
701 load(*iv, uiv);
703 assert(*num >= 0 && *num < DES_CBLOCK_LEN);
705 if (encp) {
706 int i = *num;
708 while (length > 0) {
709 if (i == 0)
710 DES_encrypt(uiv, ks, 1);
711 store(uiv, tmp);
712 for (; i < DES_CBLOCK_LEN && i < length; i++) {
713 output[i] = tmp[i] ^ input[i];
715 if (i == DES_CBLOCK_LEN)
716 load(output, uiv);
717 output += i;
718 input += i;
719 length -= i;
720 if (i == DES_CBLOCK_LEN)
721 i = 0;
723 store(uiv, *iv);
724 *num = i;
725 } else {
726 int i = *num;
727 unsigned char c;
729 while (length > 0) {
730 if (i == 0) {
731 DES_encrypt(uiv, ks, 1);
732 store(uiv, tmp);
734 for (; i < DES_CBLOCK_LEN && i < length; i++) {
735 c = input[i];
736 output[i] = tmp[i] ^ input[i];
737 (*iv)[i] = c;
739 output += i;
740 input += i;
741 length -= i;
742 if (i == DES_CBLOCK_LEN) {
743 i = 0;
744 load(*iv, uiv);
747 store(uiv, *iv);
748 *num = i;
753 * Crete a checksum using DES in CBC encryption mode. This mode is
754 * only used for Kerberos 4, and it should stay that way.
756 * The IV must always be diffrent for diffrent input data blocks.
758 * @param in data to checksum
759 * @param output the checksum
760 * @param length length of data
761 * @param ks key schedule to use
762 * @param iv initial vector to use
764 * @ingroup hcrypto_des
767 uint32_t
768 DES_cbc_cksum(const void *in, DES_cblock *output,
769 long length, DES_key_schedule *ks, DES_cblock *iv)
771 const unsigned char *input = in;
772 uint32_t uiv[2];
773 uint32_t u[2] = { 0, 0 };
775 load(*iv, uiv);
777 while (length >= DES_CBLOCK_LEN) {
778 load(input, u);
779 u[0] ^= uiv[0]; u[1] ^= uiv[1];
780 DES_encrypt(u, ks, 1);
781 uiv[0] = u[0]; uiv[1] = u[1];
783 length -= DES_CBLOCK_LEN;
784 input += DES_CBLOCK_LEN;
786 if (length) {
787 unsigned char tmp[DES_CBLOCK_LEN];
788 memcpy(tmp, input, length);
789 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
790 load(tmp, u);
791 u[0] ^= uiv[0]; u[1] ^= uiv[1];
792 DES_encrypt(u, ks, 1);
794 if (output)
795 store(u, *output);
797 uiv[0] = 0; u[0] = 0; uiv[1] = 0;
798 return u[1];
805 static unsigned char
806 bitswap8(unsigned char b)
808 unsigned char r = 0;
809 int i;
810 for (i = 0; i < 8; i++) {
811 r = r << 1 | (b & 1);
812 b = b >> 1;
814 return r;
818 * Convert a string to a DES key. Use something like
819 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
821 * @param str The string to convert to a key
822 * @param key the resulting key
824 * @ingroup hcrypto_des
827 void
828 DES_string_to_key(const char *str, DES_cblock *key)
830 const unsigned char *s;
831 unsigned char *k;
832 DES_key_schedule ks;
833 size_t i, len;
835 memset(key, 0, sizeof(*key));
836 k = *key;
837 s = (const unsigned char *)str;
839 len = strlen(str);
840 for (i = 0; i < len; i++) {
841 if ((i % 16) < 8)
842 k[i % 8] ^= s[i] << 1;
843 else
844 k[7 - (i % 8)] ^= bitswap8(s[i]);
846 DES_set_odd_parity(key);
847 if (DES_is_weak_key(key))
848 k[7] ^= 0xF0;
849 DES_set_key(key, &ks);
850 DES_cbc_cksum(s, key, len, &ks, key);
851 memset(&ks, 0, sizeof(ks));
852 DES_set_odd_parity(key);
853 if (DES_is_weak_key(key))
854 k[7] ^= 0xF0;
858 * Read password from prompt and create a DES key. Internal uses
859 * DES_string_to_key(). Really, go use a really string2key function
860 * like PKCS5_PBKDF2_HMAC_SHA1().
862 * @param key key to convert to
863 * @param prompt prompt to display user
864 * @param verify prompt twice.
866 * @return 1 on success, non 1 on failure.
870 DES_read_password(DES_cblock *key, char *prompt, int verify)
872 char buf[512];
873 int ret;
875 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
876 if (ret == 1)
877 DES_string_to_key(buf, key);
878 return ret;
886 void
887 _DES_ipfp_test(void)
889 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
890 uint32_t u[2] = { 1, 0 };
891 IP(u);
892 FP(u);
893 IP(u);
894 FP(u);
895 if (u[0] != 1 || u[1] != 0)
896 abort();
898 load(k, u);
899 store(u, k2);
900 if (memcmp(k, k2, 8) != 0)
901 abort();
904 /* D3DES (V5.09) -
906 * A portable, public domain, version of the Data Encryption Standard.
908 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
909 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
910 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
911 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
912 * for humouring me on.
914 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
915 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
918 static uint32_t SP1[64] = {
919 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
920 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
921 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
922 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
923 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
924 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
925 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
926 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
927 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
928 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
929 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
930 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
931 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
932 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
933 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
934 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
936 static uint32_t SP2[64] = {
937 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
938 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
939 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
940 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
941 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
942 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
943 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
944 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
945 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
946 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
947 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
948 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
949 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
950 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
951 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
952 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
954 static uint32_t SP3[64] = {
955 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
956 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
957 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
958 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
959 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
960 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
961 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
962 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
963 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
964 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
965 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
966 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
967 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
968 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
969 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
970 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
972 static uint32_t SP4[64] = {
973 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
974 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
975 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
976 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
977 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
978 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
979 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
980 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
981 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
982 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
983 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
984 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
985 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
986 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
987 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
988 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
990 static uint32_t SP5[64] = {
991 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
992 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
993 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
994 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
995 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
996 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
997 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
998 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
999 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
1000 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
1001 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
1002 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
1003 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
1004 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
1005 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
1006 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
1008 static uint32_t SP6[64] = {
1009 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
1010 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
1011 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
1012 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
1013 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
1014 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
1015 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
1016 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
1017 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
1018 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
1019 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
1020 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
1021 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
1022 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
1023 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
1024 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
1026 static uint32_t SP7[64] = {
1027 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
1028 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
1029 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
1030 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
1031 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
1032 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
1033 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
1034 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
1035 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
1036 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
1037 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
1038 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
1039 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
1040 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
1041 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
1042 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
1044 static uint32_t SP8[64] = {
1045 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
1046 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
1047 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
1048 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
1049 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
1050 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
1051 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
1052 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
1053 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
1054 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
1055 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
1056 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
1057 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
1058 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
1059 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
1060 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
1062 static void
1063 IP(uint32_t v[2])
1065 uint32_t work;
1067 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1068 v[1] ^= work;
1069 v[0] ^= (work << 4);
1070 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1071 v[1] ^= work;
1072 v[0] ^= (work << 16);
1073 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1074 v[0] ^= work;
1075 v[1] ^= (work << 2);
1076 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1077 v[0] ^= work;
1078 v[1] ^= (work << 8);
1079 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
1080 work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
1081 v[0] ^= work;
1082 v[1] ^= work;
1083 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
1086 static void
1087 FP(uint32_t v[2])
1089 uint32_t work;
1091 v[0] = (v[0] << 31) | (v[0] >> 1);
1092 work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1093 v[1] ^= work;
1094 v[0] ^= work;
1095 v[1] = (v[1] << 31) | (v[1] >> 1);
1096 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1097 v[0] ^= work;
1098 v[1] ^= (work << 8);
1099 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1100 v[0] ^= work;
1101 v[1] ^= (work << 2);
1102 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1103 v[1] ^= work;
1104 v[0] ^= (work << 16);
1105 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1106 v[1] ^= work;
1107 v[0] ^= (work << 4);
1110 static void
1111 desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1113 uint32_t *keys;
1114 uint32_t fval, work, right, left;
1115 int round;
1117 left = block[0];
1118 right = block[1];
1120 if (encp) {
1121 keys = &ks->ks[0];
1123 for( round = 0; round < 8; round++ ) {
1124 work = (right << 28) | (right >> 4);
1125 work ^= *keys++;
1126 fval = SP7[ work & 0x3fL];
1127 fval |= SP5[(work >> 8) & 0x3fL];
1128 fval |= SP3[(work >> 16) & 0x3fL];
1129 fval |= SP1[(work >> 24) & 0x3fL];
1130 work = right ^ *keys++;
1131 fval |= SP8[ work & 0x3fL];
1132 fval |= SP6[(work >> 8) & 0x3fL];
1133 fval |= SP4[(work >> 16) & 0x3fL];
1134 fval |= SP2[(work >> 24) & 0x3fL];
1135 left ^= fval;
1136 work = (left << 28) | (left >> 4);
1137 work ^= *keys++;
1138 fval = SP7[ work & 0x3fL];
1139 fval |= SP5[(work >> 8) & 0x3fL];
1140 fval |= SP3[(work >> 16) & 0x3fL];
1141 fval |= SP1[(work >> 24) & 0x3fL];
1142 work = left ^ *keys++;
1143 fval |= SP8[ work & 0x3fL];
1144 fval |= SP6[(work >> 8) & 0x3fL];
1145 fval |= SP4[(work >> 16) & 0x3fL];
1146 fval |= SP2[(work >> 24) & 0x3fL];
1147 right ^= fval;
1149 } else {
1150 keys = &ks->ks[30];
1152 for( round = 0; round < 8; round++ ) {
1153 work = (right << 28) | (right >> 4);
1154 work ^= *keys++;
1155 fval = SP7[ work & 0x3fL];
1156 fval |= SP5[(work >> 8) & 0x3fL];
1157 fval |= SP3[(work >> 16) & 0x3fL];
1158 fval |= SP1[(work >> 24) & 0x3fL];
1159 work = right ^ *keys++;
1160 fval |= SP8[ work & 0x3fL];
1161 fval |= SP6[(work >> 8) & 0x3fL];
1162 fval |= SP4[(work >> 16) & 0x3fL];
1163 fval |= SP2[(work >> 24) & 0x3fL];
1164 left ^= fval;
1165 work = (left << 28) | (left >> 4);
1166 keys -= 4;
1167 work ^= *keys++;
1168 fval = SP7[ work & 0x3fL];
1169 fval |= SP5[(work >> 8) & 0x3fL];
1170 fval |= SP3[(work >> 16) & 0x3fL];
1171 fval |= SP1[(work >> 24) & 0x3fL];
1172 work = left ^ *keys++;
1173 fval |= SP8[ work & 0x3fL];
1174 fval |= SP6[(work >> 8) & 0x3fL];
1175 fval |= SP4[(work >> 16) & 0x3fL];
1176 fval |= SP2[(work >> 24) & 0x3fL];
1177 right ^= fval;
1178 keys -= 4;
1181 block[0] = right;
1182 block[1] = left;