Fixes.
[shishi.git] / lib / crypto-des.c
blob38fe4b61d6b75e6c7d0b2d484fd8399086f7f21c
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.
24 static int
25 des_crc_verify (Shishi * handle, char *out, int *outlen)
27 int res;
28 char md[16];
29 gcry_md_hd_t hd;
30 char *p;
32 memcpy (md, out + 8, 4);
33 memset (out + 8, 0, 4);
35 gcry_md_open (&hd, GCRY_MD_CRC32_RFC1510, 0);
37 if (!hd)
39 puts ("CRC not available");
40 return !SHISHI_OK;
43 gcry_md_write (hd, out, *outlen);
44 p = gcry_md_read (hd, GCRY_MD_CRC32_RFC1510);
45 if (VERBOSECRYPTO (handle))
47 int i;
49 for (i = 0; i < 4; i++)
50 printf ("%02X ", md[i] & 0xFF);
51 printf ("\n");
52 for (i = 0; i < 4; i++)
53 printf ("%02X ", p[i] & 0xFF);
54 printf ("\n");
57 if (memcmp (p, md, 4) == 0)
59 memmove (out, out + 8 + 4, *outlen - 8 - 4);
60 *outlen -= 8 + 4;
61 res = SHISHI_OK;
63 else
65 if (VERBOSE (handle))
66 printf ("des-cbc-crc verify fail\n");
67 res = !SHISHI_OK;
70 gcry_md_close (hd);
72 return res;
75 static int
76 des_crc_checksum (Shishi * handle,
77 char *out, size_t * outlen, const char *in, size_t inlen)
79 int res;
80 char buffer[BUFSIZ];
81 char *p;
82 gcry_md_hd_t hd;
84 if (inlen + 8 + 4 > BUFSIZ)
86 shishi_error_printf (handle, "checksum inbuffer too large");
87 return !SHISHI_OK;
90 memcpy (buffer + 8 + 4, in, inlen);
91 memset (buffer + 8, 0, 4);
93 res = shishi_randomize (handle, buffer, 8);
94 if (res != SHISHI_OK)
95 return res;
97 gcry_md_open (&hd, GCRY_MD_CRC32_RFC1510, 0);
98 if (hd == NULL)
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);
105 gcry_md_close (hd);
107 memcpy (out, buffer, 8 + 4);
109 *outlen = 8 + 4;
111 return SHISHI_OK;
114 static int
115 des_md4_verify (Shishi * handle, char *out, int *outlen)
117 int res;
118 char md[16];
119 gcry_md_hd_t hd;
120 char *p;
122 memcpy (md, out + 8, 16);
123 memset (out + 8, 0, 16);
125 gcry_md_open (&hd, GCRY_MD_MD4, 0);
127 if (!hd)
129 puts ("MD4 not available");
130 return !SHISHI_OK;
133 gcry_md_write (hd, out, *outlen);
134 p = gcry_md_read (hd, GCRY_MD_MD4);
135 if (VERBOSECRYPTO (handle))
137 int i;
139 for (i = 0; i < 16; i++)
140 printf ("%02X ", md[i] & 0xFF);
141 printf ("\n");
142 for (i = 0; i < 16; i++)
143 printf ("%02X ", p[i] & 0xFF);
144 printf ("\n");
147 if (memcmp (p, md, 16) == 0)
149 memmove (out, out + 8 + 16, *outlen - 8 - 16);
150 *outlen -= 8 + 16;
151 res = SHISHI_OK;
153 else
155 if (VERBOSE (handle))
156 printf ("des-cbc-md4 verify fail\n");
157 res = !SHISHI_OK;
160 gcry_md_close (hd);
162 return res;
165 static int
166 des_md4_checksum (Shishi * handle,
167 char *out, size_t * outlen, const char *in, size_t inlen)
169 int res;
170 char buffer[BUFSIZ];
171 char *p;
172 gcry_md_hd_t hd;
174 if (inlen + 8 + 16 > BUFSIZ)
176 shishi_error_printf (handle, "checksum inbuffer too large");
177 return !SHISHI_OK;
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)
185 return res;
187 gcry_md_open (&hd, GCRY_MD_MD4, 0);
188 if (hd == NULL)
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);
195 gcry_md_close (hd);
197 memcpy (out, buffer, 8 + 16);
199 *outlen = 8 + 16;
201 return SHISHI_OK;
204 static int
205 des_md5_verify (Shishi * handle, char *out, int *outlen)
207 int res;
208 char md[16];
209 gcry_md_hd_t hd;
210 char *p;
212 memcpy (md, out + 8, 16);
213 memset (out + 8, 0, 16);
215 gcry_md_open (&hd, GCRY_MD_MD5, 0);
217 if (!hd)
219 shishi_error_set (handle, "MD5 not available");
220 return !SHISHI_OK;
223 gcry_md_write (hd, out, *outlen);
224 p = gcry_md_read (hd, GCRY_MD_MD5);
225 if (VERBOSECRYPTO (handle))
227 int i;
229 for (i = 0; i < 16; i++)
230 printf ("%02X ", md[i] & 0xFF);
231 printf ("\n");
232 for (i = 0; i < 16; i++)
233 printf ("%02X ", p[i] & 0xFF);
234 printf ("\n");
237 if (memcmp (p, md, 16) == 0)
239 memmove (out, out + 8 + 16, *outlen - 8 - 16);
240 *outlen -= 8 + 16;
241 res = SHISHI_OK;
243 else
245 if (VERBOSE (handle))
246 printf ("des-cbc-md5 verify fail\n");
247 res = !SHISHI_OK;
250 gcry_md_close (hd);
252 return res;
255 static int
256 des_md5_checksum (Shishi * handle,
257 char *out, size_t * outlen, const char *in, size_t inlen)
259 int res;
260 char buffer[BUFSIZ];
261 char *p;
262 gcry_md_hd_t hd;
264 if (inlen + 8 + 16 > BUFSIZ)
266 shishi_error_printf (handle, "checksum inbuffer too large");
267 return !SHISHI_OK;
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)
275 return res;
277 gcry_md_open (&hd, GCRY_MD_MD5, 0);
278 if (hd == NULL)
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);
285 gcry_md_close (hd);
287 memcpy (out, buffer, 8 + 16);
289 *outlen = 8 + 16;
291 return SHISHI_OK;
294 static int
295 des_crc_encrypt (Shishi * handle,
296 Shishi_key * key,
297 int keyusage,
298 const char *iv, size_t ivlen,
299 const char *in, size_t inlen, char **out, size_t * outlen)
301 char buffer[BUFSIZ];
302 char buffer2[BUFSIZ];
303 int buflen;
304 int buf2len;
305 int res;
307 memcpy (buffer2, in, inlen);
308 buf2len = inlen;
310 while ((buf2len % 8) != 0)
312 buffer2[buf2len] = '\0'; /* XXX */
313 buf2len++;
316 buflen = sizeof (buffer);
317 res = des_crc_checksum (handle, buffer, &buflen, buffer2, buf2len);
318 memcpy (buffer + buflen, buffer2, buf2len);
319 buflen += buf2len;
320 res = simplified_encrypt (handle, key, 0, iv, ivlen,
321 buffer, buflen, out, outlen);
323 return res;
326 static int
327 des_crc_decrypt (Shishi * handle,
328 Shishi_key * key,
329 int keyusage,
330 const char *iv, size_t ivlen,
331 const char *in, size_t inlen, char **out, size_t * outlen)
333 int res;
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");
341 return res;
343 #if 0
344 memcpy (out,
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",
346 232);
347 *outlen = 232;
348 #endif
350 size_t i;
351 printf ("decrypt %d\n", *outlen);
352 for (i = 0; i < *outlen; i++)
353 printf ("%02x ", ((char *) out)[i] & 0xFF);
354 printf ("\n");
356 res = des_crc_verify (handle, *out, outlen);
357 if (res != SHISHI_OK)
359 shishi_error_set (handle, "verify failed");
360 return res;
363 return res;
366 static int
367 des_md4_encrypt (Shishi * handle,
368 Shishi_key * key,
369 int keyusage,
370 const char *iv, size_t ivlen,
371 const char *in, size_t inlen, char **out, size_t * outlen)
373 char buffer[BUFSIZ];
374 char buffer2[BUFSIZ];
375 size_t buflen;
376 size_t buf2len;
377 int res;
379 memcpy (buffer2, in, inlen);
380 buf2len = inlen;
381 while ((buf2len % 8) != 0)
383 buffer2[buf2len] = '\0'; /* XXX */
384 buf2len++;
387 buflen = sizeof (buffer);
388 res = des_md4_checksum (handle, buffer, &buflen, buffer2, buf2len);
389 memcpy (buffer + buflen, buffer, buf2len);
390 buflen += buf2len;
391 res = simplified_encrypt (handle, key, 0, iv, ivlen,
392 buffer, buflen, out, outlen);
394 return res;
397 static int
398 des_md4_decrypt (Shishi * handle,
399 Shishi_key * key,
400 int keyusage,
401 const char *iv,
402 size_t ivlen,
403 const char *in, size_t inlen, char **out, size_t * outlen)
405 int res;
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");
412 return res;
414 res = des_md4_verify (handle, *out, outlen);
415 if (res != SHISHI_OK)
417 shishi_error_set (handle, "verify failed");
418 return res;
421 return res;
424 static int
425 des_md5_encrypt (Shishi * handle,
426 Shishi_key * key,
427 int keyusage,
428 const char *iv,
429 size_t ivlen,
430 const char *in, size_t inlen, char **out, size_t * outlen)
432 char buffer[BUFSIZ];
433 char buffer2[BUFSIZ];
434 size_t buflen;
435 size_t buf2len;
436 int res;
438 memcpy (buffer2, in, inlen);
439 buf2len = inlen;
441 while ((buf2len % 8) != 0)
443 buffer2[buf2len] = '\0'; /* XXX */
444 buf2len++;
447 buflen = sizeof (buffer);
448 res = des_md5_checksum (handle, buffer, &buflen, buffer2, buf2len);
449 memcpy (buffer + buflen, buffer2, buf2len);
450 buflen += buf2len;
451 res = simplified_encrypt (handle, key, 0, iv, ivlen,
452 buffer, buflen, out, outlen);
454 return res;
457 static int
458 des_md5_decrypt (Shishi * handle,
459 Shishi_key * key,
460 int keyusage,
461 const char *iv,
462 size_t ivlen,
463 const char *in, size_t inlen, char **out, size_t * outlen)
465 int res;
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");
472 return res;
474 res = des_md5_verify (handle, *out, outlen);
475 if (res != SHISHI_OK)
477 shishi_error_set (handle, "verify failed");
478 return res;
481 return res;
484 static int
485 des_none_encrypt (Shishi * handle,
486 Shishi_key * key,
487 int keyusage,
488 const char *iv,
489 size_t ivlen,
490 const char *in, size_t inlen, char **out, size_t * outlen)
492 int res;
494 res = simplified_encrypt (handle, key, 0, iv, ivlen,
495 in, inlen, out, outlen);
496 if (res != SHISHI_OK)
497 return res;
499 return SHISHI_OK;
502 static int
503 des_none_decrypt (Shishi * handle,
504 Shishi_key * key,
505 int keyusage,
506 const char *iv,
507 size_t ivlen,
508 const char *in, size_t inlen, char **out, size_t * outlen)
510 int res;
512 res = simplified_decrypt (handle, key, 0, iv, ivlen,
513 in, inlen, out, outlen);
514 if (res != SHISHI_OK)
515 return res;
517 return SHISHI_OK;
520 static int
521 des_set_odd_key_parity (char key[8])
523 int i, j;
525 for (i = 0; i < 8; i++)
527 int n_set_bits = 0;
529 for (j = 1; j < 8; j++)
530 if (key[i] & (1 << j))
531 n_set_bits++;
533 key[i] &= ~1;
534 if ((n_set_bits % 2) == 0)
535 key[i] |= 1;
538 return SHISHI_OK;
541 static int
542 des_key_correction (Shishi * handle, char *key)
544 int res;
545 gcry_cipher_hd_t ch;
547 /* fixparity(key); */
548 des_set_odd_key_parity (key);
550 gcry_cipher_open (&ch, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
551 if (ch == NULL)
552 return !SHISHI_OK;
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");
563 key[7] ^= 0xF0;
565 else
566 return !SHISHI_OK;
569 gcry_cipher_close (ch);
571 return SHISHI_OK;
574 static int
575 des_cbc_check (char key[8], char *data, int n_data)
577 gcry_cipher_hd_t ch;
578 int res;
580 gcry_cipher_open (&ch, GCRY_CIPHER_DES,
581 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
582 if (ch == NULL)
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);
590 if (res != 0)
591 return SHISHI_GCRYPT_ERROR;
593 res = gcry_cipher_encrypt (ch, key, 8, data, n_data);
594 if (res != 0)
595 return SHISHI_GCRYPT_ERROR;
597 gcry_cipher_close (ch);
599 return SHISHI_OK;
602 static int
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))
610 return !SHISHI_OK;
612 memcpy (tmp, random, keylen);
613 des_set_odd_key_parity (tmp);
615 shishi_key_value_set (outkey, tmp);
617 return SHISHI_OK;
620 static int
621 des_string_to_key (Shishi * handle,
622 const char *string,
623 size_t stringlen,
624 const char *salt,
625 size_t saltlen, const char *parameter, Shishi_key * outkey)
627 char *s;
628 int n_s;
629 int odd;
630 char tempkey[8];
631 int i, j;
632 char temp, temp2;
633 int res;
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);
642 puts ("");
643 puts ("");
645 printf ("\t ;; Salt:\n");
646 escapeprint (salt, saltlen);
647 hexprint (salt, saltlen);
648 puts ("");
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");
657 if (saltlen < 0)
658 saltlen = 0;
660 odd = 1;
661 n_s = stringlen + saltlen;
662 if ((n_s % 8) != 0)
663 n_s += 8 - n_s % 8;
664 s = (char *) malloc (n_s);
665 memcpy (s, string, stringlen);
666 if (saltlen > 0)
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);
675 hexprint (s, n_s);
676 puts ("");
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);
688 puts ("");
689 binprint (&s[i * 8], 8);
690 puts ("");
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);
701 puts ("");
702 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
705 if (odd == 0)
707 for (j = 0; j < 4; j++)
709 temp = s[i * 8 + j];
710 temp =
711 ((temp >> 6) & 0x01) |
712 ((temp >> 4) & 0x02) |
713 ((temp >> 2) & 0x04) |
714 ((temp) & 0x08) |
715 ((temp << 2) & 0x10) |
716 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
717 temp2 = s[i * 8 + 7 - j];
718 temp2 =
719 ((temp2 >> 6) & 0x01) |
720 ((temp2 >> 4) & 0x02) |
721 ((temp2 >> 2) & 0x04) |
722 ((temp2) & 0x08) |
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);
733 puts ("");
737 odd = !odd;
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);
753 puts ("");
754 puts ("");
758 for (j = 0; j < 8; j++)
759 tempkey[j] = tempkey[j] << 1;
761 if (VERBOSECRYPTO (handle))
763 printf ("for (8byteblock in s) {\n");
764 printf ("}\n");
765 printf ("\t ;; for loop terminated\n");
766 printf ("\t ;; tempstring as 64bitblock\n");
767 hexprint (tempkey, 8);
768 puts ("");
769 binprint (tempkey, 8);
770 puts ("");
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)
777 return res;
779 if (VERBOSECRYPTO (handle))
781 printf ("\t ;; tempkey\n");
782 escapeprint (tempkey, 8);
783 hexprint (tempkey, 8);
784 puts ("");
785 binprint (tempkey, 8);
786 puts ("");
787 puts ("");
788 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
791 memcpy (s, string, stringlen);
792 if (saltlen > 0)
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)
798 return res;
800 res = des_key_correction (handle, tempkey);
801 if (res != SHISHI_OK)
802 return res;
804 if (VERBOSECRYPTO (handle))
806 printf ("\t ;; key\n");
807 escapeprint (tempkey, 8);
808 hexprint (tempkey, 8);
809 puts ("");
810 binprint (tempkey, 8);
811 puts ("");
812 puts ("");
815 shishi_key_value_set (outkey, tempkey);
817 return SHISHI_OK;
820 static int
821 checksum_md4 (Shishi * handle, char *out, int *outlen, char *in, int inlen)
823 int res;
824 char buffer[BUFSIZ];
825 gcry_md_hd_t hd;
826 char *p;
828 if (inlen + 8 > BUFSIZ)
830 shishi_error_printf (handle, "checksum inbuffer too large");
831 return !SHISHI_OK;
834 memcpy (buffer + 8, in, inlen);
836 #if 0
837 printf ("cksum in len=%d:", inlen);
838 for (i = 0; i < inlen; i++)
839 printf ("%02x ", in[i] & 0xFF);
840 printf ("\n");
841 #endif
843 res = shishi_randomize (handle, buffer, 8);
844 if (res != SHISHI_OK)
845 return res;
847 #if 0
848 printf ("cksum random: ");
849 for (i = 0; i < 8; i++)
850 printf ("%02X ", buffer[i] & 0xFF);
851 printf ("\n");
852 #endif
854 gcry_md_open (&hd, GCRY_MD_MD4, 0);
855 if (!hd)
856 return SHISHI_GCRYPT_ERROR;
858 gcry_md_write (hd, buffer, inlen + 8);
859 p = gcry_md_read (hd, GCRY_MD_MD4);
861 #if 0
862 printf ("cksum md4: ");
863 for (i = 0; i < 16; i++)
864 printf ("%02X ", p[i] & 0xFF);
865 printf ("\n");
866 #endif
868 memcpy (buffer + 8, p, 16);
869 gcry_md_close (hd);
871 memcpy (out, buffer, 8 + 16);
873 *outlen = 8 + 16;
875 #if 0
876 printf ("cksum out: ");
877 for (i = 0; i < *outlen; i++)
878 printf ("%02X ", out[i] & 0xFF);
879 printf ("\n");
880 #endif
882 return SHISHI_OK;
885 static int
886 checksum_md5 (Shishi * handle, char *out, int *outlen, char *in, int inlen)
888 int res;
889 char buffer[BUFSIZ];
890 gcry_md_hd_t hd;
891 char *p;
893 if (inlen + 8 > BUFSIZ)
895 shishi_error_printf (handle, "checksum inbuffer too large");
896 return !SHISHI_OK;
899 memcpy (buffer + 8, in, inlen);
901 #if 0
902 printf ("cksum in len=%d:", inlen);
903 for (i = 0; i < inlen; i++)
904 printf ("%02x ", in[i] & 0xFF);
905 printf ("\n");
906 #endif
908 res = shishi_randomize (handle, buffer, 8);
909 if (res != SHISHI_OK)
910 return res;
912 #if 0
913 printf ("cksum random: ");
914 for (i = 0; i < 8; i++)
915 printf ("%02X ", buffer[i] & 0xFF);
916 printf ("\n");
917 #endif
919 gcry_md_open (&hd, GCRY_MD_MD5, 0);
920 if (!hd)
921 return SHISHI_GCRYPT_ERROR;
923 gcry_md_write (hd, buffer, inlen + 8);
924 p = gcry_md_read (hd, GCRY_MD_MD5);
926 #if 0
927 printf ("cksum md5: ");
928 for (i = 0; i < 16; i++)
929 printf ("%02X ", p[i] & 0xFF);
930 printf ("\n");
931 #endif
933 memcpy (buffer + 8, p, 16);
934 gcry_md_close (hd);
936 memcpy (out, buffer, 8 + 16);
938 *outlen = 8 + 16;
940 #if 0
941 printf ("cksum out: ");
942 for (i = 0; i < *outlen; i++)
943 printf ("%02X ", out[i] & 0xFF);
944 printf ("\n");
945 #endif
947 return SHISHI_OK;