1 /* crypto-des.c --- DES crypto functions.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
28 /* Get _shishi_escapeprint, etc. */
32 raw_des_checksum0 (Shishi
* handle
, int algo
,
33 const char *in
, size_t inlen
, char *out
, size_t * outlen
)
39 int hlen
= (algo
== SHISHI_DES_CBC_CRC
) ? 4 : 16;
42 rc
= shishi_randomize (handle
, 0, out
, blen
);
46 tmplen
= blen
+ inlen
;
47 tmp
= xmalloc (tmplen
);
49 memcpy (tmp
, out
, blen
);
50 memcpy (tmp
+ blen
, in
, inlen
);
54 case SHISHI_DES_CBC_CRC
:
55 rc
= shishi_crc (handle
, tmp
, tmplen
, &p
);
58 case SHISHI_DES_CBC_MD4
:
59 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
);
62 case SHISHI_DES_CBC_MD5
:
63 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
);
67 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
68 return SHISHI_CRYPTO_INTERNAL_ERROR
;
72 memcpy (out
+ blen
, p
, hlen
);
74 *outlen
= blen
+ hlen
;
80 raw_des_checksum1 (Shishi
* handle
, int algo
,
81 const char *in
, size_t inlen
, char *out
, size_t * outlen
)
87 int hlen
= (algo
== SHISHI_DES_CBC_CRC
) ? 4 : 16;
90 rc
= shishi_randomize (handle
, 0, out
, blen
);
94 memset (out
+ blen
, 0, hlen
);
96 tmplen
= blen
+ hlen
+ inlen
;
97 tmp
= xmalloc (tmplen
);
99 memcpy (tmp
, out
, blen
+ hlen
);
100 memcpy (tmp
+ blen
+ hlen
, in
, inlen
);
104 case SHISHI_DES_CBC_CRC
:
105 rc
= shishi_crc (handle
, tmp
, tmplen
, &p
);
108 case SHISHI_DES_CBC_MD4
:
109 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
);
112 case SHISHI_DES_CBC_MD5
:
113 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
);
117 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
118 return SHISHI_CRYPTO_INTERNAL_ERROR
;
124 memcpy (out
+ blen
, p
, hlen
);
128 *outlen
= blen
+ hlen
;
134 des_encrypt_checksum (Shishi
* handle
,
137 const char *iv
, size_t ivlen
,
138 char **ivout
, size_t * ivoutlen
,
139 const char *in
, size_t inlen
,
140 char **out
, size_t * outlen
, int algo
)
142 char cksum
[8 + MAX_HASH_LEN
];
145 size_t inpadlen
, padzerolen
= 0, ptlen
, cksumlen
;
146 int hlen
= (algo
== SHISHI_DES_CBC_CRC
) ? 4 : 16;
149 if ((inlen
+ hlen
) % 8)
150 padzerolen
= 8 - ((inlen
+ hlen
) % 8);
151 inpadlen
= inlen
+ padzerolen
;
152 inpad
= xmalloc (inpadlen
);
154 memcpy (inpad
, in
, inlen
);
155 memset (inpad
+ inlen
, 0, padzerolen
);
157 res
= raw_des_checksum1 (handle
, algo
, inpad
, inpadlen
, cksum
, &cksumlen
);
158 if (res
!= SHISHI_OK
)
160 shishi_error_printf (handle
, "DES checksum failed");
164 ptlen
= inpadlen
+ cksumlen
;
165 pt
= xmalloc (ptlen
);
166 memcpy (pt
, cksum
, cksumlen
);
167 memcpy (pt
+ cksumlen
, inpad
, inpadlen
);
171 res
= _shishi_simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
172 ivout
, ivoutlen
, pt
, ptlen
, out
, outlen
);
176 if (res
!= SHISHI_OK
)
178 shishi_error_printf (handle
, "DES encrypt failed");
186 des_crc_encrypt (Shishi
* handle
,
189 const char *iv
, size_t ivlen
,
190 char **ivout
, size_t * ivoutlen
,
191 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
193 return des_encrypt_checksum (handle
, key
, keyusage
,
194 shishi_key_value (key
),
195 shishi_key_length (key
), ivout
, ivoutlen
, in
,
196 inlen
, out
, outlen
, SHISHI_DES_CBC_CRC
);
200 des_md4_encrypt (Shishi
* handle
,
205 char **ivout
, size_t * ivoutlen
,
206 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
208 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
209 ivoutlen
, in
, inlen
, out
, outlen
,
214 des_md5_encrypt (Shishi
* handle
,
219 char **ivout
, size_t * ivoutlen
,
220 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
222 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
223 ivoutlen
, in
, inlen
, out
, outlen
,
228 des_none_encrypt (Shishi
* handle
,
233 char **ivout
, size_t * ivoutlen
,
234 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
236 return _shishi_simplified_encrypt (handle
, key
, 0, iv
, ivlen
, ivout
,
237 ivoutlen
, in
, inlen
, out
, outlen
);
241 des_decrypt_verify (Shishi
* handle
,
244 const char *iv
, size_t ivlen
,
245 char **ivout
, size_t * ivoutlen
,
246 const char *in
, size_t inlen
,
247 char **out
, size_t * outlen
, int algo
)
252 size_t hlen
= (algo
== SHISHI_DES_CBC_CRC
) ? 4 : 16;
254 res
= _shishi_simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
255 ivout
, ivoutlen
, in
, inlen
, out
, outlen
);
256 if (res
!= SHISHI_OK
)
258 shishi_error_printf (handle
, "decrypt failed");
262 if (VERBOSECRYPTONOISE (handle
))
264 puts ("verify decrypted:");
265 _shishi_escapeprint (*out
, *outlen
);
266 _shishi_hexprint (*out
, *outlen
);
269 memcpy (incoming
, *out
+ 8, hlen
);
270 memset (*out
+ 8, 0, hlen
);
272 if (VERBOSECRYPTONOISE (handle
))
275 _shishi_hexprint (*out
, *outlen
);
280 case SHISHI_DES_CBC_CRC
:
281 shishi_crc (handle
, *out
, *outlen
, &computed
);
284 case SHISHI_DES_CBC_MD4
:
285 shishi_md4 (handle
, *out
, *outlen
, &computed
);
288 case SHISHI_DES_CBC_MD5
:
289 shishi_md5 (handle
, *out
, *outlen
, &computed
);
293 shishi_error_printf (handle
, "MD %d unknown in raw des verify", algo
);
294 return SHISHI_CRYPTO_ERROR
;
298 if (VERBOSECRYPTONOISE (handle
))
300 puts ("DES verify:");
301 _shishi_hexprint (incoming
, hlen
);
302 _shishi_hexprint (computed
, hlen
);
305 if (memcmp (computed
, incoming
, hlen
) != 0)
307 shishi_error_printf (handle
, "DES hash verify failed");
308 return SHISHI_CRYPTO_ERROR
;
313 memmove (*out
, *out
+ 8 + hlen
, *outlen
- 8 - hlen
);
320 des_crc_decrypt (Shishi
* handle
,
325 char **ivout
, size_t * ivoutlen
,
326 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
328 return des_decrypt_verify (handle
, key
, keyusage
,
329 shishi_key_value (key
), shishi_key_length (key
),
330 ivout
, ivoutlen
, in
, inlen
, out
, outlen
,
335 des_md4_decrypt (Shishi
* handle
,
340 char **ivout
, size_t * ivoutlen
,
341 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
343 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
344 ivoutlen
, in
, inlen
, out
, outlen
,
349 des_md5_decrypt (Shishi
* handle
,
354 char **ivout
, size_t * ivoutlen
,
355 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
357 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
358 ivoutlen
, in
, inlen
, out
, outlen
,
363 des_none_decrypt (Shishi
* handle
,
368 char **ivout
, size_t * ivoutlen
,
369 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
371 return _shishi_simplified_decrypt (handle
, key
, 0, iv
, ivlen
, ivout
,
372 ivoutlen
, in
, inlen
, out
, outlen
);
376 des_set_odd_key_parity (char key
[8])
380 for (i
= 0; i
< 8; i
++)
384 for (j
= 1; j
< 8; j
++)
385 if (key
[i
] & (1 << j
))
389 if ((n_set_bits
% 2) == 0)
394 static char weak_des_keys
[16][8] = {
396 "\x01\x01\x01\x01\x01\x01\x01\x01",
397 "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
398 "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
399 "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
401 "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
402 "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
403 "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
404 "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
405 "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
406 "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
407 "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
408 "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
409 "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
410 "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
411 "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
412 "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
416 des_key_correction (Shishi
* handle
, char key
[8])
420 /* fixparity(key); */
421 des_set_odd_key_parity (key
);
423 /* This loop could be replaced by optimized code (compare nettle),
424 but let's not do that. */
425 for (i
= 0; i
< 16; i
++)
426 if (memcmp (key
, weak_des_keys
[i
], 8) == 0)
428 if (VERBOSECRYPTONOISE (handle
))
429 printf ("\t ;; WEAK KEY (corrected)\n");
436 des_random_to_key (Shishi
* handle
,
437 const char *rnd
, size_t rndlen
, Shishi_key
* outkey
)
439 char tmp
[MAX_RANDOM_LEN
];
440 int keylen
= shishi_cipher_keylen (shishi_key_type (outkey
));
442 if (rndlen
!= shishi_key_length (outkey
))
444 shishi_error_printf (handle
, "DES random to key caller error");
445 return SHISHI_CRYPTO_ERROR
;
448 memcpy (tmp
, rnd
, keylen
);
449 des_set_odd_key_parity (tmp
);
451 shishi_key_value_set (outkey
, tmp
);
457 des_string_to_key (Shishi
* handle
,
461 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
472 if (VERBOSECRYPTO (handle
))
474 printf ("des_string_to_key (string, salt)\n");
475 printf ("\t ;; String:\n");
476 _shishi_escapeprint (string
, stringlen
);
477 _shishi_hexprint (string
, stringlen
);
478 printf ("\t ;; Salt:\n");
479 _shishi_escapeprint (salt
, saltlen
);
480 _shishi_hexprint (salt
, saltlen
);
483 if (VERBOSECRYPTONOISE (handle
))
485 printf ("odd = 1;\n");
486 printf ("s = string | salt;\n");
487 printf ("tempstring = 0; /* 56-bit string */\n");
488 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
493 n_s
= stringlen
+ saltlen
;
496 s
= (char *) xmalloc (n_s
);
497 memcpy (s
, string
, stringlen
);
499 memcpy (s
+ stringlen
, salt
, saltlen
);
500 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
501 memset (tempkey
, 0, sizeof (tempkey
)); /* tempkey = NULL; */
503 if (VERBOSECRYPTONOISE (handle
))
505 printf ("\t ;; s = pad(string|salt):\n");
506 _shishi_escapeprint (s
, n_s
);
507 _shishi_hexprint (s
, n_s
);
510 for (i
= 0; i
< n_s
/ 8; i
++)
512 if (VERBOSECRYPTONOISE (handle
))
514 printf ("for (8byteblock in s) {\n");
515 printf ("\t ;; loop iteration %d\n", i
);
516 printf ("\t ;; 8byteblock:\n");
517 _shishi_escapeprint (&s
[i
* 8], 8);
518 _shishi_hexprint (&s
[i
* 8], 8);
519 _shishi_binprint (&s
[i
* 8], 8);
520 printf ("56bitstring = removeMSBits(8byteblock);\n");
523 for (j
= 0; j
< 8; j
++)
524 s
[i
* 8 + j
] = s
[i
* 8 + j
] & ~0x80;
526 if (VERBOSECRYPTONOISE (handle
))
528 printf ("\t ;; 56bitstring:\n");
529 _shishi_bin7print (&s
[i
* 8], 8);
530 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
535 for (j
= 0; j
< 4; j
++)
539 ((temp
>> 6) & 0x01) |
540 ((temp
>> 4) & 0x02) |
541 ((temp
>> 2) & 0x04) |
543 ((temp
<< 2) & 0x10) |
544 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
545 temp2
= s
[i
* 8 + 7 - j
];
547 ((temp2
>> 6) & 0x01) |
548 ((temp2
>> 4) & 0x02) |
549 ((temp2
>> 2) & 0x04) |
551 ((temp2
<< 2) & 0x10) |
552 ((temp2
<< 4) & 0x20) | ((temp2
<< 6) & 0x40);
553 s
[i
* 8 + j
] = temp2
;
554 s
[i
* 8 + 7 - j
] = temp
;
556 if (VERBOSECRYPTONOISE (handle
))
558 printf ("reverse(56bitstring)\n");
559 printf ("\t ;; 56bitstring after reverse\n");
560 _shishi_bin7print (&s
[i
* 8], 8);
566 if (VERBOSECRYPTONOISE (handle
))
568 printf ("odd = ! odd\n");
569 printf ("tempstring = tempstring XOR 56bitstring;\n");
572 /* tempkey = tempkey XOR 8byteblock; */
573 for (j
= 0; j
< 8; j
++)
574 tempkey
[j
] ^= s
[i
* 8 + j
];
576 if (VERBOSECRYPTONOISE (handle
))
578 printf ("\t ;; tempstring\n");
579 _shishi_bin7print (tempkey
, 8);
583 for (j
= 0; j
< 8; j
++)
584 tempkey
[j
] = tempkey
[j
] << 1;
586 if (VERBOSECRYPTONOISE (handle
))
588 printf ("for (8byteblock in s) {\n");
590 printf ("\t ;; for loop terminated\n");
591 printf ("\t ;; tempstring as 64bitblock\n");
592 _shishi_hexprint (tempkey
, 8);
593 _shishi_binprint (tempkey
, 8);
594 printf ("/* add parity as low bit of each byte */\n");
595 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
598 des_key_correction (handle
, tempkey
);
600 if (VERBOSECRYPTONOISE (handle
))
602 printf ("\t ;; tempkey\n");
603 _shishi_escapeprint (tempkey
, 8);
604 _shishi_hexprint (tempkey
, 8);
605 _shishi_binprint (tempkey
, 8);
606 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
609 memcpy (s
, string
, stringlen
);
611 memcpy (s
+ stringlen
, salt
, saltlen
);
612 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
614 res
= shishi_des_cbc_mac (handle
, tempkey
, tempkey
, s
, n_s
, &p
);
615 if (res
!= SHISHI_OK
)
618 memcpy (tempkey
, p
, 8);
621 des_key_correction (handle
, tempkey
);
623 if (VERBOSECRYPTO (handle
))
625 printf ("\t ;; key\n");
626 _shishi_escapeprint (tempkey
, 8);
627 _shishi_hexprint (tempkey
, 8);
628 _shishi_binprint (tempkey
, 8);
631 shishi_key_value_set (outkey
, tempkey
);
637 des_checksum (Shishi
* handle
,
641 const char *in
, size_t inlen
,
642 char **out
, size_t * outlen
, int algo
)
644 char cksum
[8 + MAX_HASH_LEN
];
650 res
= raw_des_checksum0 (handle
, algo
, in
, inlen
, cksum
, &cksumlen
);
651 if (res
!= SHISHI_OK
)
653 shishi_error_set (handle
, "raw des checksum failed");
657 keyp
= shishi_key_value (key
);
659 for (i
= 0; i
< 8; i
++)
662 res
= _shishi_simplified_dencrypt (handle
, key
, NULL
, 0, NULL
, NULL
,
663 cksum
, cksumlen
, out
, outlen
, 0);
665 for (i
= 0; i
< 8; i
++)
668 if (res
!= SHISHI_OK
)
670 shishi_error_set (handle
, "encrypt failed");
678 des_crc_checksum (Shishi
* handle
,
682 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
684 return des_checksum (handle
, key
, keyusage
, cksumtype
,
685 in
, inlen
, out
, outlen
, SHISHI_DES_CBC_CRC
);
689 des_md4_checksum (Shishi
* handle
,
693 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
695 return des_checksum (handle
, key
, keyusage
, cksumtype
,
696 in
, inlen
, out
, outlen
, SHISHI_DES_CBC_MD4
);
700 des_md5_checksum (Shishi
* handle
,
704 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
706 return des_checksum (handle
, key
, keyusage
, cksumtype
,
707 in
, inlen
, out
, outlen
, SHISHI_DES_CBC_MD5
);
711 gss_des_checksum (Shishi
* handle
,
715 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
720 rc
= shishi_md5 (handle
, in
, inlen
, &p
);
725 rc
= shishi_des_cbc_mac (handle
, shishi_key_value (key
), NULL
, p
, 16, out
);
736 des_verify (Shishi
* handle
, int algo
,
738 const char *in
, size_t inlen
, const char *cksum
, size_t cksumlen
)
749 if (cksumlen
!= 8 + 16)
750 return SHISHI_VERIFY_FAILED
;
753 * get_mic des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
754 * conf | rsa-md5(conf | msg))
755 * verify_mic decrypt and verify rsa-md5 checksum
758 keyp
= shishi_key_value (key
);
760 for (i
= 0; i
< 8; i
++)
763 res
= _shishi_simplified_decrypt (handle
, key
, 0, NULL
, 0, NULL
, NULL
,
764 cksum
, cksumlen
, &out
, &outlen
);
766 for (i
= 0; i
< 8; i
++)
769 if (res
!= SHISHI_OK
)
771 shishi_error_set (handle
, "decrypt failed");
776 tmp
= xmalloc (tmplen
);
777 memcpy (tmp
, out
, 8);
778 memcpy (tmp
+ 8, in
, inlen
);
782 case SHISHI_RSA_MD4_DES
:
783 res
= shishi_md4 (handle
, tmp
, tmplen
, &md
);
786 case SHISHI_RSA_MD5_DES
:
787 res
= shishi_md5 (handle
, tmp
, tmplen
, &md
);
791 res
= SHISHI_CRYPTO_ERROR
;
794 if (res
!= SHISHI_OK
)
796 shishi_error_printf (handle
, "DES verify MD error");
800 if (memcmp (out
+ 8, md
, 16) != 0)
801 return SHISHI_VERIFY_FAILED
;
807 des_md4_verify (Shishi
* handle
,
811 const char *in
, size_t inlen
,
812 const char *cksum
, size_t cksumlen
)
814 return des_verify (handle
, SHISHI_RSA_MD4_DES
, key
,
815 in
, inlen
, cksum
, cksumlen
);
819 des_md5_verify (Shishi
* handle
,
823 const char *in
, size_t inlen
,
824 const char *cksum
, size_t cksumlen
)
826 return des_verify (handle
, SHISHI_RSA_MD5_DES
, key
,
827 in
, inlen
, cksum
, cksumlen
);
830 cipherinfo des_cbc_crc_info
= {
844 cipherinfo des_cbc_md4_info
= {
858 cipherinfo des_cbc_md5_info
= {
872 cipherinfo des_cbc_none_info
= {
886 checksuminfo crc32_info
= {
893 checksuminfo md4_des_info
= {
901 checksuminfo md5_des_info
= {
909 checksuminfo md5_gss_info
= {
910 SHISHI_RSA_MD5_DES_GSS
,