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
,
78 const char *in
, size_t inlen
)
85 if (inlen
+ 8 + 4 > BUFSIZ
)
87 shishi_error_printf (handle
, "checksum inbuffer too large");
91 memcpy (buffer
+ 8 + 4, in
, inlen
);
92 memset (buffer
+ 8, 0, 4);
94 res
= shishi_randomize (handle
, buffer
, 8);
98 gcry_md_open (&hd
, GCRY_MD_CRC32_RFC1510
, 0);
100 return SHISHI_GCRYPT_ERROR
;
102 gcry_md_write (hd
, buffer
, inlen
+ 8 + 4);
103 p
= gcry_md_read (hd
, GCRY_MD_CRC32_RFC1510
);
105 memcpy (buffer
+ 8, p
, 4);
108 memcpy (out
, buffer
, 8 + 4);
116 des_md4_verify (Shishi
* handle
, char *out
, int *outlen
)
123 memcpy (md
, out
+ 8, 16);
124 memset (out
+ 8, 0, 16);
126 gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
130 puts("MD4 not available");
134 gcry_md_write (hd
, out
, *outlen
);
135 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
136 if (VERBOSECRYPTO(handle
))
140 for (i
= 0; i
< 16; i
++)
141 printf ("%02X ", md
[i
] & 0xFF);
143 for (i
= 0; i
< 16; i
++)
144 printf ("%02X ", p
[i
] & 0xFF);
148 if (memcmp (p
, md
, 16) == 0)
150 memmove (out
, out
+ 8 + 16, *outlen
- 8 - 16);
157 printf ("des-cbc-md4 verify fail\n");
167 des_md4_checksum (Shishi
* handle
,
168 char *out
, size_t *outlen
,
169 const char *in
, size_t inlen
)
176 if (inlen
+ 8 + 16 > BUFSIZ
)
178 shishi_error_printf (handle
, "checksum inbuffer too large");
182 memcpy (buffer
+ 8 + 16, in
, inlen
);
183 memset (buffer
+ 8, 0, 16);
185 res
= shishi_randomize (handle
, buffer
, 8);
186 if (res
!= SHISHI_OK
)
189 gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
191 return SHISHI_GCRYPT_ERROR
;
193 gcry_md_write (hd
, buffer
, inlen
+ 8 + 16);
194 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
196 memcpy (buffer
+ 8, p
, 16);
199 memcpy (out
, buffer
, 8 + 16);
207 des_md5_verify (Shishi
* handle
, char *out
, int *outlen
)
214 memcpy (md
, out
+ 8, 16);
215 memset (out
+ 8, 0, 16);
217 gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
221 shishi_error_set (handle
, "MD5 not available");
225 gcry_md_write (hd
, out
, *outlen
);
226 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
227 if (VERBOSECRYPTO(handle
))
231 for (i
= 0; i
< 16; i
++)
232 printf ("%02X ", md
[i
] & 0xFF);
234 for (i
= 0; i
< 16; i
++)
235 printf ("%02X ", p
[i
] & 0xFF);
239 if (memcmp (p
, md
, 16) == 0)
241 memmove (out
, out
+ 8 + 16, *outlen
- 8 - 16);
248 printf ("des-cbc-md5 verify fail\n");
258 des_md5_checksum (Shishi
* handle
,
259 char *out
, size_t *outlen
,
260 const char *in
, size_t inlen
)
267 if (inlen
+ 8 + 16 > BUFSIZ
)
269 shishi_error_printf (handle
, "checksum inbuffer too large");
273 memcpy (buffer
+ 8 + 16, in
, inlen
);
274 memset (buffer
+ 8, 0, 16);
276 res
= shishi_randomize (handle
, buffer
, 8);
277 if (res
!= SHISHI_OK
)
280 gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
282 return SHISHI_GCRYPT_ERROR
;
284 gcry_md_write (hd
, buffer
, inlen
+ 8 + 16);
285 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
287 memcpy (buffer
+ 8, p
, 16);
290 memcpy (out
, buffer
, 8 + 16);
298 des_crc_encrypt (Shishi
* handle
,
309 char buffer2
[BUFSIZ
];
314 memcpy(buffer2
, in
, inlen
);
317 while ((buf2len
% 8) != 0)
319 buffer2
[buf2len
] = '\0'; /* XXX */
323 buflen
= sizeof (buffer
);
324 res
= des_crc_checksum (handle
, buffer
, &buflen
, buffer2
, buf2len
);
325 memcpy (buffer
+ buflen
, buffer2
, buf2len
);
327 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
328 buffer
, buflen
, out
, outlen
);
334 des_crc_decrypt (Shishi
* handle
,
346 printf("in %d\n", inlen
);
347 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
348 in
, inlen
, out
, outlen
);
349 if (res
!= SHISHI_OK
)
351 shishi_error_set (handle
, "decrypt failed");
355 memcpy(out
, "\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", 232);
360 printf("decrypt %d\n", *outlen
);
361 for(i
=0; i
< *outlen
; i
++)
362 printf("%02x ", ((char*)out
)[i
] & 0xFF);
365 res
= des_crc_verify (handle
, out
, outlen
);
366 if (res
!= SHISHI_OK
)
368 shishi_error_set (handle
, "verify failed");
376 des_md4_encrypt (Shishi
* handle
,
387 char buffer2
[BUFSIZ
];
392 memcpy(buffer2
, in
, inlen
);
394 while ((buf2len
% 8) != 0)
396 buffer2
[buf2len
] = '\0'; /* XXX */
400 buflen
= sizeof (buffer
);
401 res
= des_md4_checksum (handle
, buffer
, &buflen
, buffer2
, buf2len
);
402 memcpy (buffer
+ buflen
, buffer
, buf2len
);
404 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
405 buffer
, buflen
, out
, outlen
);
411 des_md4_decrypt (Shishi
* handle
,
423 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
424 in
, inlen
, out
, outlen
);
425 if (res
!= SHISHI_OK
)
427 shishi_error_set (handle
, "decrypt failed");
430 res
= des_md4_verify (handle
, out
, outlen
);
431 if (res
!= SHISHI_OK
)
433 shishi_error_set (handle
, "verify failed");
441 des_md5_encrypt (Shishi
* handle
,
452 char buffer2
[BUFSIZ
];
457 memcpy(buffer2
, in
, inlen
);
460 while ((buf2len
% 8) != 0)
462 buffer2
[buf2len
] = '\0'; /* XXX */
466 buflen
= sizeof (buffer
);
467 res
= des_md5_checksum (handle
, buffer
, &buflen
, buffer2
, buf2len
);
468 memcpy (buffer
+ buflen
, buffer2
, buf2len
);
470 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
471 buffer
, buflen
, out
, outlen
);
477 des_md5_decrypt (Shishi
* handle
,
489 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
490 in
, inlen
, out
, outlen
);
491 if (res
!= SHISHI_OK
)
493 shishi_error_set (handle
, "decrypt failed");
496 res
= des_md5_verify (handle
, out
, outlen
);
497 if (res
!= SHISHI_OK
)
499 shishi_error_set (handle
, "verify failed");
507 des_none_encrypt (Shishi
* handle
,
519 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
520 in
, inlen
, out
, outlen
);
521 if (res
!= SHISHI_OK
)
528 des_none_decrypt (Shishi
* handle
,
540 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
541 in
, inlen
, out
, outlen
);
542 if (res
!= SHISHI_OK
)
549 des_set_odd_key_parity (char key
[8])
553 for (i
= 0; i
< 8; i
++)
557 for (j
= 1; j
< 8; j
++)
558 if (key
[i
] & (1 << j
))
562 if ((n_set_bits
% 2) == 0)
570 des_key_correction (Shishi
* handle
, char *key
)
575 /* fixparity(key); */
576 des_set_odd_key_parity (key
);
578 gcry_cipher_open (&ch
, GCRY_CIPHER_DES
, GCRY_CIPHER_MODE_CBC
, 0);
582 /* XXX libgcrypt tests for pseudo-weak keys, rfc 1510 doesn't */
584 res
= gcry_cipher_setkey (ch
, key
, 8);
585 if (res
!= GPG_ERR_NO_ERROR
)
587 printf("hepp %d\n", gpg_err_code(res
));
588 if (gpg_err_code(res
) == GPG_ERR_WEAK_KEY
)
590 if (VERBOSECRYPTO(handle
))
591 printf ("\t ;; WEAK KEY (corrected)\n");
598 gcry_cipher_close (ch
);
604 des_cbc_check (char key
[8], char *data
, int n_data
)
609 gcry_cipher_open (&ch
, GCRY_CIPHER_DES
,
610 GCRY_CIPHER_MODE_CBC
,
611 GCRY_CIPHER_CBC_MAC
);
613 return SHISHI_GCRYPT_ERROR
;
615 res
= gcry_cipher_setkey (ch
, key
, 8);
616 if (res
!= GPG_ERR_NO_ERROR
)
617 return SHISHI_GCRYPT_ERROR
;
619 res
= gcry_cipher_setiv (ch
, key
, 8);
621 return SHISHI_GCRYPT_ERROR
;
623 res
= gcry_cipher_encrypt (ch
, key
, 8, data
, n_data
);
625 return SHISHI_GCRYPT_ERROR
;
627 gcry_cipher_close (ch
);
633 des_random_to_key (Shishi
* handle
,
638 char tmp
[MAX_RANDOM_LEN
];
639 int keylen
= shishi_cipher_keylen (shishi_key_type(outkey
));
641 if (randomlen
!= shishi_key_length(outkey
))
644 memcpy(tmp
, random
, keylen
);
645 des_set_odd_key_parity (tmp
);
647 shishi_key_value_set(outkey
, tmp
);
653 des_string_to_key (Shishi
* handle
,
658 const char *parameter
,
669 if (VERBOSECRYPTO(handle
))
671 printf ("des_string_to_key (string, salt)\n");
673 printf ("\t ;; String:\n");
674 escapeprint (string
, stringlen
);
675 hexprint (string
, stringlen
);
679 printf ("\t ;; Salt:\n");
680 escapeprint (salt
, saltlen
);
681 hexprint (salt
, saltlen
);
684 printf ("odd = 1;\n");
685 printf ("s = string | salt;\n");
686 printf ("tempstring = 0; /* 56-bit string */\n");
687 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
695 n_s
= stringlen
+ saltlen
;
698 s
= (char *) malloc (n_s
);
699 memcpy (s
, string
, stringlen
);
701 memcpy (s
+ stringlen
, salt
, saltlen
);
702 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
703 memset (tempkey
, 0, sizeof (tempkey
)); /* tempkey = NULL; */
705 if (VERBOSECRYPTO(handle
))
707 printf ("\t ;; s = pad(string|salt):\n");
708 escapeprint (s
, n_s
);
713 for (i
= 0; i
< n_s
/ 8; i
++)
715 if (VERBOSECRYPTO(handle
))
717 printf ("for (8byteblock in s) {\n");
718 printf ("\t ;; loop iteration %d\n", i
);
719 printf ("\t ;; 8byteblock:\n");
720 escapeprint (&s
[i
* 8], 8);
721 hexprint (&s
[i
* 8], 8);
723 binprint (&s
[i
* 8], 8);
725 printf ("56bitstring = removeMSBits(8byteblock);\n");
728 for (j
= 0; j
< 8; j
++)
729 s
[i
* 8 + j
] = s
[i
* 8 + j
] & ~0x80;
731 if (VERBOSECRYPTO(handle
))
733 printf ("\t ;; 56bitstring:\n");
734 bin7print (&s
[i
* 8], 8);
736 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
741 for (j
= 0; j
< 4; j
++)
745 ((temp
>> 6) & 0x01) |
746 ((temp
>> 4) & 0x02) |
747 ((temp
>> 2) & 0x04) |
749 ((temp
<< 2) & 0x10) |
750 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
751 temp2
= s
[i
* 8 + 7 - j
];
753 ((temp2
>> 6) & 0x01) |
754 ((temp2
>> 4) & 0x02) |
755 ((temp2
>> 2) & 0x04) |
757 ((temp2
<< 2) & 0x10) |
758 ((temp2
<< 4) & 0x20) | ((temp2
<< 6) & 0x40);
759 s
[i
* 8 + j
] = temp2
;
760 s
[i
* 8 + 7 - j
] = temp
;
762 if (VERBOSECRYPTO(handle
))
764 printf ("reverse(56bitstring)\n");
765 printf ("\t ;; 56bitstring after reverse\n");
766 bin7print (&s
[i
* 8], 8);
773 if (VERBOSECRYPTO(handle
))
775 printf ("odd = ! odd\n");
776 printf ("tempstring = tempstring XOR 56bitstring;\n");
779 /* tempkey = tempkey XOR 8byteblock; */
780 for (j
= 0; j
< 8; j
++)
781 tempkey
[j
] ^= s
[i
* 8 + j
];
783 if (VERBOSECRYPTO(handle
))
785 printf ("\t ;; tempstring\n");
786 bin7print (tempkey
, 8);
792 for (j
= 0; j
< 8; j
++)
793 tempkey
[j
] = tempkey
[j
] << 1;
795 if (VERBOSECRYPTO(handle
))
797 printf ("for (8byteblock in s) {\n");
799 printf ("\t ;; for loop terminated\n");
800 printf ("\t ;; tempstring as 64bitblock\n");
801 hexprint (tempkey
, 8);
803 binprint (tempkey
, 8);
805 printf ("/* add parity as low bit of each byte */\n");
806 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
809 res
= des_key_correction (handle
, tempkey
);
810 if (res
!= SHISHI_OK
)
813 if (VERBOSECRYPTO(handle
))
815 printf ("\t ;; tempkey\n");
816 escapeprint (tempkey
, 8);
817 hexprint (tempkey
, 8);
819 binprint (tempkey
, 8);
822 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
825 memcpy (s
, string
, stringlen
);
827 memcpy (s
+ stringlen
, salt
, saltlen
);
828 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
830 res
= des_cbc_check (tempkey
, s
, n_s
);
831 if (res
!= SHISHI_OK
)
834 res
= des_key_correction (handle
, tempkey
);
835 if (res
!= SHISHI_OK
)
838 if (VERBOSECRYPTO(handle
))
840 printf ("\t ;; key\n");
841 escapeprint (tempkey
, 8);
842 hexprint (tempkey
, 8);
844 binprint (tempkey
, 8);
849 shishi_key_value_set (outkey
, tempkey
);
855 checksum_md4 (Shishi
* handle
,
856 char *out
, int *outlen
, char *in
, int inlen
)
863 if (inlen
+ 8 > BUFSIZ
)
865 shishi_error_printf (handle
, "checksum inbuffer too large");
869 memcpy (buffer
+ 8, in
, inlen
);
872 printf ("cksum in len=%d:", inlen
);
873 for (i
= 0; i
< inlen
; i
++)
874 printf ("%02x ", in
[i
] & 0xFF);
878 res
= shishi_randomize (handle
, buffer
, 8);
879 if (res
!= SHISHI_OK
)
883 printf ("cksum random: ");
884 for (i
= 0; i
< 8; i
++)
885 printf ("%02X ", buffer
[i
] & 0xFF);
889 gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
891 return SHISHI_GCRYPT_ERROR
;
893 gcry_md_write (hd
, buffer
, inlen
+ 8);
894 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
897 printf ("cksum md4: ");
898 for (i
= 0; i
< 16; i
++)
899 printf ("%02X ", p
[i
] & 0xFF);
903 memcpy (buffer
+ 8, p
, 16);
906 memcpy (out
, buffer
, 8 + 16);
911 printf ("cksum out: ");
912 for (i
= 0; i
< *outlen
; i
++)
913 printf ("%02X ", out
[i
] & 0xFF);
921 checksum_md5 (Shishi
* handle
,
922 char *out
, int *outlen
, char *in
, int inlen
)
929 if (inlen
+ 8 > BUFSIZ
)
931 shishi_error_printf (handle
, "checksum inbuffer too large");
935 memcpy (buffer
+ 8, in
, inlen
);
938 printf ("cksum in len=%d:", inlen
);
939 for (i
= 0; i
< inlen
; i
++)
940 printf ("%02x ", in
[i
] & 0xFF);
944 res
= shishi_randomize (handle
, buffer
, 8);
945 if (res
!= SHISHI_OK
)
949 printf ("cksum random: ");
950 for (i
= 0; i
< 8; i
++)
951 printf ("%02X ", buffer
[i
] & 0xFF);
955 gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
957 return SHISHI_GCRYPT_ERROR
;
959 gcry_md_write (hd
, buffer
, inlen
+ 8);
960 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
963 printf ("cksum md5: ");
964 for (i
= 0; i
< 16; i
++)
965 printf ("%02X ", p
[i
] & 0xFF);
969 memcpy (buffer
+ 8, p
, 16);
972 memcpy (out
, buffer
, 8 + 16);
977 printf ("cksum out: ");
978 for (i
= 0; i
< *outlen
; i
++)
979 printf ("%02X ", out
[i
] & 0xFF);