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 hd
= gcry_md_open (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 hd
= gcry_md_open (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 hd
= gcry_md_open (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 hd
= gcry_md_open (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 hd
= gcry_md_open (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 hd
= gcry_md_open (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 ch
= gcry_cipher_open (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
!= GCRYERR_SUCCESS
)
587 if (res
== GCRYERR_WEAK_KEY
)
589 if (VERBOSECRYPTO(handle
))
590 printf ("\t ;; WEAK KEY (corrected)\n");
597 gcry_cipher_close (ch
);
603 des_cbc_check (char key
[8], char *data
, int n_data
)
608 ch
= gcry_cipher_open (GCRY_CIPHER_DES
,
609 GCRY_CIPHER_MODE_CBC
,
610 GCRY_CIPHER_CBC_MAC
);
612 return SHISHI_GCRYPT_ERROR
;
614 res
= gcry_cipher_setkey (ch
, key
, 8);
615 if (res
!= GCRYERR_SUCCESS
)
616 return SHISHI_GCRYPT_ERROR
;
618 res
= gcry_cipher_setiv (ch
, key
, 8);
620 return SHISHI_GCRYPT_ERROR
;
622 res
= gcry_cipher_encrypt (ch
, key
, 8, data
, n_data
);
624 return SHISHI_GCRYPT_ERROR
;
626 gcry_cipher_close (ch
);
632 des_random_to_key (Shishi
* handle
,
637 char tmp
[MAX_RANDOM_LEN
];
638 int keylen
= shishi_cipher_keylen (shishi_key_type(outkey
));
640 if (randomlen
!= shishi_key_length(outkey
))
643 memcpy(tmp
, random
, keylen
);
644 des_set_odd_key_parity (tmp
);
646 shishi_key_value_set(outkey
, tmp
);
652 des_string_to_key (Shishi
* handle
,
657 const char *parameter
,
668 if (VERBOSECRYPTO(handle
))
670 printf ("des_string_to_key (string, salt)\n");
672 printf ("\t ;; String:\n");
673 escapeprint (string
, stringlen
);
674 hexprint (string
, stringlen
);
678 printf ("\t ;; Salt:\n");
679 escapeprint (salt
, saltlen
);
680 hexprint (salt
, saltlen
);
683 printf ("odd = 1;\n");
684 printf ("s = string | salt;\n");
685 printf ("tempstring = 0; /* 56-bit string */\n");
686 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
694 n_s
= stringlen
+ saltlen
;
697 s
= (char *) malloc (n_s
);
698 memcpy (s
, string
, stringlen
);
700 memcpy (s
+ stringlen
, salt
, saltlen
);
701 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
702 memset (tempkey
, 0, sizeof (tempkey
)); /* tempkey = NULL; */
704 if (VERBOSECRYPTO(handle
))
706 printf ("\t ;; s = pad(string|salt):\n");
707 escapeprint (s
, n_s
);
712 for (i
= 0; i
< n_s
/ 8; i
++)
714 if (VERBOSECRYPTO(handle
))
716 printf ("for (8byteblock in s) {\n");
717 printf ("\t ;; loop iteration %d\n", i
);
718 printf ("\t ;; 8byteblock:\n");
719 escapeprint (&s
[i
* 8], 8);
720 hexprint (&s
[i
* 8], 8);
722 binprint (&s
[i
* 8], 8);
724 printf ("56bitstring = removeMSBits(8byteblock);\n");
727 for (j
= 0; j
< 8; j
++)
728 s
[i
* 8 + j
] = s
[i
* 8 + j
] & ~0x80;
730 if (VERBOSECRYPTO(handle
))
732 printf ("\t ;; 56bitstring:\n");
733 bin7print (&s
[i
* 8], 8);
735 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
740 for (j
= 0; j
< 4; j
++)
744 ((temp
>> 6) & 0x01) |
745 ((temp
>> 4) & 0x02) |
746 ((temp
>> 2) & 0x04) |
748 ((temp
<< 2) & 0x10) |
749 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
750 temp2
= s
[i
* 8 + 7 - j
];
752 ((temp2
>> 6) & 0x01) |
753 ((temp2
>> 4) & 0x02) |
754 ((temp2
>> 2) & 0x04) |
756 ((temp2
<< 2) & 0x10) |
757 ((temp2
<< 4) & 0x20) | ((temp2
<< 6) & 0x40);
758 s
[i
* 8 + j
] = temp2
;
759 s
[i
* 8 + 7 - j
] = temp
;
761 if (VERBOSECRYPTO(handle
))
763 printf ("reverse(56bitstring)\n");
764 printf ("\t ;; 56bitstring after reverse\n");
765 bin7print (&s
[i
* 8], 8);
772 if (VERBOSECRYPTO(handle
))
774 printf ("odd = ! odd\n");
775 printf ("tempstring = tempstring XOR 56bitstring;\n");
778 /* tempkey = tempkey XOR 8byteblock; */
779 for (j
= 0; j
< 8; j
++)
780 tempkey
[j
] ^= s
[i
* 8 + j
];
782 if (VERBOSECRYPTO(handle
))
784 printf ("\t ;; tempstring\n");
785 bin7print (tempkey
, 8);
791 for (j
= 0; j
< 8; j
++)
792 tempkey
[j
] = tempkey
[j
] << 1;
794 if (VERBOSECRYPTO(handle
))
796 printf ("for (8byteblock in s) {\n");
798 printf ("\t ;; for loop terminated\n");
799 printf ("\t ;; tempstring as 64bitblock\n");
800 hexprint (tempkey
, 8);
802 binprint (tempkey
, 8);
804 printf ("/* add parity as low bit of each byte */\n");
805 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
808 res
= des_key_correction (handle
, tempkey
);
809 if (res
!= SHISHI_OK
)
812 if (VERBOSECRYPTO(handle
))
814 printf ("\t ;; tempkey\n");
815 escapeprint (tempkey
, 8);
816 hexprint (tempkey
, 8);
818 binprint (tempkey
, 8);
821 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
824 memcpy (s
, string
, stringlen
);
826 memcpy (s
+ stringlen
, salt
, saltlen
);
827 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
829 res
= des_cbc_check (tempkey
, s
, n_s
);
830 if (res
!= SHISHI_OK
)
833 res
= des_key_correction (handle
, tempkey
);
834 if (res
!= SHISHI_OK
)
837 if (VERBOSECRYPTO(handle
))
839 printf ("\t ;; key\n");
840 escapeprint (tempkey
, 8);
841 hexprint (tempkey
, 8);
843 binprint (tempkey
, 8);
848 shishi_key_value_set (outkey
, tempkey
);
854 checksum_md4 (Shishi
* handle
,
855 char *out
, int *outlen
, char *in
, int inlen
)
862 if (inlen
+ 8 > BUFSIZ
)
864 shishi_error_printf (handle
, "checksum inbuffer too large");
868 memcpy (buffer
+ 8, in
, inlen
);
871 printf ("cksum in len=%d:", inlen
);
872 for (i
= 0; i
< inlen
; i
++)
873 printf ("%02x ", in
[i
] & 0xFF);
877 res
= shishi_randomize (handle
, buffer
, 8);
878 if (res
!= SHISHI_OK
)
882 printf ("cksum random: ");
883 for (i
= 0; i
< 8; i
++)
884 printf ("%02X ", buffer
[i
] & 0xFF);
888 hd
= gcry_md_open (GCRY_MD_MD4
, 0);
890 return SHISHI_GCRYPT_ERROR
;
892 gcry_md_write (hd
, buffer
, inlen
+ 8);
893 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
896 printf ("cksum md4: ");
897 for (i
= 0; i
< 16; i
++)
898 printf ("%02X ", p
[i
] & 0xFF);
902 memcpy (buffer
+ 8, p
, 16);
905 memcpy (out
, buffer
, 8 + 16);
910 printf ("cksum out: ");
911 for (i
= 0; i
< *outlen
; i
++)
912 printf ("%02X ", out
[i
] & 0xFF);
920 checksum_md5 (Shishi
* handle
,
921 char *out
, int *outlen
, char *in
, int inlen
)
928 if (inlen
+ 8 > BUFSIZ
)
930 shishi_error_printf (handle
, "checksum inbuffer too large");
934 memcpy (buffer
+ 8, in
, inlen
);
937 printf ("cksum in len=%d:", inlen
);
938 for (i
= 0; i
< inlen
; i
++)
939 printf ("%02x ", in
[i
] & 0xFF);
943 res
= shishi_randomize (handle
, buffer
, 8);
944 if (res
!= SHISHI_OK
)
948 printf ("cksum random: ");
949 for (i
= 0; i
< 8; i
++)
950 printf ("%02X ", buffer
[i
] & 0xFF);
954 hd
= gcry_md_open (GCRY_MD_MD5
, 0);
956 return SHISHI_GCRYPT_ERROR
;
958 gcry_md_write (hd
, buffer
, inlen
+ 8);
959 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
962 printf ("cksum md5: ");
963 for (i
= 0; i
< 16; i
++)
964 printf ("%02X ", p
[i
] & 0xFF);
968 memcpy (buffer
+ 8, p
, 16);
971 memcpy (out
, buffer
, 8 + 16);
976 printf ("cksum out: ");
977 for (i
= 0; i
< *outlen
; i
++)
978 printf ("%02X ", out
[i
] & 0xFF);