1 /* crypto-des.c DES crypto functions
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Note: This file is #include'd by crypto.c.
25 raw_des_checksum0 (Shishi
* handle
, int algo
,
26 const char *in
, size_t inlen
,
27 char *out
, size_t * outlen
)
36 rc
= shishi_randomize (handle
, out
, blen
);
40 tmplen
= blen
+ inlen
;
41 tmp
= xmalloc (tmplen
);
43 memcpy (tmp
, out
, blen
);
44 memcpy (tmp
+ blen
, in
, inlen
);
48 case SHISHI_DES_CBC_MD4
:
49 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
);
52 case SHISHI_DES_CBC_MD5
:
53 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
);
57 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
58 return SHISHI_CRYPTO_INTERNAL_ERROR
;
62 memcpy (out
+ blen
, p
, hlen
);
64 *outlen
= blen
+ hlen
;
70 raw_des_checksum1 (Shishi
* handle
, int algo
,
71 const char *in
, size_t inlen
,
72 char *out
, size_t * outlen
)
81 rc
= shishi_randomize (handle
, out
, blen
);
85 memset (out
+ blen
, 0, hlen
);
87 tmplen
= blen
+ hlen
+ inlen
;
88 tmp
= xmalloc (tmplen
);
90 memcpy (tmp
, out
, blen
+ hlen
);
91 memcpy (tmp
+ blen
+ hlen
, in
, inlen
);
95 case SHISHI_DES_CBC_MD4
:
96 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
);
99 case SHISHI_DES_CBC_MD5
:
100 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
);
104 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
105 return SHISHI_CRYPTO_INTERNAL_ERROR
;
109 memcpy (out
+ blen
, p
, hlen
);
111 *outlen
= blen
+ hlen
;
117 des_encrypt_checksum (Shishi
* handle
,
120 const char *iv
, size_t ivlen
,
121 char **ivout
, size_t * ivoutlen
,
122 const char *in
, size_t inlen
,
123 char **out
, size_t * outlen
, int algo
)
125 char cksum
[8 + MAX_HASH_LEN
];
128 size_t inpadlen
, padzerolen
= 0, ptlen
, cksumlen
;
132 padzerolen
= 8 - (inlen
% 8);
133 inpadlen
= inlen
+ padzerolen
;
134 inpad
= xmalloc (inpadlen
);
136 memcpy (inpad
, in
, inlen
);
137 memset (inpad
+ inlen
, 0, padzerolen
);
139 res
= raw_des_checksum1 (handle
, algo
, inpad
, inpadlen
, cksum
, &cksumlen
);
140 if (res
!= SHISHI_OK
)
142 shishi_error_printf (handle
, "DES checksum failed");
146 ptlen
= inpadlen
+ cksumlen
;
147 pt
= xmalloc (ptlen
);
148 memcpy (pt
, cksum
, cksumlen
);
149 memcpy (pt
+ cksumlen
, inpad
, inpadlen
);
153 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
154 pt
, ptlen
, out
, outlen
);
158 if (res
!= SHISHI_OK
)
160 shishi_error_printf (handle
, "DES encrypt failed");
168 des_crc_encrypt (Shishi
* handle
,
171 const char *iv
, size_t ivlen
,
172 char **ivout
, size_t * ivoutlen
,
173 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
175 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
176 ivoutlen
, in
, inlen
, out
, outlen
,
181 des_md4_encrypt (Shishi
* handle
,
186 char **ivout
, size_t * ivoutlen
,
187 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
189 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
190 ivoutlen
, in
, inlen
, out
, outlen
,
195 des_md5_encrypt (Shishi
* handle
,
200 char **ivout
, size_t * ivoutlen
,
201 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
203 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
204 ivoutlen
, in
, inlen
, out
, outlen
,
209 des_none_encrypt (Shishi
* handle
,
214 char **ivout
, size_t * ivoutlen
,
215 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
217 return simplified_encrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
218 in
, inlen
, out
, outlen
);
222 des_decrypt_verify (Shishi
* handle
,
225 const char *iv
, size_t ivlen
,
226 char **ivout
, size_t * ivoutlen
,
227 const char *in
, size_t inlen
,
228 char **out
, size_t * outlen
, int algo
)
235 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
236 in
, inlen
, out
, outlen
);
237 if (res
!= SHISHI_OK
)
239 shishi_error_printf (handle
, "decrypt failed");
243 memcpy (incoming
, *out
+ 8, hlen
);
244 memset (*out
+ 8, 0, hlen
);
248 case SHISHI_DES_CBC_MD4
:
249 shishi_md4 (handle
, *out
, *outlen
, &computed
);
252 case SHISHI_DES_CBC_MD5
:
253 shishi_md5 (handle
, *out
, *outlen
, &computed
);
257 shishi_error_printf (handle
, "MD %d unknown in raw des verify", algo
);
258 return SHISHI_CRYPTO_ERROR
;
262 if (VERBOSECRYPTO (handle
))
264 puts ("DES verify:");
265 hexprint (incoming
, hlen
);
267 hexprint (computed
, hlen
);
271 if (memcmp (computed
, incoming
, hlen
) != 0)
273 shishi_error_printf (handle
, "DES hash verify failed");
274 return SHISHI_CRYPTO_ERROR
;
279 memmove (*out
, *out
+ 8 + hlen
, *outlen
- 8 - hlen
);
286 des_crc_decrypt (Shishi
* handle
,
291 char **ivout
, size_t * ivoutlen
,
292 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
294 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
295 ivoutlen
, in
, inlen
, out
, outlen
,
300 des_md4_decrypt (Shishi
* handle
,
305 char **ivout
, size_t * ivoutlen
,
306 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
308 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
309 ivoutlen
, in
, inlen
, out
, outlen
,
314 des_md5_decrypt (Shishi
* handle
,
319 char **ivout
, size_t * ivoutlen
,
320 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
322 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
323 ivoutlen
, in
, inlen
, out
, outlen
,
328 des_none_decrypt (Shishi
* handle
,
333 char **ivout
, size_t * ivoutlen
,
334 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
336 return simplified_decrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
337 in
, inlen
, out
, outlen
);
341 des_set_odd_key_parity (char key
[8])
345 for (i
= 0; i
< 8; i
++)
349 for (j
= 1; j
< 8; j
++)
350 if (key
[i
] & (1 << j
))
354 if ((n_set_bits
% 2) == 0)
361 static char weak_des_keys
[16][8] = {
363 "\x01\x01\x01\x01\x01\x01\x01\x01",
364 "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
365 "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
366 "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
368 "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
369 "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
370 "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
371 "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
372 "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
373 "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
374 "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
375 "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
376 "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
377 "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
378 "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
379 "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
383 des_key_correction (Shishi
* handle
, char key
[8])
387 /* fixparity(key); */
388 des_set_odd_key_parity (key
);
390 /* This loop could be replaced by optimized code (compare nettle),
391 but let's not do that. */
392 for (i
= 0; i
< 16; i
++)
393 if (memcmp (key
, weak_des_keys
[i
], 8) == 0)
395 if (VERBOSECRYPTO (handle
))
396 printf ("\t ;; WEAK KEY (corrected)\n");
405 des_random_to_key (Shishi
* handle
,
406 const char *random
, size_t randomlen
, Shishi_key
* outkey
)
408 char tmp
[MAX_RANDOM_LEN
];
409 int keylen
= shishi_cipher_keylen (shishi_key_type (outkey
));
411 if (randomlen
!= shishi_key_length (outkey
))
413 shishi_error_printf (handle
, "DES random to key caller error");
414 return SHISHI_CRYPTO_ERROR
;
417 memcpy (tmp
, random
, keylen
);
418 des_set_odd_key_parity (tmp
);
420 shishi_key_value_set (outkey
, tmp
);
426 des_string_to_key (Shishi
* handle
,
430 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
441 if (VERBOSECRYPTO (handle
))
443 printf ("des_string_to_key (string, salt)\n");
445 printf ("\t ;; String:\n");
446 escapeprint (string
, stringlen
);
447 hexprint (string
, stringlen
);
451 printf ("\t ;; Salt:\n");
452 escapeprint (salt
, saltlen
);
453 hexprint (salt
, saltlen
);
456 printf ("odd = 1;\n");
457 printf ("s = string | salt;\n");
458 printf ("tempstring = 0; /* 56-bit string */\n");
459 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
464 n_s
= stringlen
+ saltlen
;
467 s
= (char *) xmalloc (n_s
);
468 memcpy (s
, string
, stringlen
);
470 memcpy (s
+ stringlen
, salt
, saltlen
);
471 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
472 memset (tempkey
, 0, sizeof (tempkey
)); /* tempkey = NULL; */
474 if (VERBOSECRYPTO (handle
))
476 printf ("\t ;; s = pad(string|salt):\n");
477 escapeprint (s
, n_s
);
482 for (i
= 0; i
< n_s
/ 8; i
++)
484 if (VERBOSECRYPTO (handle
))
486 printf ("for (8byteblock in s) {\n");
487 printf ("\t ;; loop iteration %d\n", i
);
488 printf ("\t ;; 8byteblock:\n");
489 escapeprint (&s
[i
* 8], 8);
490 hexprint (&s
[i
* 8], 8);
492 binprint (&s
[i
* 8], 8);
494 printf ("56bitstring = removeMSBits(8byteblock);\n");
497 for (j
= 0; j
< 8; j
++)
498 s
[i
* 8 + j
] = s
[i
* 8 + j
] & ~0x80;
500 if (VERBOSECRYPTO (handle
))
502 printf ("\t ;; 56bitstring:\n");
503 bin7print (&s
[i
* 8], 8);
505 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
510 for (j
= 0; j
< 4; j
++)
514 ((temp
>> 6) & 0x01) |
515 ((temp
>> 4) & 0x02) |
516 ((temp
>> 2) & 0x04) |
518 ((temp
<< 2) & 0x10) |
519 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
520 temp2
= s
[i
* 8 + 7 - j
];
522 ((temp2
>> 6) & 0x01) |
523 ((temp2
>> 4) & 0x02) |
524 ((temp2
>> 2) & 0x04) |
526 ((temp2
<< 2) & 0x10) |
527 ((temp2
<< 4) & 0x20) | ((temp2
<< 6) & 0x40);
528 s
[i
* 8 + j
] = temp2
;
529 s
[i
* 8 + 7 - j
] = temp
;
531 if (VERBOSECRYPTO (handle
))
533 printf ("reverse(56bitstring)\n");
534 printf ("\t ;; 56bitstring after reverse\n");
535 bin7print (&s
[i
* 8], 8);
542 if (VERBOSECRYPTO (handle
))
544 printf ("odd = ! odd\n");
545 printf ("tempstring = tempstring XOR 56bitstring;\n");
548 /* tempkey = tempkey XOR 8byteblock; */
549 for (j
= 0; j
< 8; j
++)
550 tempkey
[j
] ^= s
[i
* 8 + j
];
552 if (VERBOSECRYPTO (handle
))
554 printf ("\t ;; tempstring\n");
555 bin7print (tempkey
, 8);
561 for (j
= 0; j
< 8; j
++)
562 tempkey
[j
] = tempkey
[j
] << 1;
564 if (VERBOSECRYPTO (handle
))
566 printf ("for (8byteblock in s) {\n");
568 printf ("\t ;; for loop terminated\n");
569 printf ("\t ;; tempstring as 64bitblock\n");
570 hexprint (tempkey
, 8);
572 binprint (tempkey
, 8);
574 printf ("/* add parity as low bit of each byte */\n");
575 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
578 res
= des_key_correction (handle
, tempkey
);
579 if (res
!= SHISHI_OK
)
582 if (VERBOSECRYPTO (handle
))
584 printf ("\t ;; tempkey\n");
585 escapeprint (tempkey
, 8);
586 hexprint (tempkey
, 8);
588 binprint (tempkey
, 8);
591 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
594 memcpy (s
, string
, stringlen
);
596 memcpy (s
+ stringlen
, salt
, saltlen
);
597 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
599 res
= shishi_des_cbc_mac (handle
, tempkey
, tempkey
, s
, n_s
, &p
);
600 if (res
!= SHISHI_OK
)
602 memcpy (tempkey
, p
, 8);
605 res
= des_key_correction (handle
, tempkey
);
606 if (res
!= SHISHI_OK
)
609 if (VERBOSECRYPTO (handle
))
611 printf ("\t ;; key\n");
612 escapeprint (tempkey
, 8);
613 hexprint (tempkey
, 8);
615 binprint (tempkey
, 8);
620 shishi_key_value_set (outkey
, tempkey
);
626 des_checksum (Shishi
* handle
,
630 const char *in
, size_t inlen
,
631 char **out
, size_t * outlen
, int algo
)
633 char cksum
[8 + MAX_HASH_LEN
];
639 res
= raw_des_checksum0 (handle
, algo
, in
, inlen
, cksum
, &cksumlen
);
640 if (res
!= SHISHI_OK
)
642 shishi_error_set (handle
, "raw des checksum failed");
646 keyp
= shishi_key_value (key
);
648 for (i
= 0; i
< 8; i
++)
651 res
= simplified_dencrypt (handle
, key
, NULL
, 0, NULL
, NULL
,
652 cksum
, cksumlen
, out
, outlen
, 0);
654 for (i
= 0; i
< 8; i
++)
657 if (res
!= SHISHI_OK
)
659 shishi_error_set (handle
, "encrypt failed");
667 des_md4_checksum (Shishi
* handle
,
671 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
673 return des_checksum (handle
, key
, keyusage
, cksumtype
,
674 in
, inlen
, out
, outlen
, SHISHI_DES_CBC_MD4
);
678 des_md5_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_MD5
);
689 gss_des_checksum (Shishi
* handle
,
693 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
698 rc
= shishi_md5 (handle
, in
, inlen
, &p
);
703 rc
= shishi_des_cbc_mac (handle
, shishi_key_value (key
), NULL
, p
, 16, out
);
714 des_verify (Shishi
* handle
, int algo
,
716 const char *in
, size_t inlen
,
717 const char *cksum
, size_t cksumlen
)
728 if (cksumlen
!= 8 + 16)
729 return SHISHI_VERIFY_FAILED
;
732 * get_mic des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
733 * conf | rsa-md5(conf | msg))
734 * verify_mic decrypt and verify rsa-md5 checksum
737 keyp
= shishi_key_value (key
);
739 for (i
= 0; i
< 8; i
++)
742 res
= simplified_decrypt (handle
, key
, 0, NULL
, 0, NULL
, NULL
,
743 cksum
, cksumlen
, &out
, &outlen
);
745 for (i
= 0; i
< 8; i
++)
748 if (res
!= SHISHI_OK
)
750 shishi_error_set (handle
, "decrypt failed");
755 tmp
= xmalloc (tmplen
);
756 memcpy (tmp
, out
, 8);
757 memcpy (tmp
+ 8, in
, inlen
);
761 case SHISHI_RSA_MD4_DES
:
762 res
= shishi_md4 (handle
, tmp
, tmplen
, &md
);
765 case SHISHI_RSA_MD5_DES
:
766 res
= shishi_md5 (handle
, tmp
, tmplen
, &md
);
770 res
= SHISHI_CRYPTO_ERROR
;
773 if (res
!= SHISHI_OK
)
775 shishi_error_printf (handle
, "DES verify MD error");
779 if (memcmp (out
+ 8, md
, 16) != 0)
780 return SHISHI_VERIFY_FAILED
;
786 des_md4_verify (Shishi
* handle
,
790 const char *in
, size_t inlen
,
791 const char *cksum
, size_t cksumlen
)
793 return des_verify (handle
, SHISHI_RSA_MD4_DES
, key
,
794 in
, inlen
, cksum
, cksumlen
);
798 des_md5_verify (Shishi
* handle
,
802 const char *in
, size_t inlen
,
803 const char *cksum
, size_t cksumlen
)
805 return des_verify (handle
, SHISHI_RSA_MD5_DES
, key
,
806 in
, inlen
, cksum
, cksumlen
);