Cleanup debug messages.
[shishi.git] / lib / crypto-des.c
blob96744e7a5d2f177831ed24372dfbb99b743dae5e
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 hexprint (computed, hlen);
269 if (memcmp (computed, incoming, hlen) != 0)
271 shishi_error_printf (handle, "DES hash verify failed");
272 return SHISHI_CRYPTO_ERROR;
275 free (computed);
277 memmove (*out, *out + 8 + hlen, *outlen - 8 - hlen);
278 *outlen -= 8 + hlen;
280 return SHISHI_OK;
283 static int
284 des_crc_decrypt (Shishi * handle,
285 Shishi_key * key,
286 int keyusage,
287 const char *iv,
288 size_t ivlen,
289 char **ivout, size_t * ivoutlen,
290 const char *in, size_t inlen, char **out, size_t * outlen)
292 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
293 ivoutlen, in, inlen, out, outlen,
294 SHISHI_DES_CBC_CRC);
297 static int
298 des_md4_decrypt (Shishi * handle,
299 Shishi_key * key,
300 int keyusage,
301 const char *iv,
302 size_t ivlen,
303 char **ivout, size_t * ivoutlen,
304 const char *in, size_t inlen, char **out, size_t * outlen)
306 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
307 ivoutlen, in, inlen, out, outlen,
308 SHISHI_DES_CBC_MD4);
311 static int
312 des_md5_decrypt (Shishi * handle,
313 Shishi_key * key,
314 int keyusage,
315 const char *iv,
316 size_t ivlen,
317 char **ivout, size_t * ivoutlen,
318 const char *in, size_t inlen, char **out, size_t * outlen)
320 return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
321 ivoutlen, in, inlen, out, outlen,
322 SHISHI_DES_CBC_MD5);
325 static int
326 des_none_decrypt (Shishi * handle,
327 Shishi_key * key,
328 int keyusage,
329 const char *iv,
330 size_t ivlen,
331 char **ivout, size_t * ivoutlen,
332 const char *in, size_t inlen, char **out, size_t * outlen)
334 return simplified_decrypt (handle, key, 0, iv, ivlen, ivout, ivoutlen,
335 in, inlen, out, outlen);
338 static int
339 des_set_odd_key_parity (char key[8])
341 int i, j;
343 for (i = 0; i < 8; i++)
345 int n_set_bits = 0;
347 for (j = 1; j < 8; j++)
348 if (key[i] & (1 << j))
349 n_set_bits++;
351 key[i] &= ~1;
352 if ((n_set_bits % 2) == 0)
353 key[i] |= 1;
356 return SHISHI_OK;
359 static char weak_des_keys[16][8] = {
360 /* Weak keys */
361 "\x01\x01\x01\x01\x01\x01\x01\x01",
362 "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
363 "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
364 "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
365 /* Semiweak keys */
366 "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
367 "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
368 "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
369 "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
370 "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
371 "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
372 "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
373 "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
374 "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
375 "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
376 "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
377 "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
380 static int
381 des_key_correction (Shishi * handle, char key[8])
383 size_t i;
385 /* fixparity(key); */
386 des_set_odd_key_parity (key);
388 /* This loop could be replaced by optimized code (compare nettle),
389 but let's not do that. */
390 for (i = 0; i < 16; i++)
391 if (memcmp (key, weak_des_keys[i], 8) == 0)
393 if (VERBOSECRYPTO (handle))
394 printf ("\t ;; WEAK KEY (corrected)\n");
395 key[7] ^= 0xF0;
396 break;
399 return SHISHI_OK;
402 static int
403 des_random_to_key (Shishi * handle,
404 const char *random, size_t randomlen, Shishi_key * outkey)
406 char tmp[MAX_RANDOM_LEN];
407 int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
409 if (randomlen != shishi_key_length (outkey))
411 shishi_error_printf (handle, "DES random to key caller error");
412 return SHISHI_CRYPTO_ERROR;
415 memcpy (tmp, random, keylen);
416 des_set_odd_key_parity (tmp);
418 shishi_key_value_set (outkey, tmp);
420 return SHISHI_OK;
423 static int
424 des_string_to_key (Shishi * handle,
425 const char *string,
426 size_t stringlen,
427 const char *salt,
428 size_t saltlen, const char *parameter, Shishi_key * outkey)
430 char *s;
431 int n_s;
432 int odd;
433 char tempkey[8];
434 char *p;
435 int i, j;
436 char temp, temp2;
437 int res;
439 if (VERBOSECRYPTO (handle))
441 printf ("des_string_to_key (string, salt)\n");
442 printf ("\t ;; String:\n");
443 escapeprint (string, stringlen);
444 hexprint (string, stringlen);
445 printf ("\t ;; Salt:\n");
446 escapeprint (salt, saltlen);
447 hexprint (salt, saltlen);
448 printf ("odd = 1;\n");
449 printf ("s = string | salt;\n");
450 printf ("tempstring = 0; /* 56-bit string */\n");
451 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
455 odd = 1;
456 n_s = stringlen + saltlen;
457 if ((n_s % 8) != 0)
458 n_s += 8 - n_s % 8;
459 s = (char *) xmalloc (n_s);
460 memcpy (s, string, stringlen);
461 if (saltlen > 0)
462 memcpy (s + stringlen, salt, saltlen);
463 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
464 memset (tempkey, 0, sizeof (tempkey)); /* tempkey = NULL; */
466 if (VERBOSECRYPTO (handle))
468 printf ("\t ;; s = pad(string|salt):\n");
469 escapeprint (s, n_s);
470 hexprint (s, n_s);
473 for (i = 0; i < n_s / 8; i++)
475 if (VERBOSECRYPTO (handle))
477 printf ("for (8byteblock in s) {\n");
478 printf ("\t ;; loop iteration %d\n", i);
479 printf ("\t ;; 8byteblock:\n");
480 escapeprint (&s[i * 8], 8);
481 hexprint (&s[i * 8], 8);
482 binprint (&s[i * 8], 8);
483 printf ("56bitstring = removeMSBits(8byteblock);\n");
486 for (j = 0; j < 8; j++)
487 s[i * 8 + j] = s[i * 8 + j] & ~0x80;
489 if (VERBOSECRYPTO (handle))
491 printf ("\t ;; 56bitstring:\n");
492 bin7print (&s[i * 8], 8);
493 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
496 if (odd == 0)
498 for (j = 0; j < 4; j++)
500 temp = s[i * 8 + j];
501 temp =
502 ((temp >> 6) & 0x01) |
503 ((temp >> 4) & 0x02) |
504 ((temp >> 2) & 0x04) |
505 ((temp) & 0x08) |
506 ((temp << 2) & 0x10) |
507 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
508 temp2 = s[i * 8 + 7 - j];
509 temp2 =
510 ((temp2 >> 6) & 0x01) |
511 ((temp2 >> 4) & 0x02) |
512 ((temp2 >> 2) & 0x04) |
513 ((temp2) & 0x08) |
514 ((temp2 << 2) & 0x10) |
515 ((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
516 s[i * 8 + j] = temp2;
517 s[i * 8 + 7 - j] = temp;
519 if (VERBOSECRYPTO (handle))
521 printf ("reverse(56bitstring)\n");
522 printf ("\t ;; 56bitstring after reverse\n");
523 bin7print (&s[i * 8], 8);
527 odd = !odd;
529 if (VERBOSECRYPTO (handle))
531 printf ("odd = ! odd\n");
532 printf ("tempstring = tempstring XOR 56bitstring;\n");
535 /* tempkey = tempkey XOR 8byteblock; */
536 for (j = 0; j < 8; j++)
537 tempkey[j] ^= s[i * 8 + j];
539 if (VERBOSECRYPTO (handle))
541 printf ("\t ;; tempstring\n");
542 bin7print (tempkey, 8);
546 for (j = 0; j < 8; j++)
547 tempkey[j] = tempkey[j] << 1;
549 if (VERBOSECRYPTO (handle))
551 printf ("for (8byteblock in s) {\n");
552 printf ("}\n");
553 printf ("\t ;; for loop terminated\n");
554 printf ("\t ;; tempstring as 64bitblock\n");
555 hexprint (tempkey, 8);
556 binprint (tempkey, 8);
557 printf ("/* add parity as low bit of each byte */\n");
558 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
561 res = des_key_correction (handle, tempkey);
562 if (res != SHISHI_OK)
563 return res;
565 if (VERBOSECRYPTO (handle))
567 printf ("\t ;; tempkey\n");
568 escapeprint (tempkey, 8);
569 hexprint (tempkey, 8);
570 binprint (tempkey, 8);
571 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
574 memcpy (s, string, stringlen);
575 if (saltlen > 0)
576 memcpy (s + stringlen, salt, saltlen);
577 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
579 res = shishi_des_cbc_mac (handle, tempkey, tempkey, s, n_s, &p);
580 if (res != SHISHI_OK)
581 return res;
582 memcpy (tempkey, p, 8);
583 free (p);
585 res = des_key_correction (handle, tempkey);
586 if (res != SHISHI_OK)
587 return res;
589 if (VERBOSECRYPTO (handle))
591 printf ("\t ;; key\n");
592 escapeprint (tempkey, 8);
593 hexprint (tempkey, 8);
594 binprint (tempkey, 8);
597 shishi_key_value_set (outkey, tempkey);
599 return SHISHI_OK;
602 static int
603 des_checksum (Shishi * handle,
604 Shishi_key * key,
605 int keyusage,
606 int cksumtype,
607 const char *in, size_t inlen,
608 char **out, size_t * outlen, int algo)
610 char cksum[8 + MAX_HASH_LEN];
611 size_t cksumlen;
612 char *keyp;
613 int i;
614 int res;
616 res = raw_des_checksum0 (handle, algo, in, inlen, cksum, &cksumlen);
617 if (res != SHISHI_OK)
619 shishi_error_set (handle, "raw des checksum failed");
620 return res;
623 keyp = shishi_key_value (key);
625 for (i = 0; i < 8; i++)
626 keyp[i] ^= 0xF0;
628 res = simplified_dencrypt (handle, key, NULL, 0, NULL, NULL,
629 cksum, cksumlen, out, outlen, 0);
631 for (i = 0; i < 8; i++)
632 keyp[i] ^= 0xF0;
634 if (res != SHISHI_OK)
636 shishi_error_set (handle, "encrypt failed");
637 return res;
640 return SHISHI_OK;
643 static int
644 des_md4_checksum (Shishi * handle,
645 Shishi_key * key,
646 int keyusage,
647 int cksumtype,
648 const char *in, size_t inlen, char **out, size_t * outlen)
650 return des_checksum (handle, key, keyusage, cksumtype,
651 in, inlen, out, outlen, SHISHI_DES_CBC_MD4);
654 static int
655 des_md5_checksum (Shishi * handle,
656 Shishi_key * key,
657 int keyusage,
658 int cksumtype,
659 const char *in, size_t inlen, char **out, size_t * outlen)
661 return des_checksum (handle, key, keyusage, cksumtype,
662 in, inlen, out, outlen, SHISHI_DES_CBC_MD5);
665 static int
666 gss_des_checksum (Shishi * handle,
667 Shishi_key * key,
668 int keyusage,
669 int cksumtype,
670 const char *in, size_t inlen, char **out, size_t * outlen)
672 char *p;
673 int rc;
675 rc = shishi_md5 (handle, in, inlen, &p);
676 if (rc != SHISHI_OK)
677 return rc;
679 *outlen = 8;
680 rc = shishi_des_cbc_mac (handle, shishi_key_value (key), NULL, p, 16, out);
682 free (p);
684 if (rc != SHISHI_OK)
685 return rc;
687 return SHISHI_OK;
690 static int
691 des_verify (Shishi * handle, int algo,
692 Shishi_key *key,
693 const char *in, size_t inlen,
694 const char *cksum, size_t cksumlen)
696 char *out;
697 size_t outlen;
698 char *md;
699 size_t tmplen;
700 char *tmp;
701 char *keyp;
702 size_t i;
703 int res;
705 if (cksumlen != 8 + 16)
706 return SHISHI_VERIFY_FAILED;
709 * get_mic des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
710 * conf | rsa-md5(conf | msg))
711 * verify_mic decrypt and verify rsa-md5 checksum
714 keyp = shishi_key_value (key);
716 for (i = 0; i < 8; i++)
717 keyp[i] ^= 0xF0;
719 res = simplified_decrypt (handle, key, 0, NULL, 0, NULL, NULL,
720 cksum, cksumlen, &out, &outlen);
722 for (i = 0; i < 8; i++)
723 keyp[i] ^= 0xF0;
725 if (res != SHISHI_OK)
727 shishi_error_set (handle, "decrypt failed");
728 return res;
731 tmplen = 8 + inlen;
732 tmp = xmalloc (tmplen);
733 memcpy (tmp, out, 8);
734 memcpy (tmp + 8, in, inlen);
736 switch (algo)
738 case SHISHI_RSA_MD4_DES:
739 res = shishi_md4 (handle, tmp, tmplen, &md);
740 break;
742 case SHISHI_RSA_MD5_DES:
743 res = shishi_md5 (handle, tmp, tmplen, &md);
744 break;
746 default:
747 res = SHISHI_CRYPTO_ERROR;
750 if (res != SHISHI_OK)
752 shishi_error_printf (handle, "DES verify MD error");
753 return res;
756 if (memcmp (out + 8, md, 16) != 0)
757 return SHISHI_VERIFY_FAILED;
759 return SHISHI_OK;
762 static int
763 des_md4_verify (Shishi * handle,
764 Shishi_key * key,
765 int keyusage,
766 int cksumtype,
767 const char *in, size_t inlen,
768 const char *cksum, size_t cksumlen)
770 return des_verify (handle, SHISHI_RSA_MD4_DES, key,
771 in, inlen, cksum, cksumlen);
774 static int
775 des_md5_verify (Shishi * handle,
776 Shishi_key * key,
777 int keyusage,
778 int cksumtype,
779 const char *in, size_t inlen,
780 const char *cksum, size_t cksumlen)
782 return des_verify (handle, SHISHI_RSA_MD5_DES, key,
783 in, inlen, cksum, cksumlen);