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 des_crc_verify (Shishi
* handle
, char *out
, int *outlen
)
32 memcpy (md
, out
+ 8, 4);
33 memset (out
+ 8, 0, 4);
35 gcry_md_open (&hd
, GCRY_MD_CRC32_RFC1510
, 0);
39 puts ("CRC not available");
43 gcry_md_write (hd
, out
, *outlen
);
44 p
= gcry_md_read (hd
, GCRY_MD_CRC32_RFC1510
);
45 if (VERBOSECRYPTO (handle
))
49 for (i
= 0; i
< 4; i
++)
50 printf ("%02X ", md
[i
] & 0xFF);
52 for (i
= 0; i
< 4; i
++)
53 printf ("%02X ", p
[i
] & 0xFF);
57 if (memcmp (p
, md
, 4) == 0)
59 memmove (out
, out
+ 8 + 4, *outlen
- 8 - 4);
66 printf ("des-cbc-crc verify fail\n");
76 des_crc_checksum (Shishi
* handle
,
77 char *out
, size_t * outlen
, const char *in
, size_t inlen
)
84 if (inlen
+ 8 + 4 > BUFSIZ
)
86 shishi_error_printf (handle
, "checksum inbuffer too large");
90 memcpy (buffer
+ 8 + 4, in
, inlen
);
91 memset (buffer
+ 8, 0, 4);
93 res
= shishi_randomize (handle
, buffer
, 8);
97 gcry_md_open (&hd
, GCRY_MD_CRC32_RFC1510
, 0);
99 return SHISHI_GCRYPT_ERROR
;
101 gcry_md_write (hd
, buffer
, inlen
+ 8 + 4);
102 p
= gcry_md_read (hd
, GCRY_MD_CRC32_RFC1510
);
104 memcpy (buffer
+ 8, p
, 4);
107 memcpy (out
, buffer
, 8 + 4);
115 des_md4_verify (Shishi
* handle
, char *out
, int *outlen
)
122 memcpy (md
, out
+ 8, 16);
123 memset (out
+ 8, 0, 16);
125 gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
129 puts ("MD4 not available");
133 gcry_md_write (hd
, out
, *outlen
);
134 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
135 if (VERBOSECRYPTO (handle
))
139 for (i
= 0; i
< 16; i
++)
140 printf ("%02X ", md
[i
] & 0xFF);
142 for (i
= 0; i
< 16; i
++)
143 printf ("%02X ", p
[i
] & 0xFF);
147 if (memcmp (p
, md
, 16) == 0)
149 memmove (out
, out
+ 8 + 16, *outlen
- 8 - 16);
155 if (VERBOSE (handle
))
156 printf ("des-cbc-md4 verify fail\n");
166 des_md4_checksum (Shishi
* handle
,
167 char *out
, size_t * outlen
, const char *in
, size_t inlen
)
174 if (inlen
+ 8 + 16 > BUFSIZ
)
176 shishi_error_printf (handle
, "checksum inbuffer too large");
180 memcpy (buffer
+ 8 + 16, in
, inlen
);
181 memset (buffer
+ 8, 0, 16);
183 res
= shishi_randomize (handle
, buffer
, 8);
184 if (res
!= SHISHI_OK
)
187 gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
189 return SHISHI_GCRYPT_ERROR
;
191 gcry_md_write (hd
, buffer
, inlen
+ 8 + 16);
192 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
194 memcpy (buffer
+ 8, p
, 16);
197 memcpy (out
, buffer
, 8 + 16);
205 des_md5_verify (Shishi
* handle
, char *out
, int *outlen
)
212 memcpy (md
, out
+ 8, 16);
213 memset (out
+ 8, 0, 16);
215 gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
219 shishi_error_set (handle
, "MD5 not available");
223 gcry_md_write (hd
, out
, *outlen
);
224 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
225 if (VERBOSECRYPTO (handle
))
229 for (i
= 0; i
< 16; i
++)
230 printf ("%02X ", md
[i
] & 0xFF);
232 for (i
= 0; i
< 16; i
++)
233 printf ("%02X ", p
[i
] & 0xFF);
237 if (memcmp (p
, md
, 16) == 0)
239 memmove (out
, out
+ 8 + 16, *outlen
- 8 - 16);
245 if (VERBOSE (handle
))
246 printf ("des-cbc-md5 verify fail\n");
256 des_md5_checksum (Shishi
* handle
,
257 char *out
, size_t * outlen
, const char *in
, size_t inlen
)
264 if (inlen
+ 8 + 16 > BUFSIZ
)
266 shishi_error_printf (handle
, "checksum inbuffer too large");
270 memcpy (buffer
+ 8 + 16, in
, inlen
);
271 memset (buffer
+ 8, 0, 16);
273 res
= shishi_randomize (handle
, buffer
, 8);
274 if (res
!= SHISHI_OK
)
277 gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
279 return SHISHI_GCRYPT_ERROR
;
281 gcry_md_write (hd
, buffer
, inlen
+ 8 + 16);
282 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
284 memcpy (buffer
+ 8, p
, 16);
287 memcpy (out
, buffer
, 8 + 16);
295 des_crc_encrypt (Shishi
* handle
,
298 const char *iv
, size_t ivlen
,
299 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
302 char buffer2
[BUFSIZ
];
307 memcpy (buffer2
, in
, inlen
);
310 while ((buf2len
% 8) != 0)
312 buffer2
[buf2len
] = '\0'; /* XXX */
316 buflen
= sizeof (buffer
);
317 res
= des_crc_checksum (handle
, buffer
, &buflen
, buffer2
, buf2len
);
318 memcpy (buffer
+ buflen
, buffer2
, buf2len
);
320 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
321 buffer
, buflen
, out
, outlen
);
327 des_crc_decrypt (Shishi
* handle
,
330 const char *iv
, size_t ivlen
,
331 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
335 printf ("in %d\n", inlen
);
336 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
337 in
, inlen
, out
, outlen
);
338 if (res
!= SHISHI_OK
)
340 shishi_error_set (handle
, "decrypt failed");
345 "\x56\xcc\xa9\xd6\x67\x0a\xca\x0e\xbc\x58\xdc\x9b\x79\x81\xd3\x30\x81\xd0\xa0\x13\x30\x11\xa0\x03\x02\x01\x01\xa1\x0a\x04\x08\x8f\x75\x58\x45\x9d\x31\x6b\x1f\xa1\x1c\x30\x1a\x30\x18\xa0\x03\x02\x01\x00\xa1\x11\x18\x0f\x31\x39\x37\x30\x30\x31\x30\x31\x30\x30\x30\x30\x30\x30\x5a\xa2\x06\x02\x04\x3d\xdd\x3a\x46\xa4\x07\x03\x05\x00\x50\x40\x00\x00\xa5\x11\x18\x0f\x32\x30\x30\x32\x31\x31\x32\x31\x31\x39\x35\x35\x35\x30\x5a\xa7\x11\x18\x0f\x32\x30\x30\x32\x31\x31\x32\x32\x30\x35\x35\x35\x35\x30\x5a\xa9\x0f\x1b\x0d\x4a\x4f\x53\x45\x46\x53\x53\x4f\x4e\x2e\x4f\x52\x47\xaa\x22\x30\x20\xa0\x03\x02\x01\x00\xa1\x19\x30\x17\x1b\x06\x6b\x72\x62\x74\x67\x74\x1b\x0d\x4a\x4f\x53\x45\x46\x53\x53\x4f\x4e\x2e\x4f\x52\x47\xab\x2f\x30\x2d\x30\x0d\xa0\x03\x02\x01\x02\xa1\x06\x04\x04\xc0\xa8\x01\x01\x30\x0d\xa0\x03\x02\x01\x02\xa1\x06\x04\x04\xc0\xa8\x02\x01\x30\x0d\xa0\x03\x02\x01\x02\xa1\x06\x04\x04\xd9\xd0\xac\x49\x00\x00\x00\x00\x00\x00",
351 printf ("decrypt %d\n", *outlen
);
352 for (i
= 0; i
< *outlen
; i
++)
353 printf ("%02x ", ((char *) out
)[i
] & 0xFF);
356 res
= des_crc_verify (handle
, *out
, outlen
);
357 if (res
!= SHISHI_OK
)
359 shishi_error_set (handle
, "verify failed");
367 des_md4_encrypt (Shishi
* handle
,
370 const char *iv
, size_t ivlen
,
371 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
374 char buffer2
[BUFSIZ
];
379 memcpy (buffer2
, in
, inlen
);
381 while ((buf2len
% 8) != 0)
383 buffer2
[buf2len
] = '\0'; /* XXX */
387 buflen
= sizeof (buffer
);
388 res
= des_md4_checksum (handle
, buffer
, &buflen
, buffer2
, buf2len
);
389 memcpy (buffer
+ buflen
, buffer
, buf2len
);
391 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
392 buffer
, buflen
, out
, outlen
);
398 des_md4_decrypt (Shishi
* handle
,
403 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
407 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
408 in
, inlen
, out
, outlen
);
409 if (res
!= SHISHI_OK
)
411 shishi_error_set (handle
, "decrypt failed");
414 res
= des_md4_verify (handle
, *out
, outlen
);
415 if (res
!= SHISHI_OK
)
417 shishi_error_set (handle
, "verify failed");
425 des_md5_encrypt (Shishi
* handle
,
430 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
433 char buffer2
[BUFSIZ
];
438 memcpy (buffer2
, in
, inlen
);
441 while ((buf2len
% 8) != 0)
443 buffer2
[buf2len
] = '\0'; /* XXX */
447 buflen
= sizeof (buffer
);
448 res
= des_md5_checksum (handle
, buffer
, &buflen
, buffer2
, buf2len
);
449 memcpy (buffer
+ buflen
, buffer2
, buf2len
);
451 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
452 buffer
, buflen
, out
, outlen
);
458 des_md5_decrypt (Shishi
* handle
,
463 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
467 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
468 in
, inlen
, out
, outlen
);
469 if (res
!= SHISHI_OK
)
471 shishi_error_set (handle
, "decrypt failed");
474 res
= des_md5_verify (handle
, *out
, outlen
);
475 if (res
!= SHISHI_OK
)
477 shishi_error_set (handle
, "verify failed");
485 des_none_encrypt (Shishi
* handle
,
490 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
494 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
495 in
, inlen
, out
, outlen
);
496 if (res
!= SHISHI_OK
)
503 des_none_decrypt (Shishi
* handle
,
508 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
512 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
513 in
, inlen
, out
, outlen
);
514 if (res
!= SHISHI_OK
)
521 des_set_odd_key_parity (char key
[8])
525 for (i
= 0; i
< 8; i
++)
529 for (j
= 1; j
< 8; j
++)
530 if (key
[i
] & (1 << j
))
534 if ((n_set_bits
% 2) == 0)
542 des_key_correction (Shishi
* handle
, char *key
)
547 /* fixparity(key); */
548 des_set_odd_key_parity (key
);
550 gcry_cipher_open (&ch
, GCRY_CIPHER_DES
, GCRY_CIPHER_MODE_CBC
, 0);
554 /* XXX libgcrypt tests for pseudo-weak keys, rfc 1510 doesn't */
556 res
= gcry_cipher_setkey (ch
, key
, 8);
557 if (res
!= GPG_ERR_NO_ERROR
)
559 if (gpg_err_code (res
) == GPG_ERR_WEAK_KEY
)
561 if (VERBOSECRYPTO (handle
))
562 printf ("\t ;; WEAK KEY (corrected)\n");
569 gcry_cipher_close (ch
);
575 des_cbc_check (char key
[8], char *data
, int n_data
)
580 gcry_cipher_open (&ch
, GCRY_CIPHER_DES
,
581 GCRY_CIPHER_MODE_CBC
, GCRY_CIPHER_CBC_MAC
);
583 return SHISHI_GCRYPT_ERROR
;
585 res
= gcry_cipher_setkey (ch
, key
, 8);
586 if (res
!= GPG_ERR_NO_ERROR
)
587 return SHISHI_GCRYPT_ERROR
;
589 res
= gcry_cipher_setiv (ch
, key
, 8);
591 return SHISHI_GCRYPT_ERROR
;
593 res
= gcry_cipher_encrypt (ch
, key
, 8, data
, n_data
);
595 return SHISHI_GCRYPT_ERROR
;
597 gcry_cipher_close (ch
);
603 des_random_to_key (Shishi
* handle
,
604 const char *random
, size_t randomlen
, Shishi_key
* outkey
)
606 char tmp
[MAX_RANDOM_LEN
];
607 int keylen
= shishi_cipher_keylen (shishi_key_type (outkey
));
609 if (randomlen
!= shishi_key_length (outkey
))
612 memcpy (tmp
, random
, keylen
);
613 des_set_odd_key_parity (tmp
);
615 shishi_key_value_set (outkey
, tmp
);
621 des_string_to_key (Shishi
* handle
,
625 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
635 if (VERBOSECRYPTO (handle
))
637 printf ("des_string_to_key (string, salt)\n");
639 printf ("\t ;; String:\n");
640 escapeprint (string
, stringlen
);
641 hexprint (string
, stringlen
);
645 printf ("\t ;; Salt:\n");
646 escapeprint (salt
, saltlen
);
647 hexprint (salt
, saltlen
);
650 printf ("odd = 1;\n");
651 printf ("s = string | salt;\n");
652 printf ("tempstring = 0; /* 56-bit string */\n");
653 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
661 n_s
= stringlen
+ saltlen
;
664 s
= (char *) malloc (n_s
);
665 memcpy (s
, string
, stringlen
);
667 memcpy (s
+ stringlen
, salt
, saltlen
);
668 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
669 memset (tempkey
, 0, sizeof (tempkey
)); /* tempkey = NULL; */
671 if (VERBOSECRYPTO (handle
))
673 printf ("\t ;; s = pad(string|salt):\n");
674 escapeprint (s
, n_s
);
679 for (i
= 0; i
< n_s
/ 8; i
++)
681 if (VERBOSECRYPTO (handle
))
683 printf ("for (8byteblock in s) {\n");
684 printf ("\t ;; loop iteration %d\n", i
);
685 printf ("\t ;; 8byteblock:\n");
686 escapeprint (&s
[i
* 8], 8);
687 hexprint (&s
[i
* 8], 8);
689 binprint (&s
[i
* 8], 8);
691 printf ("56bitstring = removeMSBits(8byteblock);\n");
694 for (j
= 0; j
< 8; j
++)
695 s
[i
* 8 + j
] = s
[i
* 8 + j
] & ~0x80;
697 if (VERBOSECRYPTO (handle
))
699 printf ("\t ;; 56bitstring:\n");
700 bin7print (&s
[i
* 8], 8);
702 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
707 for (j
= 0; j
< 4; j
++)
711 ((temp
>> 6) & 0x01) |
712 ((temp
>> 4) & 0x02) |
713 ((temp
>> 2) & 0x04) |
715 ((temp
<< 2) & 0x10) |
716 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
717 temp2
= s
[i
* 8 + 7 - j
];
719 ((temp2
>> 6) & 0x01) |
720 ((temp2
>> 4) & 0x02) |
721 ((temp2
>> 2) & 0x04) |
723 ((temp2
<< 2) & 0x10) |
724 ((temp2
<< 4) & 0x20) | ((temp2
<< 6) & 0x40);
725 s
[i
* 8 + j
] = temp2
;
726 s
[i
* 8 + 7 - j
] = temp
;
728 if (VERBOSECRYPTO (handle
))
730 printf ("reverse(56bitstring)\n");
731 printf ("\t ;; 56bitstring after reverse\n");
732 bin7print (&s
[i
* 8], 8);
739 if (VERBOSECRYPTO (handle
))
741 printf ("odd = ! odd\n");
742 printf ("tempstring = tempstring XOR 56bitstring;\n");
745 /* tempkey = tempkey XOR 8byteblock; */
746 for (j
= 0; j
< 8; j
++)
747 tempkey
[j
] ^= s
[i
* 8 + j
];
749 if (VERBOSECRYPTO (handle
))
751 printf ("\t ;; tempstring\n");
752 bin7print (tempkey
, 8);
758 for (j
= 0; j
< 8; j
++)
759 tempkey
[j
] = tempkey
[j
] << 1;
761 if (VERBOSECRYPTO (handle
))
763 printf ("for (8byteblock in s) {\n");
765 printf ("\t ;; for loop terminated\n");
766 printf ("\t ;; tempstring as 64bitblock\n");
767 hexprint (tempkey
, 8);
769 binprint (tempkey
, 8);
771 printf ("/* add parity as low bit of each byte */\n");
772 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
775 res
= des_key_correction (handle
, tempkey
);
776 if (res
!= SHISHI_OK
)
779 if (VERBOSECRYPTO (handle
))
781 printf ("\t ;; tempkey\n");
782 escapeprint (tempkey
, 8);
783 hexprint (tempkey
, 8);
785 binprint (tempkey
, 8);
788 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
791 memcpy (s
, string
, stringlen
);
793 memcpy (s
+ stringlen
, salt
, saltlen
);
794 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
796 res
= des_cbc_check (tempkey
, s
, n_s
);
797 if (res
!= SHISHI_OK
)
800 res
= des_key_correction (handle
, tempkey
);
801 if (res
!= SHISHI_OK
)
804 if (VERBOSECRYPTO (handle
))
806 printf ("\t ;; key\n");
807 escapeprint (tempkey
, 8);
808 hexprint (tempkey
, 8);
810 binprint (tempkey
, 8);
815 shishi_key_value_set (outkey
, tempkey
);
821 checksum_md4 (Shishi
* handle
, char *out
, int *outlen
, char *in
, int inlen
)
828 if (inlen
+ 8 > BUFSIZ
)
830 shishi_error_printf (handle
, "checksum inbuffer too large");
834 memcpy (buffer
+ 8, in
, inlen
);
837 printf ("cksum in len=%d:", inlen
);
838 for (i
= 0; i
< inlen
; i
++)
839 printf ("%02x ", in
[i
] & 0xFF);
843 res
= shishi_randomize (handle
, buffer
, 8);
844 if (res
!= SHISHI_OK
)
848 printf ("cksum random: ");
849 for (i
= 0; i
< 8; i
++)
850 printf ("%02X ", buffer
[i
] & 0xFF);
854 gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
856 return SHISHI_GCRYPT_ERROR
;
858 gcry_md_write (hd
, buffer
, inlen
+ 8);
859 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
862 printf ("cksum md4: ");
863 for (i
= 0; i
< 16; i
++)
864 printf ("%02X ", p
[i
] & 0xFF);
868 memcpy (buffer
+ 8, p
, 16);
871 memcpy (out
, buffer
, 8 + 16);
876 printf ("cksum out: ");
877 for (i
= 0; i
< *outlen
; i
++)
878 printf ("%02X ", out
[i
] & 0xFF);
886 checksum_md5 (Shishi
* handle
, char *out
, int *outlen
, char *in
, int inlen
)
893 if (inlen
+ 8 > BUFSIZ
)
895 shishi_error_printf (handle
, "checksum inbuffer too large");
899 memcpy (buffer
+ 8, in
, inlen
);
902 printf ("cksum in len=%d:", inlen
);
903 for (i
= 0; i
< inlen
; i
++)
904 printf ("%02x ", in
[i
] & 0xFF);
908 res
= shishi_randomize (handle
, buffer
, 8);
909 if (res
!= SHISHI_OK
)
913 printf ("cksum random: ");
914 for (i
= 0; i
< 8; i
++)
915 printf ("%02X ", buffer
[i
] & 0xFF);
919 gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
921 return SHISHI_GCRYPT_ERROR
;
923 gcry_md_write (hd
, buffer
, inlen
+ 8);
924 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
927 printf ("cksum md5: ");
928 for (i
= 0; i
< 16; i
++)
929 printf ("%02X ", p
[i
] & 0xFF);
933 memcpy (buffer
+ 8, p
, 16);
936 memcpy (out
, buffer
, 8 + 16);
941 printf ("cksum out: ");
942 for (i
= 0; i
< *outlen
; i
++)
943 printf ("%02X ", out
[i
] & 0xFF);