Doc fix.
[shishi.git] / lib / crypto-des.c
blob8cf3c7776714a2911da46d01ebe5a4b396898590
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 int blen = 8;
33 int hlen = 16;
34 int rc;
36 rc = shishi_randomize (handle, out, blen);
37 if (rc != SHISHI_OK)
38 return rc;
40 tmplen = blen + inlen;
41 tmp = xmalloc (tmplen);
43 memcpy (tmp, out, blen);
44 memcpy (tmp + blen, in, inlen);
46 switch (algo)
48 case SHISHI_DES_CBC_MD4:
49 rc = shishi_md4 (handle, tmp, tmplen, &p);
50 break;
52 case SHISHI_DES_CBC_MD5:
53 rc = shishi_md5 (handle, tmp, tmplen, &p);
54 break;
56 default:
57 shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
58 return SHISHI_CRYPTO_INTERNAL_ERROR;
59 break;
62 memcpy (out + blen, p, hlen);
64 *outlen = blen + hlen;
66 return SHISHI_OK;
69 static int
70 raw_des_checksum1 (Shishi * handle, int algo,
71 const char *in, size_t inlen,
72 char *out, size_t * outlen)
74 char *tmp;
75 size_t tmplen;
76 char *p;
77 int blen = 8;
78 int hlen = 16;
79 int rc;
81 rc = shishi_randomize (handle, out, blen);
82 if (rc != SHISHI_OK)
83 return rc;
85 memset (out + blen, 0, hlen);
87 tmplen = blen + hlen + inlen;
88 tmp = xmalloc (tmplen);
90 memcpy (tmp, out, blen + hlen);
91 memcpy (tmp + blen + hlen, in, inlen);
93 switch (algo)
95 case SHISHI_DES_CBC_MD4:
96 rc = shishi_md4 (handle, tmp, tmplen, &p);
97 break;
99 case SHISHI_DES_CBC_MD5:
100 rc = shishi_md5 (handle, tmp, tmplen, &p);
101 break;
103 default:
104 shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
105 return SHISHI_CRYPTO_INTERNAL_ERROR;
106 break;
109 memcpy (out + blen, p, hlen);
111 *outlen = blen + hlen;
113 return SHISHI_OK;
116 static int
117 des_encrypt_checksum (Shishi * handle,
118 Shishi_key * key,
119 int keyusage,
120 const char *iv, size_t ivlen,
121 char **ivout, size_t * ivoutlen,
122 const char *in, size_t inlen,
123 char **out, size_t * outlen, int algo)
125 char cksum[8 + MAX_HASH_LEN];
126 char *inpad;
127 char *pt;
128 size_t inpadlen, padzerolen = 0, ptlen, cksumlen;
129 int res;
131 if (inlen % 8)
132 padzerolen = 8 - (inlen % 8);
133 inpadlen = inlen + padzerolen;
134 inpad = xmalloc (inpadlen);
136 memcpy (inpad, in, inlen);
137 memset (inpad + inlen, 0, padzerolen);
139 res = raw_des_checksum1 (handle, algo, inpad, inpadlen, cksum, &cksumlen);
140 if (res != SHISHI_OK)
142 shishi_error_printf (handle, "DES checksum failed");
143 return res;
146 ptlen = inpadlen + cksumlen;
147 pt = xmalloc (ptlen);
148 memcpy (pt, cksum, cksumlen);
149 memcpy (pt + cksumlen, inpad, inpadlen);
151 free (inpad);
153 res = simplified_encrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
154 pt, ptlen, out, outlen);
156 free (pt);
158 if (res != SHISHI_OK)
160 shishi_error_printf (handle, "DES encrypt failed");
161 return res;
164 return SHISHI_OK;
167 static int
168 des_crc_encrypt (Shishi * handle,
169 Shishi_key * key,
170 int keyusage,
171 const char *iv, size_t ivlen,
172 char **ivout, size_t * ivoutlen,
173 const char *in, size_t inlen, char **out, size_t * outlen)
175 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
176 ivoutlen, in, inlen, out, outlen,
177 SHISHI_DES_CBC_CRC);
180 static int
181 des_md4_encrypt (Shishi * handle,
182 Shishi_key * key,
183 int keyusage,
184 const char *iv,
185 size_t ivlen,
186 char **ivout, size_t * ivoutlen,
187 const char *in, size_t inlen, char **out, size_t * outlen)
189 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
190 ivoutlen, in, inlen, out, outlen,
191 SHISHI_DES_CBC_MD4);
194 static int
195 des_md5_encrypt (Shishi * handle,
196 Shishi_key * key,
197 int keyusage,
198 const char *iv,
199 size_t ivlen,
200 char **ivout, size_t * ivoutlen,
201 const char *in, size_t inlen, char **out, size_t * outlen)
203 return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
204 ivoutlen, in, inlen, out, outlen,
205 SHISHI_DES_CBC_MD5);
208 static int
209 des_none_encrypt (Shishi * handle,
210 Shishi_key * key,
211 int keyusage,
212 const char *iv,
213 size_t ivlen,
214 char **ivout, size_t * ivoutlen,
215 const char *in, size_t inlen, char **out, size_t * outlen)
217 return simplified_encrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
218 in, inlen, out, outlen);
221 static int
222 des_decrypt_verify (Shishi * handle,
223 Shishi_key * key,
224 int keyusage,
225 const char *iv, size_t ivlen,
226 char **ivout, size_t * ivoutlen,
227 const char *in, size_t inlen,
228 char **out, size_t * outlen, int algo)
230 int res;
231 char incoming[16];
232 char *computed;
233 size_t hlen = 16;
235 res = simplified_decrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
236 in, inlen, out, outlen);
237 if (res != SHISHI_OK)
239 shishi_error_printf (handle, "decrypt failed");
240 return res;
243 memcpy (incoming, *out + 8, hlen);
244 memset (*out + 8, 0, hlen);
246 switch (algo)
248 case SHISHI_DES_CBC_MD4:
249 shishi_md4 (handle, *out, *outlen, &computed);
250 break;
252 case SHISHI_DES_CBC_MD5:
253 shishi_md5 (handle, *out, *outlen, &computed);
254 break;
256 default:
257 shishi_error_printf (handle, "MD %d unknown in raw des verify", algo);
258 return SHISHI_CRYPTO_ERROR;
259 break;
262 if (VERBOSECRYPTO (handle))
264 puts ("DES verify:");
265 hexprint (incoming, hlen);
266 puts ("");
267 hexprint (computed, hlen);
268 puts ("");
271 if (memcmp (computed, incoming, hlen) != 0)
273 shishi_error_printf (handle, "DES hash verify failed");
274 return SHISHI_CRYPTO_ERROR;
277 free (computed);
279 memmove (*out, *out + 8 + hlen, *outlen - 8 - hlen);
280 *outlen -= 8 + hlen;
282 return SHISHI_OK;
285 static int
286 des_crc_decrypt (Shishi * handle,
287 Shishi_key * key,
288 int keyusage,
289 const char *iv,
290 size_t ivlen,
291 char **ivout, size_t * ivoutlen,
292 const char *in, size_t inlen, char **out, size_t * outlen)
294 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
295 ivoutlen, in, inlen, out, outlen,
296 SHISHI_DES_CBC_CRC);
299 static int
300 des_md4_decrypt (Shishi * handle,
301 Shishi_key * key,
302 int keyusage,
303 const char *iv,
304 size_t ivlen,
305 char **ivout, size_t * ivoutlen,
306 const char *in, size_t inlen, char **out, size_t * outlen)
308 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
309 ivoutlen, in, inlen, out, outlen,
310 SHISHI_DES_CBC_MD4);
313 static int
314 des_md5_decrypt (Shishi * handle,
315 Shishi_key * key,
316 int keyusage,
317 const char *iv,
318 size_t ivlen,
319 char **ivout, size_t * ivoutlen,
320 const char *in, size_t inlen, char **out, size_t * outlen)
322 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
323 ivoutlen, in, inlen, out, outlen,
324 SHISHI_DES_CBC_MD5);
327 static int
328 des_none_decrypt (Shishi * handle,
329 Shishi_key * key,
330 int keyusage,
331 const char *iv,
332 size_t ivlen,
333 char **ivout, size_t * ivoutlen,
334 const char *in, size_t inlen, char **out, size_t * outlen)
336 return simplified_decrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
337 in, inlen, out, outlen);
340 static int
341 des_set_odd_key_parity (char key[8])
343 int i, j;
345 for (i = 0; i < 8; i++)
347 int n_set_bits = 0;
349 for (j = 1; j < 8; j++)
350 if (key[i] & (1 << j))
351 n_set_bits++;
353 key[i] &= ~1;
354 if ((n_set_bits % 2) == 0)
355 key[i] |= 1;
358 return SHISHI_OK;
361 static char weak_des_keys[16][8] = {
362 /* Weak keys */
363 "\x01\x01\x01\x01\x01\x01\x01\x01",
364 "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
365 "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
366 "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
367 /* Semiweak keys */
368 "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
369 "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
370 "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
371 "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
372 "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
373 "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
374 "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
375 "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
376 "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
377 "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
378 "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
379 "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
382 static int
383 des_key_correction (Shishi * handle, char key[8])
385 size_t i;
387 /* fixparity(key); */
388 des_set_odd_key_parity (key);
390 /* This loop could be replaced by optimized code (compare nettle),
391 but let's not do that. */
392 for (i = 0; i < 16; i++)
393 if (memcmp (key, weak_des_keys[i], 8) == 0)
395 if (VERBOSECRYPTO (handle))
396 printf ("\t ;; WEAK KEY (corrected)\n");
397 key[7] ^= 0xF0;
398 break;
401 return SHISHI_OK;
404 static int
405 des_random_to_key (Shishi * handle,
406 const char *random, size_t randomlen, Shishi_key * outkey)
408 char tmp[MAX_RANDOM_LEN];
409 int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
411 if (randomlen != shishi_key_length (outkey))
413 shishi_error_printf (handle, "DES random to key caller error");
414 return SHISHI_CRYPTO_ERROR;
417 memcpy (tmp, random, keylen);
418 des_set_odd_key_parity (tmp);
420 shishi_key_value_set (outkey, tmp);
422 return SHISHI_OK;
425 static int
426 des_string_to_key (Shishi * handle,
427 const char *string,
428 size_t stringlen,
429 const char *salt,
430 size_t saltlen, const char *parameter, Shishi_key * outkey)
432 char *s;
433 int n_s;
434 int odd;
435 char tempkey[8];
436 char *p;
437 int i, j;
438 char temp, temp2;
439 int res;
441 if (VERBOSECRYPTO (handle))
443 printf ("des_string_to_key (string, salt)\n");
445 printf ("\t ;; String:\n");
446 escapeprint (string, stringlen);
447 hexprint (string, stringlen);
448 puts ("");
449 puts ("");
451 printf ("\t ;; Salt:\n");
452 escapeprint (salt, saltlen);
453 hexprint (salt, saltlen);
454 puts ("");
456 printf ("odd = 1;\n");
457 printf ("s = string | salt;\n");
458 printf ("tempstring = 0; /* 56-bit string */\n");
459 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
463 odd = 1;
464 n_s = stringlen + saltlen;
465 if ((n_s % 8) != 0)
466 n_s += 8 - n_s % 8;
467 s = (char *) xmalloc (n_s);
468 memcpy (s, string, stringlen);
469 if (saltlen > 0)
470 memcpy (s + stringlen, salt, saltlen);
471 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
472 memset (tempkey, 0, sizeof (tempkey)); /* tempkey = NULL; */
474 if (VERBOSECRYPTO (handle))
476 printf ("\t ;; s = pad(string|salt):\n");
477 escapeprint (s, n_s);
478 hexprint (s, n_s);
479 puts ("");
482 for (i = 0; i < n_s / 8; i++)
484 if (VERBOSECRYPTO (handle))
486 printf ("for (8byteblock in s) {\n");
487 printf ("\t ;; loop iteration %d\n", i);
488 printf ("\t ;; 8byteblock:\n");
489 escapeprint (&s[i * 8], 8);
490 hexprint (&s[i * 8], 8);
491 puts ("");
492 binprint (&s[i * 8], 8);
493 puts ("");
494 printf ("56bitstring = removeMSBits(8byteblock);\n");
497 for (j = 0; j < 8; j++)
498 s[i * 8 + j] = s[i * 8 + j] & ~0x80;
500 if (VERBOSECRYPTO (handle))
502 printf ("\t ;; 56bitstring:\n");
503 bin7print (&s[i * 8], 8);
504 puts ("");
505 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
508 if (odd == 0)
510 for (j = 0; j < 4; j++)
512 temp = s[i * 8 + j];
513 temp =
514 ((temp >> 6) & 0x01) |
515 ((temp >> 4) & 0x02) |
516 ((temp >> 2) & 0x04) |
517 ((temp) & 0x08) |
518 ((temp << 2) & 0x10) |
519 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
520 temp2 = s[i * 8 + 7 - j];
521 temp2 =
522 ((temp2 >> 6) & 0x01) |
523 ((temp2 >> 4) & 0x02) |
524 ((temp2 >> 2) & 0x04) |
525 ((temp2) & 0x08) |
526 ((temp2 << 2) & 0x10) |
527 ((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
528 s[i * 8 + j] = temp2;
529 s[i * 8 + 7 - j] = temp;
531 if (VERBOSECRYPTO (handle))
533 printf ("reverse(56bitstring)\n");
534 printf ("\t ;; 56bitstring after reverse\n");
535 bin7print (&s[i * 8], 8);
536 puts ("");
540 odd = !odd;
542 if (VERBOSECRYPTO (handle))
544 printf ("odd = ! odd\n");
545 printf ("tempstring = tempstring XOR 56bitstring;\n");
548 /* tempkey = tempkey XOR 8byteblock; */
549 for (j = 0; j < 8; j++)
550 tempkey[j] ^= s[i * 8 + j];
552 if (VERBOSECRYPTO (handle))
554 printf ("\t ;; tempstring\n");
555 bin7print (tempkey, 8);
556 puts ("");
557 puts ("");
561 for (j = 0; j < 8; j++)
562 tempkey[j] = tempkey[j] << 1;
564 if (VERBOSECRYPTO (handle))
566 printf ("for (8byteblock in s) {\n");
567 printf ("}\n");
568 printf ("\t ;; for loop terminated\n");
569 printf ("\t ;; tempstring as 64bitblock\n");
570 hexprint (tempkey, 8);
571 puts ("");
572 binprint (tempkey, 8);
573 puts ("");
574 printf ("/* add parity as low bit of each byte */\n");
575 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
578 res = des_key_correction (handle, tempkey);
579 if (res != SHISHI_OK)
580 return res;
582 if (VERBOSECRYPTO (handle))
584 printf ("\t ;; tempkey\n");
585 escapeprint (tempkey, 8);
586 hexprint (tempkey, 8);
587 puts ("");
588 binprint (tempkey, 8);
589 puts ("");
590 puts ("");
591 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
594 memcpy (s, string, stringlen);
595 if (saltlen > 0)
596 memcpy (s + stringlen, salt, saltlen);
597 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
599 res = shishi_des_cbc_mac (handle, tempkey, tempkey, s, n_s, &p);
600 if (res != SHISHI_OK)
601 return res;
602 memcpy (tempkey, p, 8);
603 free (p);
605 res = des_key_correction (handle, tempkey);
606 if (res != SHISHI_OK)
607 return res;
609 if (VERBOSECRYPTO (handle))
611 printf ("\t ;; key\n");
612 escapeprint (tempkey, 8);
613 hexprint (tempkey, 8);
614 puts ("");
615 binprint (tempkey, 8);
616 puts ("");
617 puts ("");
620 shishi_key_value_set (outkey, tempkey);
622 return SHISHI_OK;
625 static int
626 des_checksum (Shishi * handle,
627 Shishi_key * key,
628 int keyusage,
629 int cksumtype,
630 const char *in, size_t inlen,
631 char **out, size_t * outlen, int algo)
633 char cksum[8 + MAX_HASH_LEN];
634 size_t cksumlen;
635 char *keyp;
636 int i;
637 int res;
639 res = raw_des_checksum0 (handle, algo, in, inlen, cksum, &cksumlen);
640 if (res != SHISHI_OK)
642 shishi_error_set (handle, "raw des checksum failed");
643 return res;
646 keyp = shishi_key_value (key);
648 for (i = 0; i < 8; i++)
649 keyp[i] ^= 0xF0;
651 res = simplified_dencrypt (handle, key, NULL, 0, NULL, NULL,
652 cksum, cksumlen, out, outlen, 0);
654 for (i = 0; i < 8; i++)
655 keyp[i] ^= 0xF0;
657 if (res != SHISHI_OK)
659 shishi_error_set (handle, "encrypt failed");
660 return res;
663 return SHISHI_OK;
666 static int
667 des_md4_checksum (Shishi * handle,
668 Shishi_key * key,
669 int keyusage,
670 int cksumtype,
671 const char *in, size_t inlen, char **out, size_t * outlen)
673 return des_checksum (handle, key, keyusage, cksumtype,
674 in, inlen, out, outlen, SHISHI_DES_CBC_MD4);
677 static int
678 des_md5_checksum (Shishi * handle,
679 Shishi_key * key,
680 int keyusage,
681 int cksumtype,
682 const char *in, size_t inlen, char **out, size_t * outlen)
684 return des_checksum (handle, key, keyusage, cksumtype,
685 in, inlen, out, outlen, SHISHI_DES_CBC_MD5);
688 static int
689 gss_des_checksum (Shishi * handle,
690 Shishi_key * key,
691 int keyusage,
692 int cksumtype,
693 const char *in, size_t inlen, char **out, size_t * outlen)
695 char *p;
696 int rc;
698 rc = shishi_md5 (handle, in, inlen, &p);
699 if (rc != SHISHI_OK)
700 return rc;
702 *outlen = 8;
703 rc = shishi_des_cbc_mac (handle, shishi_key_value (key), NULL, p, 16, out);
705 free (p);
707 if (rc != SHISHI_OK)
708 return rc;
710 return SHISHI_OK;
713 static int
714 des_verify (Shishi * handle, int algo,
715 Shishi_key *key,
716 const char *in, size_t inlen,
717 const char *cksum, size_t cksumlen)
719 char *out;
720 size_t outlen;
721 char *md;
722 size_t tmplen;
723 char *tmp;
724 char *keyp;
725 size_t i;
726 int res;
728 if (cksumlen != 8 + 16)
729 return SHISHI_VERIFY_FAILED;
732 * get_mic des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
733 * conf | rsa-md5(conf | msg))
734 * verify_mic decrypt and verify rsa-md5 checksum
737 keyp = shishi_key_value (key);
739 for (i = 0; i < 8; i++)
740 keyp[i] ^= 0xF0;
742 res = simplified_decrypt (handle, key, 0, NULL, 0, NULL, NULL,
743 cksum, cksumlen, &out, &outlen);
745 for (i = 0; i < 8; i++)
746 keyp[i] ^= 0xF0;
748 if (res != SHISHI_OK)
750 shishi_error_set (handle, "decrypt failed");
751 return res;
754 tmplen = 8 + inlen;
755 tmp = xmalloc (tmplen);
756 memcpy (tmp, out, 8);
757 memcpy (tmp + 8, in, inlen);
759 switch (algo)
761 case SHISHI_RSA_MD4_DES:
762 res = shishi_md4 (handle, tmp, tmplen, &md);
763 break;
765 case SHISHI_RSA_MD5_DES:
766 res = shishi_md5 (handle, tmp, tmplen, &md);
767 break;
769 default:
770 res = SHISHI_CRYPTO_ERROR;
773 if (res != SHISHI_OK)
775 shishi_error_printf (handle, "DES verify MD error");
776 return res;
779 if (memcmp (out + 8, md, 16) != 0)
780 return SHISHI_VERIFY_FAILED;
782 return SHISHI_OK;
785 static int
786 des_md4_verify (Shishi * handle,
787 Shishi_key * key,
788 int keyusage,
789 int cksumtype,
790 const char *in, size_t inlen,
791 const char *cksum, size_t cksumlen)
793 return des_verify (handle, SHISHI_RSA_MD4_DES, key,
794 in, inlen, cksum, cksumlen);
797 static int
798 des_md5_verify (Shishi * handle,
799 Shishi_key * key,
800 int keyusage,
801 int cksumtype,
802 const char *in, size_t inlen,
803 const char *cksum, size_t cksumlen)
805 return des_verify (handle, SHISHI_RSA_MD5_DES, key,
806 in, inlen, cksum, cksumlen);