Add md4 verify.
[shishi.git] / lib / crypto-des.c
blob363f0bbcf293f4a5e425a65de19e87bf41df8f67
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_checksum0 (Shishi * handle, int algo,
26 const char *in, size_t inlen,
27 char *out, size_t * outlen)
29 char *tmp;
30 size_t tmplen;
31 char *p;
32 size_t plen;
33 int blen = 8;
34 int hlen = 16;
35 int rc;
37 rc = shishi_randomize (handle, out, blen);
38 if (rc != SHISHI_OK)
39 return rc;
41 tmplen = blen + inlen;
42 tmp = xmalloc (tmplen);
44 memcpy (tmp, out, blen);
45 memcpy (tmp + blen, in, inlen);
47 switch (algo)
49 case SHISHI_DES_CBC_MD4:
50 rc = shishi_md4 (handle, tmp, tmplen, &p, &plen);
51 break;
53 case SHISHI_DES_CBC_MD5:
54 rc = shishi_md5 (handle, tmp, tmplen, &p, &plen);
55 break;
57 default:
58 shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
59 return SHISHI_CRYPTO_INTERNAL_ERROR;
60 break;
63 memcpy (out + blen, p, plen);
65 *outlen = blen + hlen;
67 return SHISHI_OK;
70 static int
71 raw_des_checksum1 (Shishi * handle, int algo,
72 const char *in, size_t inlen,
73 char *out, size_t * outlen)
75 char *tmp;
76 size_t tmplen;
77 char *p;
78 size_t plen;
79 int blen = 8;
80 int hlen = 16;
81 int rc;
83 rc = shishi_randomize (handle, out, blen);
84 if (rc != SHISHI_OK)
85 return rc;
87 memset (out + blen, 0, hlen);
89 tmplen = blen + hlen + inlen;
90 tmp = xmalloc (tmplen);
92 memcpy (tmp, out, blen + hlen);
93 memcpy (tmp + blen + hlen, in, inlen);
95 switch (algo)
97 case SHISHI_DES_CBC_MD4:
98 rc = shishi_md4 (handle, tmp, tmplen, &p, &plen);
99 break;
101 case SHISHI_DES_CBC_MD5:
102 rc = shishi_md5 (handle, tmp, tmplen, &p, &plen);
103 break;
105 default:
106 shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
107 return SHISHI_CRYPTO_INTERNAL_ERROR;
108 break;
111 memcpy (out + blen, p, plen);
113 *outlen = blen + hlen;
115 return SHISHI_OK;
118 static int
119 des_encrypt_checksum (Shishi * handle,
120 Shishi_key * key,
121 int keyusage,
122 const char *iv, size_t ivlen,
123 char **ivout, size_t * ivoutlen,
124 const char *in, size_t inlen,
125 char **out, size_t * outlen, int algo)
127 char cksum[8 + MAX_HASH_LEN];
128 char *inpad;
129 char *pt;
130 size_t inpadlen, padzerolen = 0, ptlen, cksumlen;
131 int res;
133 if (inlen % 8)
134 padzerolen = 8 - (inlen % 8);
135 inpadlen = inlen + padzerolen;
136 inpad = xmalloc (inpadlen);
138 memcpy (inpad, in, inlen);
139 memset (inpad + inlen, 0, padzerolen);
141 res = raw_des_checksum1 (handle, algo, inpad, inpadlen, cksum, &cksumlen);
142 if (res != SHISHI_OK)
144 shishi_error_printf (handle, "DES checksum failed");
145 return res;
148 ptlen = inpadlen + cksumlen;
149 pt = xmalloc (ptlen);
150 memcpy (pt, cksum, cksumlen);
151 memcpy (pt + cksumlen, inpad, inpadlen);
153 free (inpad);
155 res = simplified_encrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
156 pt, ptlen, out, outlen);
158 free (pt);
160 if (res != SHISHI_OK)
162 shishi_error_printf (handle, "DES encrypt failed");
163 return res;
166 return SHISHI_OK;
169 static int
170 des_crc_encrypt (Shishi * handle,
171 Shishi_key * key,
172 int keyusage,
173 const char *iv, size_t ivlen,
174 char **ivout, size_t * ivoutlen,
175 const char *in, size_t inlen, char **out, size_t * outlen)
177 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
178 ivoutlen, in, inlen, out, outlen,
179 SHISHI_DES_CBC_CRC);
182 static int
183 des_md4_encrypt (Shishi * handle,
184 Shishi_key * key,
185 int keyusage,
186 const char *iv,
187 size_t ivlen,
188 char **ivout, size_t * ivoutlen,
189 const char *in, size_t inlen, char **out, size_t * outlen)
191 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
192 ivoutlen, in, inlen, out, outlen,
193 SHISHI_DES_CBC_MD4);
196 static int
197 des_md5_encrypt (Shishi * handle,
198 Shishi_key * key,
199 int keyusage,
200 const char *iv,
201 size_t ivlen,
202 char **ivout, size_t * ivoutlen,
203 const char *in, size_t inlen, char **out, size_t * outlen)
205 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
206 ivoutlen, in, inlen, out, outlen,
207 SHISHI_DES_CBC_MD5);
210 static int
211 des_none_encrypt (Shishi * handle,
212 Shishi_key * key,
213 int keyusage,
214 const char *iv,
215 size_t ivlen,
216 char **ivout, size_t * ivoutlen,
217 const char *in, size_t inlen, char **out, size_t * outlen)
219 return simplified_encrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
220 in, inlen, out, outlen);
223 static int
224 des_decrypt_verify (Shishi * handle,
225 Shishi_key * key,
226 int keyusage,
227 const char *iv, size_t ivlen,
228 char **ivout, size_t * ivoutlen,
229 const char *in, size_t inlen,
230 char **out, size_t * outlen, int algo)
232 int res;
233 char incoming[16];
234 char *computed;
235 size_t hlen = 16;
237 res = simplified_decrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
238 in, inlen, out, outlen);
239 if (res != SHISHI_OK)
241 shishi_error_printf (handle, "decrypt failed");
242 return res;
245 memcpy (incoming, *out + 8, hlen);
246 memset (*out + 8, 0, hlen);
248 switch (algo)
250 case SHISHI_DES_CBC_MD4:
251 shishi_md4 (handle, *out, *outlen, &computed, &hlen);
252 break;
254 case SHISHI_DES_CBC_MD5:
255 shishi_md5 (handle, *out, *outlen, &computed, &hlen);
256 break;
258 default:
259 shishi_error_printf (handle, "MD %d unknown in raw des verify", algo);
260 return SHISHI_CRYPTO_ERROR;
261 break;
264 if (VERBOSECRYPTO (handle))
266 puts ("DES verify:");
267 hexprint (incoming, hlen);
268 puts ("");
269 hexprint (computed, hlen);
270 puts ("");
273 if (memcmp (computed, incoming, hlen) != 0)
275 shishi_error_printf (handle, "DES hash verify failed");
276 return SHISHI_CRYPTO_ERROR;
279 free (computed);
281 memmove (*out, *out + 8 + hlen, *outlen - 8 - hlen);
282 *outlen -= 8 + hlen;
284 return SHISHI_OK;
287 static int
288 des_crc_decrypt (Shishi * handle,
289 Shishi_key * key,
290 int keyusage,
291 const char *iv,
292 size_t ivlen,
293 char **ivout, size_t * ivoutlen,
294 const char *in, size_t inlen, char **out, size_t * outlen)
296 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
297 ivoutlen, in, inlen, out, outlen,
298 SHISHI_DES_CBC_CRC);
301 static int
302 des_md4_decrypt (Shishi * handle,
303 Shishi_key * key,
304 int keyusage,
305 const char *iv,
306 size_t ivlen,
307 char **ivout, size_t * ivoutlen,
308 const char *in, size_t inlen, char **out, size_t * outlen)
310 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
311 ivoutlen, in, inlen, out, outlen,
312 SHISHI_DES_CBC_MD4);
315 static int
316 des_md5_decrypt (Shishi * handle,
317 Shishi_key * key,
318 int keyusage,
319 const char *iv,
320 size_t ivlen,
321 char **ivout, size_t * ivoutlen,
322 const char *in, size_t inlen, char **out, size_t * outlen)
324 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
325 ivoutlen, in, inlen, out, outlen,
326 SHISHI_DES_CBC_MD5);
329 static int
330 des_none_decrypt (Shishi * handle,
331 Shishi_key * key,
332 int keyusage,
333 const char *iv,
334 size_t ivlen,
335 char **ivout, size_t * ivoutlen,
336 const char *in, size_t inlen, char **out, size_t * outlen)
338 return simplified_decrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
339 in, inlen, out, outlen);
342 static int
343 des_set_odd_key_parity (char key[8])
345 int i, j;
347 for (i = 0; i < 8; i++)
349 int n_set_bits = 0;
351 for (j = 1; j < 8; j++)
352 if (key[i] & (1 << j))
353 n_set_bits++;
355 key[i] &= ~1;
356 if ((n_set_bits % 2) == 0)
357 key[i] |= 1;
360 return SHISHI_OK;
363 static char weak_des_keys[16][8] = {
364 /* Weak keys */
365 "\x01\x01\x01\x01\x01\x01\x01\x01",
366 "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
367 "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
368 "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
369 /* Semiweak keys */
370 "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
371 "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
372 "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
373 "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
374 "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
375 "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
376 "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
377 "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
378 "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
379 "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
380 "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
381 "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
384 static int
385 des_key_correction (Shishi * handle, char key[8])
387 size_t i;
389 /* fixparity(key); */
390 des_set_odd_key_parity (key);
392 /* This loop could be replaced by optimized code (compare nettle),
393 but let's not do that. */
394 for (i = 0; i < 16; i++)
395 if (memcmp (key, weak_des_keys[i], 8) == 0)
397 if (VERBOSECRYPTO (handle))
398 printf ("\t ;; WEAK KEY (corrected)\n");
399 key[7] ^= 0xF0;
400 break;
403 return SHISHI_OK;
406 static int
407 des_random_to_key (Shishi * handle,
408 const char *random, size_t randomlen, Shishi_key * outkey)
410 char tmp[MAX_RANDOM_LEN];
411 int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
413 if (randomlen != shishi_key_length (outkey))
415 shishi_error_printf (handle, "DES random to key caller error");
416 return SHISHI_CRYPTO_ERROR;
419 memcpy (tmp, random, keylen);
420 des_set_odd_key_parity (tmp);
422 shishi_key_value_set (outkey, tmp);
424 return SHISHI_OK;
427 static int
428 des_string_to_key (Shishi * handle,
429 const char *string,
430 size_t stringlen,
431 const char *salt,
432 size_t saltlen, const char *parameter, Shishi_key * outkey)
434 char *s;
435 int n_s;
436 int odd;
437 char tempkey[8];
438 char *p;
439 int i, j;
440 char temp, temp2;
441 int res;
443 if (VERBOSECRYPTO (handle))
445 printf ("des_string_to_key (string, salt)\n");
447 printf ("\t ;; String:\n");
448 escapeprint (string, stringlen);
449 hexprint (string, stringlen);
450 puts ("");
451 puts ("");
453 printf ("\t ;; Salt:\n");
454 escapeprint (salt, saltlen);
455 hexprint (salt, saltlen);
456 puts ("");
458 printf ("odd = 1;\n");
459 printf ("s = string | salt;\n");
460 printf ("tempstring = 0; /* 56-bit string */\n");
461 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
465 odd = 1;
466 n_s = stringlen + saltlen;
467 if ((n_s % 8) != 0)
468 n_s += 8 - n_s % 8;
469 s = (char *) xmalloc (n_s);
470 memcpy (s, string, stringlen);
471 if (saltlen > 0)
472 memcpy (s + stringlen, salt, saltlen);
473 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
474 memset (tempkey, 0, sizeof (tempkey)); /* tempkey = NULL; */
476 if (VERBOSECRYPTO (handle))
478 printf ("\t ;; s = pad(string|salt):\n");
479 escapeprint (s, n_s);
480 hexprint (s, n_s);
481 puts ("");
484 for (i = 0; i < n_s / 8; i++)
486 if (VERBOSECRYPTO (handle))
488 printf ("for (8byteblock in s) {\n");
489 printf ("\t ;; loop iteration %d\n", i);
490 printf ("\t ;; 8byteblock:\n");
491 escapeprint (&s[i * 8], 8);
492 hexprint (&s[i * 8], 8);
493 puts ("");
494 binprint (&s[i * 8], 8);
495 puts ("");
496 printf ("56bitstring = removeMSBits(8byteblock);\n");
499 for (j = 0; j < 8; j++)
500 s[i * 8 + j] = s[i * 8 + j] & ~0x80;
502 if (VERBOSECRYPTO (handle))
504 printf ("\t ;; 56bitstring:\n");
505 bin7print (&s[i * 8], 8);
506 puts ("");
507 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
510 if (odd == 0)
512 for (j = 0; j < 4; j++)
514 temp = s[i * 8 + j];
515 temp =
516 ((temp >> 6) & 0x01) |
517 ((temp >> 4) & 0x02) |
518 ((temp >> 2) & 0x04) |
519 ((temp) & 0x08) |
520 ((temp << 2) & 0x10) |
521 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
522 temp2 = s[i * 8 + 7 - j];
523 temp2 =
524 ((temp2 >> 6) & 0x01) |
525 ((temp2 >> 4) & 0x02) |
526 ((temp2 >> 2) & 0x04) |
527 ((temp2) & 0x08) |
528 ((temp2 << 2) & 0x10) |
529 ((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
530 s[i * 8 + j] = temp2;
531 s[i * 8 + 7 - j] = temp;
533 if (VERBOSECRYPTO (handle))
535 printf ("reverse(56bitstring)\n");
536 printf ("\t ;; 56bitstring after reverse\n");
537 bin7print (&s[i * 8], 8);
538 puts ("");
542 odd = !odd;
544 if (VERBOSECRYPTO (handle))
546 printf ("odd = ! odd\n");
547 printf ("tempstring = tempstring XOR 56bitstring;\n");
550 /* tempkey = tempkey XOR 8byteblock; */
551 for (j = 0; j < 8; j++)
552 tempkey[j] ^= s[i * 8 + j];
554 if (VERBOSECRYPTO (handle))
556 printf ("\t ;; tempstring\n");
557 bin7print (tempkey, 8);
558 puts ("");
559 puts ("");
563 for (j = 0; j < 8; j++)
564 tempkey[j] = tempkey[j] << 1;
566 if (VERBOSECRYPTO (handle))
568 printf ("for (8byteblock in s) {\n");
569 printf ("}\n");
570 printf ("\t ;; for loop terminated\n");
571 printf ("\t ;; tempstring as 64bitblock\n");
572 hexprint (tempkey, 8);
573 puts ("");
574 binprint (tempkey, 8);
575 puts ("");
576 printf ("/* add parity as low bit of each byte */\n");
577 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
580 res = des_key_correction (handle, tempkey);
581 if (res != SHISHI_OK)
582 return res;
584 if (VERBOSECRYPTO (handle))
586 printf ("\t ;; tempkey\n");
587 escapeprint (tempkey, 8);
588 hexprint (tempkey, 8);
589 puts ("");
590 binprint (tempkey, 8);
591 puts ("");
592 puts ("");
593 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
596 memcpy (s, string, stringlen);
597 if (saltlen > 0)
598 memcpy (s + stringlen, salt, saltlen);
599 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
601 res = shishi_des_cbc_mac (handle, tempkey, tempkey, s, n_s, &p);
602 if (res != SHISHI_OK)
603 return res;
604 memcpy (tempkey, p, 8);
605 free (p);
607 res = des_key_correction (handle, tempkey);
608 if (res != SHISHI_OK)
609 return res;
611 if (VERBOSECRYPTO (handle))
613 printf ("\t ;; key\n");
614 escapeprint (tempkey, 8);
615 hexprint (tempkey, 8);
616 puts ("");
617 binprint (tempkey, 8);
618 puts ("");
619 puts ("");
622 shishi_key_value_set (outkey, tempkey);
624 return SHISHI_OK;
627 static int
628 des_checksum (Shishi * handle,
629 Shishi_key * key,
630 int keyusage,
631 int cksumtype,
632 const char *in, size_t inlen,
633 char **out, size_t * outlen, int algo)
635 char cksum[8 + MAX_HASH_LEN];
636 size_t cksumlen;
637 char *keyp;
638 int i;
639 int res;
641 res = raw_des_checksum0 (handle, algo, in, inlen, cksum, &cksumlen);
642 if (res != SHISHI_OK)
644 shishi_error_set (handle, "raw des checksum failed");
645 return res;
648 keyp = shishi_key_value (key);
650 for (i = 0; i < 8; i++)
651 keyp[i] ^= 0xF0;
653 res = simplified_dencrypt (handle, key, NULL, 0, NULL, NULL,
654 cksum, cksumlen, out, outlen, 0);
656 for (i = 0; i < 8; i++)
657 keyp[i] ^= 0xF0;
659 if (res != SHISHI_OK)
661 shishi_error_set (handle, "encrypt failed");
662 return res;
665 return SHISHI_OK;
668 static int
669 des_md4_checksum (Shishi * handle,
670 Shishi_key * key,
671 int keyusage,
672 int cksumtype,
673 const char *in, size_t inlen, char **out, size_t * outlen)
675 return des_checksum (handle, key, keyusage, cksumtype,
676 in, inlen, out, outlen, SHISHI_DES_CBC_MD4);
679 static int
680 des_md5_checksum (Shishi * handle,
681 Shishi_key * key,
682 int keyusage,
683 int cksumtype,
684 const char *in, size_t inlen, char **out, size_t * outlen)
686 return des_checksum (handle, key, keyusage, cksumtype,
687 in, inlen, out, outlen, SHISHI_DES_CBC_MD5);
690 static int
691 gss_des_checksum (Shishi * handle,
692 Shishi_key * key,
693 int keyusage,
694 int cksumtype,
695 const char *in, size_t inlen, char **out, size_t * outlen)
697 char *p;
698 size_t plen;
699 int rc;
701 rc = shishi_md5 (handle, in, inlen, &p, &plen);
702 if (rc != SHISHI_OK)
703 return rc;
705 *outlen = 8;
706 rc = shishi_des_cbc_mac (handle, shishi_key_value (key), NULL, p, plen, out);
708 free (p);
710 if (rc != SHISHI_OK)
711 return rc;
713 return SHISHI_OK;
716 static int
717 des_verify (Shishi * handle, int algo,
718 const char key[8],
719 const char *in, size_t inlen,
720 const char *cksum, size_t cksumlen)
722 char *out;
723 size_t outlen;
724 char *md;
725 size_t mdlen;
726 size_t tmplen;
727 char *tmp;
728 char *keyp;
729 size_t i;
730 int res;
732 if (cksumlen != 8 + 16)
733 return SHISHI_VERIFY_FAILED;
736 * get_mic des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
737 * conf | rsa-md5(conf | msg))
738 * verify_mic decrypt and verify rsa-md5 checksum
741 keyp = xmemdup (key, 8);
742 for (i = 0; i < 8; i++)
743 keyp[i] ^= 0xF0;
745 res = simplified_decrypt (handle, key, 0, NULL, 0, NULL, NULL,
746 cksum, cksumlen, &out, &outlen);
748 free (keyp);
750 if (res != SHISHI_OK)
752 shishi_error_set (handle, "decrypt failed");
753 return res;
756 tmplen = 8 + inlen;
757 tmp = xmalloc (tmplen);
758 memcpy (tmp, out, 8);
759 memcpy (tmp + 8, in, inlen);
761 switch (algo)
763 case SHISHI_RSA_MD4_DES:
764 res = shishi_md4 (handle, tmp, tmplen, &md, &mdlen);
765 break;
767 case SHISHI_RSA_MD5_DES:
768 res = shishi_md5 (handle, tmp, tmplen, &md, &mdlen);
769 break;
771 default:
772 res = SHISHI_CRYPTO_ERROR;
775 if (res != SHISHI_OK)
777 shishi_error_printf (handle, "DES verify MD error");
778 return res;
781 if (memcmp (out + 8, md, 16) != 0)
782 return SHISHI_VERIFY_FAILED;
784 return SHISHI_OK;
787 static int
788 des_md4_verify (Shishi * handle,
789 Shishi_key * key,
790 int keyusage,
791 int cksumtype,
792 const char *in, size_t inlen,
793 const char *cksum, size_t cksumlen)
795 return des_verify (handle, SHISHI_RSA_MD4_DES, shishi_key_value (key),
796 in, inlen, cksum, cksumlen);
799 static int
800 des_md5_verify (Shishi * handle,
801 Shishi_key * key,
802 int keyusage,
803 int cksumtype,
804 const char *in, size_t inlen,
805 const char *cksum, size_t cksumlen)
807 return des_verify (handle, SHISHI_RSA_MD5_DES, shishi_key_value (key),
808 in, inlen, cksum, cksumlen);