Fix.
[shishi.git] / lib / crypto-des.c
blob89495e963ccaf43dee70790ee706a4b3b3cfe028
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 raw_des_verify (Shishi * handle, int algo, char *out, int *outlen)
27 #ifdef USE_GCRYPT
28 char md[MAX_HASH_LEN];
29 gcry_md_hd_t hd;
30 gpg_error_t err;
31 int alg = (algo == SHISHI_DES_CBC_MD4) ? GCRY_MD_MD4 : GCRY_MD_MD5;
32 int hlen = gcry_md_get_algo_dlen (alg);
33 int ok;
34 char *p;
36 memcpy (md, out + 8, hlen);
37 memset (out + 8, 0, hlen);
39 err = gcry_md_open (&hd, alg, 0);
40 if (err != GPG_ERR_NO_ERROR)
42 shishi_error_printf (handle, "Algo %d not available in libgcrypt", alg);
43 return SHISHI_CRYPTO_INTERNAL_ERROR;
46 gcry_md_write (hd, out, *outlen);
48 p = gcry_md_read (hd, alg);
49 if (p == NULL)
51 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
52 return SHISHI_CRYPTO_INTERNAL_ERROR;
55 if (VERBOSECRYPTO (handle))
57 puts("DES verify:");
58 hexprint(md, hlen); puts("");
59 hexprint (p, hlen); puts("");
62 ok = memcmp (p, md, hlen) == 0;
64 gcry_md_close (hd);
66 if (!ok)
68 shishi_error_printf (handle, "DES verify failed");
69 return SHISHI_CRYPTO_ERROR;
72 memmove (out, out + 8 + hlen, *outlen - 8 - hlen);
73 *outlen -= 8 + hlen;
74 #else
75 struct md5_ctx md5;
76 struct md4_ctx md4;
77 char incoming[MAX_HASH_LEN];
78 char computed[MAX_HASH_LEN];
79 int hlen;
80 int rc;
82 switch (algo)
84 case SHISHI_DES_CBC_MD4:
85 memcpy (incoming, out + 8, MD4_DIGEST_SIZE);
86 memset (out + 8, 0, MD4_DIGEST_SIZE);
87 md4_init (&md4);
88 md4_update (&md4, *outlen, out);
89 md4_digest (&md4, MD4_DIGEST_SIZE, computed);
90 hlen = MD4_DIGEST_SIZE;
91 break;
93 case SHISHI_DES_CBC_MD5:
94 memcpy (incoming, out + 8, MD5_DIGEST_SIZE);
95 memset (out + 8, 0, MD5_DIGEST_SIZE);
96 md5_init (&md5);
97 md5_update (&md5, *outlen, out);
98 md5_digest (&md5, MD5_DIGEST_SIZE, computed);
99 hlen = MD5_DIGEST_SIZE;
100 break;
102 default:
103 shishi_error_printf (handle, "MD %d unknown in raw des verify", algo);
104 return SHISHI_CRYPTO_INTERNAL_ERROR;
105 break;
108 if (VERBOSECRYPTO (handle))
110 puts("DES verify:");
111 hexprint(incoming, hlen); puts("");
112 hexprint (computed, hlen); puts("");
115 if (memcmp (computed, incoming, hlen) != 0)
117 shishi_error_printf (handle, "DES hash verify failed");
118 return SHISHI_CRYPTO_ERROR;
121 memmove (out, out + 8 + hlen, *outlen - 8 - hlen);
122 *outlen -= 8 + hlen;
123 #endif
125 return SHISHI_OK;
128 static int
129 raw_des_checksum (Shishi * handle,
130 int algo,
131 const char *in, size_t inlen,
132 char *out, size_t * outlen,
133 int hashzeros)
135 #ifdef USE_GCRYPT
136 gpg_error_t err;
137 int alg = (algo == SHISHI_DES_CBC_MD4) ? GCRY_MD_MD4 : GCRY_MD_MD5;
138 int hlen = gcry_md_get_algo_dlen (alg);
139 char buffer[8 + MAX_HASH_LEN];
140 char *p;
141 gcry_md_hd_t hd;
142 int res;
144 err = gcry_md_open (&hd, alg, 0);
145 if (err != GPG_ERR_NO_ERROR)
147 shishi_error_printf (handle, "MD %d not available in libgcrypt", alg);
148 return SHISHI_CRYPTO_INTERNAL_ERROR;
151 res = shishi_randomize (handle, buffer, 8);
152 if (res != SHISHI_OK)
153 return res;
155 memset (buffer + 8, 0, hlen);
157 if (hashzeros)
158 gcry_md_write (hd, buffer, 8 + hlen);
159 else
160 gcry_md_write (hd, buffer, 8);
161 gcry_md_write (hd, in, inlen);
163 p = gcry_md_read (hd, alg);
164 if (p == NULL)
166 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
167 return SHISHI_CRYPTO_INTERNAL_ERROR;
170 memcpy(out, buffer, 8);
171 memcpy(out + 8, p, hlen);
173 gcry_md_close (hd);
175 *outlen = 8 + hlen;
176 #else
177 struct md5_ctx md5;
178 struct md4_ctx md4;
179 int hlen;
180 int rc;
182 rc = shishi_randomize (handle, out, 8);
183 if (rc != SHISHI_OK)
184 return rc;
186 switch (algo)
188 case SHISHI_DES_CBC_MD4:
189 memset (out + 8, 0, MD4_DIGEST_SIZE);
190 md4_init (&md4);
191 if (hashzeros)
192 md4_update (&md4, 8 + MD4_DIGEST_SIZE, out);
193 else
194 md4_update (&md4, 8, out);
195 md4_update (&md4, inlen, in);
197 md4_digest (&md4, MD4_DIGEST_SIZE, out + 8);
199 hlen = MD4_DIGEST_SIZE;
200 break;
202 case SHISHI_DES_CBC_MD5:
203 memset (out + 8, 0, MD5_DIGEST_SIZE);
204 md5_init (&md5);
205 if (hashzeros)
206 md5_update (&md5, 8 + MD5_DIGEST_SIZE, out);
207 else
208 md5_update (&md5, 8, out);
209 md5_update (&md5, inlen, in);
211 md5_digest (&md5, MD5_DIGEST_SIZE, out + 8);
213 hlen = MD5_DIGEST_SIZE;
214 break;
216 default:
217 shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
218 return SHISHI_CRYPTO_INTERNAL_ERROR;
219 break;
222 *outlen = 8 + hlen;
223 #endif
225 return SHISHI_OK;
228 static int
229 des_encrypt_checksum (Shishi * handle,
230 Shishi_key * key,
231 int keyusage,
232 const char *iv,
233 size_t ivlen,
234 const char *in, size_t inlen, char **out, size_t * outlen,
235 int algo)
237 char cksum[8 + MAX_HASH_LEN];
238 char *inpad;
239 char *pt;
240 size_t inpadlen, padzerolen = 0, ptlen, cksumlen;
241 int res;
243 if (inlen % 8)
244 padzerolen = 8 - (inlen % 8);
245 inpadlen = inlen + padzerolen;
246 inpad = xmalloc (inpadlen);
248 memcpy (inpad, in, inlen);
249 memset (inpad + inlen, 0, padzerolen);
251 res = raw_des_checksum (handle, algo, inpad, inpadlen, cksum, &cksumlen, 1);
252 if (res != SHISHI_OK)
254 shishi_error_printf (handle, "DES checksum failed");
255 return res;
258 ptlen = inpadlen + cksumlen;
259 pt = xmalloc (ptlen);
260 memcpy (pt, cksum, cksumlen);
261 memcpy (pt + cksumlen, inpad, inpadlen);
263 free (inpad);
265 res = simplified_encrypt (handle, key, 0, iv, ivlen,
266 pt, ptlen, out, outlen);
268 free (pt);
270 if (res != SHISHI_OK)
272 shishi_error_printf (handle, "DES encrypt failed");
273 return res;
276 return SHISHI_OK;
279 static int
280 des_crc_encrypt (Shishi * handle,
281 Shishi_key * key,
282 int keyusage,
283 const char *iv,
284 size_t ivlen,
285 const char *in, size_t inlen, char **out, size_t * outlen)
287 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen,
288 in, inlen, out, outlen, SHISHI_DES_CBC_CRC);
291 static int
292 des_md4_encrypt (Shishi * handle,
293 Shishi_key * key,
294 int keyusage,
295 const char *iv,
296 size_t ivlen,
297 const char *in, size_t inlen, char **out, size_t * outlen)
299 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen,
300 in, inlen, out, outlen, SHISHI_DES_CBC_MD4);
303 static int
304 des_md5_encrypt (Shishi * handle,
305 Shishi_key * key,
306 int keyusage,
307 const char *iv,
308 size_t ivlen,
309 const char *in, size_t inlen, char **out, size_t * outlen)
311 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen,
312 in, inlen, out, outlen, SHISHI_DES_CBC_MD5);
315 static int
316 des_none_encrypt (Shishi * handle,
317 Shishi_key * key,
318 int keyusage,
319 const char *iv,
320 size_t ivlen,
321 const char *in, size_t inlen, char **out, size_t * outlen)
323 return simplified_encrypt (handle, key, 0, iv, ivlen,
324 in, inlen, out, outlen);
327 static int
328 des_decrypt_verify (Shishi * handle,
329 Shishi_key * key,
330 int keyusage,
331 const char *iv, size_t ivlen,
332 const char *in, size_t inlen,
333 char **out, size_t * outlen,
334 int algo)
336 int res;
338 res = simplified_decrypt (handle, key, 0, iv, ivlen,
339 in, inlen, out, outlen);
340 if (res != SHISHI_OK)
342 shishi_error_printf (handle, "decrypt failed");
343 return res;
346 res = raw_des_verify (handle, algo, *out, outlen);
347 if (res != SHISHI_OK)
349 shishi_error_printf (handle, "verify failed");
350 return res;
353 return SHISHI_OK;
356 static int
357 des_crc_decrypt (Shishi * handle,
358 Shishi_key * key,
359 int keyusage,
360 const char *iv,
361 size_t ivlen,
362 const char *in, size_t inlen, char **out, size_t * outlen)
364 return des_decrypt_verify (handle, key, keyusage, iv, ivlen,
365 in, inlen, out, outlen, SHISHI_DES_CBC_CRC);
368 static int
369 des_md4_decrypt (Shishi * handle,
370 Shishi_key * key,
371 int keyusage,
372 const char *iv,
373 size_t ivlen,
374 const char *in, size_t inlen, char **out, size_t * outlen)
376 return des_decrypt_verify (handle, key, keyusage, iv, ivlen,
377 in, inlen, out, outlen, SHISHI_DES_CBC_MD4);
380 static int
381 des_md5_decrypt (Shishi * handle,
382 Shishi_key * key,
383 int keyusage,
384 const char *iv,
385 size_t ivlen,
386 const char *in, size_t inlen, char **out, size_t * outlen)
388 return des_decrypt_verify (handle, key, keyusage, iv, ivlen,
389 in, inlen, out, outlen, SHISHI_DES_CBC_MD5);
392 static int
393 des_none_decrypt (Shishi * handle,
394 Shishi_key * key,
395 int keyusage,
396 const char *iv,
397 size_t ivlen,
398 const char *in, size_t inlen, char **out, size_t * outlen)
400 return simplified_decrypt (handle, key, 0, iv, ivlen,
401 in, inlen, out, outlen);
404 static int
405 des_set_odd_key_parity (char key[8])
407 int i, j;
409 for (i = 0; i < 8; i++)
411 int n_set_bits = 0;
413 for (j = 1; j < 8; j++)
414 if (key[i] & (1 << j))
415 n_set_bits++;
417 key[i] &= ~1;
418 if ((n_set_bits % 2) == 0)
419 key[i] |= 1;
422 return SHISHI_OK;
425 static int
426 des_key_correction (Shishi * handle, char *key)
428 #ifdef USE_GCRYPT
429 gcry_cipher_hd_t ch;
430 gpg_error_t err;
432 /* fixparity(key); */
433 des_set_odd_key_parity (key);
435 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
436 if (err != GPG_ERR_NO_ERROR)
438 shishi_error_printf (handle, "DES-CBC not available in libgcrypt");
439 return SHISHI_CRYPTO_INTERNAL_ERROR;
442 /* XXX? libgcrypt tests for pseudo-weak keys, rfc 1510 doesn't */
444 err = gcry_cipher_setkey (ch, key, 8);
446 gcry_cipher_close (ch);
448 if (err != GPG_ERR_NO_ERROR)
450 if (gpg_err_code (err) == GPG_ERR_WEAK_KEY)
452 if (VERBOSECRYPTO (handle))
453 printf ("\t ;; WEAK KEY (corrected)\n");
454 key[7] ^= 0xF0;
456 else
458 shishi_error_printf (handle, "DES setkey failed");
459 shishi_error_set (handle, gpg_strerror (err));
460 return SHISHI_CRYPTO_INTERNAL_ERROR;
463 #else
464 struct CBC_MAC_CTX (struct des_ctx, DES_BLOCK_SIZE) des;
465 int rc;
467 /* fixparity(key); */
468 des_set_odd_key_parity (key);
470 rc = des_set_key (&des.ctx, key);
471 if (!rc && des.ctx.status == DES_WEAK_KEY)
473 if (VERBOSECRYPTO (handle))
474 printf ("\t ;; WEAK KEY (corrected)\n");
475 key[7] ^= 0xF0;
477 #endif
479 return SHISHI_OK;
482 static int
483 des_random_to_key (Shishi * handle,
484 const char *random, size_t randomlen, Shishi_key * outkey)
486 char tmp[MAX_RANDOM_LEN];
487 int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
489 if (randomlen != shishi_key_length (outkey))
491 shishi_error_printf (handle, "DES random to key caller error");
492 return SHISHI_CRYPTO_ERROR;
495 memcpy (tmp, random, keylen);
496 des_set_odd_key_parity (tmp);
498 shishi_key_value_set (outkey, tmp);
500 return SHISHI_OK;
503 static int
504 des_cbc_check (Shishi * handle, char key[8], char *data, int n_data)
506 #ifdef USE_GCRYPT
507 gcry_cipher_hd_t ch;
508 gpg_error_t err;
509 int res = SHISHI_CRYPTO_INTERNAL_ERROR;
511 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES,
512 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
513 if (err != GPG_ERR_NO_ERROR)
515 shishi_error_printf (handle, "DES-CBC-MAC not available in libgcrypt");
516 return SHISHI_CRYPTO_INTERNAL_ERROR;
519 err = gcry_cipher_setkey (ch, key, 8);
520 if (err != GPG_ERR_NO_ERROR)
522 shishi_error_printf (handle, "DES setkey failed");
523 shishi_error_set (handle, gpg_strerror (err));
524 goto done;
527 err = gcry_cipher_setiv (ch, key, 8);
528 if (err != GPG_ERR_NO_ERROR)
530 shishi_error_printf (handle, "DES setiv failed");
531 shishi_error_set (handle, gpg_strerror (err));
532 goto done;
535 err = gcry_cipher_encrypt (ch, key, 8, data, n_data);
536 if (err != GPG_ERR_NO_ERROR)
538 shishi_error_printf (handle, "DES encrypt failed");
539 shishi_error_set (handle, gpg_strerror (err));
540 goto done;
543 return SHISHI_OK;
545 done:
546 gcry_cipher_close (ch);
547 return res;
548 #else
549 struct CBC_MAC_CTX (struct des_ctx, DES_BLOCK_SIZE) des;
550 int rc;
552 rc = des_set_key (&des.ctx, key);
553 if (!rc)
555 shishi_error_printf (handle, "des_set_key() failed (%d)", rc);
556 return SHISHI_CRYPTO_INTERNAL_ERROR;
559 CBC_SET_IV (&des, key);
561 CBC_MAC (&des, des_encrypt, n_data, key, data);
563 return SHISHI_OK;
564 #endif
567 static int
568 des_string_to_key (Shishi * handle,
569 const char *string,
570 size_t stringlen,
571 const char *salt,
572 size_t saltlen, const char *parameter, Shishi_key * outkey)
574 char *s;
575 int n_s;
576 int odd;
577 char tempkey[8];
578 int i, j;
579 char temp, temp2;
580 int res;
582 if (VERBOSECRYPTO (handle))
584 printf ("des_string_to_key (string, salt)\n");
586 printf ("\t ;; String:\n");
587 escapeprint (string, stringlen);
588 hexprint (string, stringlen);
589 puts ("");
590 puts ("");
592 printf ("\t ;; Salt:\n");
593 escapeprint (salt, saltlen);
594 hexprint (salt, saltlen);
595 puts ("");
597 printf ("odd = 1;\n");
598 printf ("s = string | salt;\n");
599 printf ("tempstring = 0; /* 56-bit string */\n");
600 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
604 if (saltlen < 0)
605 saltlen = 0;
607 odd = 1;
608 n_s = stringlen + saltlen;
609 if ((n_s % 8) != 0)
610 n_s += 8 - n_s % 8;
611 s = (char *) malloc (n_s);
612 memcpy (s, string, stringlen);
613 if (saltlen > 0)
614 memcpy (s + stringlen, salt, saltlen);
615 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
616 memset (tempkey, 0, sizeof (tempkey)); /* tempkey = NULL; */
618 if (VERBOSECRYPTO (handle))
620 printf ("\t ;; s = pad(string|salt):\n");
621 escapeprint (s, n_s);
622 hexprint (s, n_s);
623 puts ("");
626 for (i = 0; i < n_s / 8; i++)
628 if (VERBOSECRYPTO (handle))
630 printf ("for (8byteblock in s) {\n");
631 printf ("\t ;; loop iteration %d\n", i);
632 printf ("\t ;; 8byteblock:\n");
633 escapeprint (&s[i * 8], 8);
634 hexprint (&s[i * 8], 8);
635 puts ("");
636 binprint (&s[i * 8], 8);
637 puts ("");
638 printf ("56bitstring = removeMSBits(8byteblock);\n");
641 for (j = 0; j < 8; j++)
642 s[i * 8 + j] = s[i * 8 + j] & ~0x80;
644 if (VERBOSECRYPTO (handle))
646 printf ("\t ;; 56bitstring:\n");
647 bin7print (&s[i * 8], 8);
648 puts ("");
649 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
652 if (odd == 0)
654 for (j = 0; j < 4; j++)
656 temp = s[i * 8 + j];
657 temp =
658 ((temp >> 6) & 0x01) |
659 ((temp >> 4) & 0x02) |
660 ((temp >> 2) & 0x04) |
661 ((temp) & 0x08) |
662 ((temp << 2) & 0x10) |
663 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
664 temp2 = s[i * 8 + 7 - j];
665 temp2 =
666 ((temp2 >> 6) & 0x01) |
667 ((temp2 >> 4) & 0x02) |
668 ((temp2 >> 2) & 0x04) |
669 ((temp2) & 0x08) |
670 ((temp2 << 2) & 0x10) |
671 ((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
672 s[i * 8 + j] = temp2;
673 s[i * 8 + 7 - j] = temp;
675 if (VERBOSECRYPTO (handle))
677 printf ("reverse(56bitstring)\n");
678 printf ("\t ;; 56bitstring after reverse\n");
679 bin7print (&s[i * 8], 8);
680 puts ("");
684 odd = !odd;
686 if (VERBOSECRYPTO (handle))
688 printf ("odd = ! odd\n");
689 printf ("tempstring = tempstring XOR 56bitstring;\n");
692 /* tempkey = tempkey XOR 8byteblock; */
693 for (j = 0; j < 8; j++)
694 tempkey[j] ^= s[i * 8 + j];
696 if (VERBOSECRYPTO (handle))
698 printf ("\t ;; tempstring\n");
699 bin7print (tempkey, 8);
700 puts ("");
701 puts ("");
705 for (j = 0; j < 8; j++)
706 tempkey[j] = tempkey[j] << 1;
708 if (VERBOSECRYPTO (handle))
710 printf ("for (8byteblock in s) {\n");
711 printf ("}\n");
712 printf ("\t ;; for loop terminated\n");
713 printf ("\t ;; tempstring as 64bitblock\n");
714 hexprint (tempkey, 8);
715 puts ("");
716 binprint (tempkey, 8);
717 puts ("");
718 printf ("/* add parity as low bit of each byte */\n");
719 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
722 res = des_key_correction (handle, tempkey);
723 if (res != SHISHI_OK)
724 return res;
726 if (VERBOSECRYPTO (handle))
728 printf ("\t ;; tempkey\n");
729 escapeprint (tempkey, 8);
730 hexprint (tempkey, 8);
731 puts ("");
732 binprint (tempkey, 8);
733 puts ("");
734 puts ("");
735 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
738 memcpy (s, string, stringlen);
739 if (saltlen > 0)
740 memcpy (s + stringlen, salt, saltlen);
741 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
743 res = des_cbc_check (handle, tempkey, s, n_s);
744 if (res != SHISHI_OK)
745 return res;
747 res = des_key_correction (handle, tempkey);
748 if (res != SHISHI_OK)
749 return res;
751 if (VERBOSECRYPTO (handle))
753 printf ("\t ;; key\n");
754 escapeprint (tempkey, 8);
755 hexprint (tempkey, 8);
756 puts ("");
757 binprint (tempkey, 8);
758 puts ("");
759 puts ("");
762 shishi_key_value_set (outkey, tempkey);
764 return SHISHI_OK;
767 static int
768 des_checksum (Shishi * handle,
769 Shishi_key * key,
770 int keyusage,
771 int cksumtype,
772 char *in, size_t inlen, char **out, size_t * outlen,
773 int algo)
775 char cksum[8 + MAX_HASH_LEN];
776 size_t cksumlen;
777 char *keyp;
778 int i;
779 int res;
781 res = raw_des_checksum (handle, algo, in, inlen, cksum, &cksumlen, 0);
782 if (res != SHISHI_OK)
784 shishi_error_set (handle, "raw des checksum failed");
785 return res;
789 keyp = shishi_key_value (key);
791 for (i = 0; i < 8; i++)
792 keyp[i] ^= 0xF0;
794 res = simplified_dencrypt (handle, key, NULL, 0, cksum, cksumlen,
795 out, outlen, 0);
797 for (i = 0; i < 8; i++)
798 keyp[i] ^= 0xF0;
800 if (res != SHISHI_OK)
802 shishi_error_set (handle, "encrypt failed");
803 return res;
806 return SHISHI_OK;
809 static int
810 des_md4_checksum (Shishi * handle,
811 Shishi_key * key,
812 int keyusage,
813 int cksumtype,
814 char *in, size_t inlen, char **out, size_t * outlen)
816 return des_checksum (handle, key, keyusage, cksumtype,
817 in, inlen, out, outlen,
818 SHISHI_DES_CBC_MD4);
821 static int
822 des_md5_checksum (Shishi * handle,
823 Shishi_key * key,
824 int keyusage,
825 int cksumtype,
826 char *in, size_t inlen, char **out, size_t * outlen)
828 return des_checksum (handle, key, keyusage, cksumtype,
829 in, inlen, out, outlen,
830 SHISHI_DES_CBC_MD5);
834 gss_des_checksum (Shishi * handle,
835 Shishi_key * key,
836 int keyusage,
837 int cksumtype,
838 char *in, size_t inlen,
839 char **out, size_t * outlen)
841 #ifdef USE_GCRYPT
842 char buffer[BUFSIZ];
843 int buflen;
844 char *keyp;
845 char *p;
846 int i;
847 gcry_md_hd_t hd;
848 gcry_cipher_hd_t ch;
849 int res;
851 gcry_md_open (&hd, GCRY_MD_MD5, 0);
852 if (!hd)
853 return SHISHI_CRYPTO_INTERNAL_ERROR;
855 gcry_md_write (hd, in, inlen);
856 p = gcry_md_read (hd, GCRY_MD_MD5);
858 keyp = shishi_key_value (key);
860 gcry_cipher_open (&ch, GCRY_CIPHER_DES,
861 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
862 if (ch == NULL)
863 return SHISHI_CRYPTO_INTERNAL_ERROR;
865 res = gcry_cipher_setkey (ch, keyp, 8);
866 if (res != GPG_ERR_NO_ERROR)
867 return SHISHI_CRYPTO_INTERNAL_ERROR;
869 res = gcry_cipher_setiv (ch, NULL, 8);
870 if (res != 0)
871 return SHISHI_CRYPTO_INTERNAL_ERROR;
873 *outlen = 8;
874 *out = xmalloc (*outlen);
876 res = gcry_cipher_encrypt (ch, *out, *outlen, p, 16);
877 if (res != 0)
878 return SHISHI_CRYPTO_INTERNAL_ERROR;
880 gcry_cipher_close (ch);
881 gcry_md_close (hd);
882 #else
883 struct md5_ctx md5;
884 struct CBC_MAC_CTX (struct des_ctx, DES_BLOCK_SIZE) des;
885 char digest[MD5_DIGEST_SIZE];
886 int rc;
888 md5_init (&md5);
889 md5_update (&md5, inlen, in);
890 md5_digest (&md5, sizeof(digest), digest);
892 rc = des_set_key (&des.ctx, shishi_key_value (key));
893 if (!rc)
895 shishi_error_printf (handle, "des_set_key() failed (%d)", rc);
896 return SHISHI_CRYPTO_INTERNAL_ERROR;
899 memset(des.iv, 0, sizeof(des.iv));
901 *outlen = DES_BLOCK_SIZE;
902 *out = xmalloc (*outlen);
904 CBC_MAC (&des, des_encrypt, MD5_DIGEST_SIZE, *out, digest);
905 #endif
906 return SHISHI_OK;