Fix.
[shishi.git] / lib / crypto-des.c
blob52165f73952ff45a460c50ade90f917ff9814898
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 char md[MAX_HASH_LEN];
28 gcry_md_hd_t hd;
29 gpg_error_t err;
30 int hlen = gcry_md_get_algo_dlen (algo);
31 int ok;
32 char *p;
34 memcpy (md, out + 8, hlen);
35 memset (out + 8, 0, hlen);
37 err = gcry_md_open (&hd, algo, 0);
38 if (err != GPG_ERR_NO_ERROR)
40 shishi_error_printf (handle, "Algo %d not available in libgcrypt", algo);
41 return SHISHI_GCRYPT_ERROR;
44 gcry_md_write (hd, out, *outlen);
46 p = gcry_md_read (hd, algo);
47 if (p == NULL)
49 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
50 return SHISHI_GCRYPT_ERROR;
53 if (VERBOSECRYPTO (handle))
55 puts("DES verify:");
56 hexprint(md, hlen);
57 hexprint (p, hlen);
60 ok = memcmp (p, md, hlen) == 0;
62 gcry_md_close (hd);
64 if (!ok)
66 shishi_error_printf (handle, "DES verify failed");
67 return SHISHI_CRYPTO_ERROR;
70 memmove (out, out + 8 + hlen, *outlen - 8 - hlen);
71 *outlen -= 8 + hlen;
73 return SHISHI_OK;
76 static int
77 raw_des_checksum (Shishi * handle,
78 int algo,
79 const char *in, size_t inlen,
80 char *out, size_t * outlen,
81 int hashzeros)
83 gpg_error_t err;
84 int hlen = gcry_md_get_algo_dlen (algo);
85 char buffer[8 + MAX_HASH_LEN];
86 char *p;
87 gcry_md_hd_t hd;
88 int res;
90 err = gcry_md_open (&hd, algo, 0);
91 if (err != GPG_ERR_NO_ERROR)
93 shishi_error_printf (handle, "MD %d not available in libgcrypt", algo);
94 return SHISHI_GCRYPT_ERROR;
97 res = shishi_randomize (handle, buffer, 8);
98 if (res != SHISHI_OK)
99 return res;
101 memset (buffer + 8, 0, hlen);
103 if (hashzeros)
104 gcry_md_write (hd, buffer, 8 + hlen);
105 else
106 gcry_md_write (hd, buffer, 8);
107 gcry_md_write (hd, in, inlen);
109 p = gcry_md_read (hd, algo);
110 if (p == NULL)
112 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
113 return SHISHI_GCRYPT_ERROR;
116 memcpy(out, buffer, 8);
117 memcpy(out + 8, p, hlen);
119 gcry_md_close (hd);
121 *outlen = 8 + hlen;
123 return SHISHI_OK;
126 static int
127 des_encrypt (Shishi * handle,
128 Shishi_key * key,
129 int keyusage,
130 const char *iv,
131 size_t ivlen,
132 const char *in, size_t inlen, char **out, size_t * outlen,
133 int algo)
135 char cksum[8 + MAX_HASH_LEN];
136 char *inpad;
137 char *pt;
138 size_t inpadlen, padzerolen = 0, ptlen, cksumlen;
139 int res;
141 if (inlen % 8)
142 padzerolen = 8 - (inlen % 8);
143 inpadlen = inlen + padzerolen;
144 inpad = xmalloc (inpadlen);
146 memcpy (inpad, in, inlen);
147 memset (inpad + inlen, 0, padzerolen);
149 res = raw_des_checksum (handle, algo, inpad, inpadlen, cksum, &cksumlen, 1);
150 if (res != SHISHI_OK)
152 shishi_error_printf (handle, "DES checksum failed");
153 return res;
156 ptlen = inpadlen + cksumlen;
157 pt = xmalloc (ptlen);
158 memcpy (pt, cksum, cksumlen);
159 memcpy (pt + cksumlen, inpad, inpadlen);
161 free (inpad);
163 res = simplified_encrypt (handle, key, 0, iv, ivlen,
164 pt, ptlen, out, outlen);
166 free (pt);
168 if (res != SHISHI_OK)
170 shishi_error_printf (handle, "DES encrypt failed");
171 return res;
174 return SHISHI_OK;
177 static int
178 des_crc_encrypt (Shishi * handle,
179 Shishi_key * key,
180 int keyusage,
181 const char *iv,
182 size_t ivlen,
183 const char *in, size_t inlen, char **out, size_t * outlen)
185 return des_encrypt (handle, key, keyusage, iv, ivlen,
186 in, inlen, out, outlen, GCRY_MD_CRC32_RFC1510);
189 static int
190 des_md4_encrypt (Shishi * handle,
191 Shishi_key * key,
192 int keyusage,
193 const char *iv,
194 size_t ivlen,
195 const char *in, size_t inlen, char **out, size_t * outlen)
197 return des_encrypt (handle, key, keyusage, iv, ivlen,
198 in, inlen, out, outlen, GCRY_MD_MD4);
201 static int
202 des_md5_encrypt (Shishi * handle,
203 Shishi_key * key,
204 int keyusage,
205 const char *iv,
206 size_t ivlen,
207 const char *in, size_t inlen, char **out, size_t * outlen)
209 return des_encrypt (handle, key, keyusage, iv, ivlen,
210 in, inlen, out, outlen, GCRY_MD_MD5);
213 static int
214 des_decrypt (Shishi * handle,
215 Shishi_key * key,
216 int keyusage,
217 const char *iv, size_t ivlen,
218 const char *in, size_t inlen,
219 char **out, size_t * outlen,
220 int algo)
222 int res;
224 res = simplified_decrypt (handle, key, 0, iv, ivlen,
225 in, inlen, out, outlen);
226 if (res != SHISHI_OK)
228 shishi_error_printf (handle, "decrypt failed");
229 return res;
232 res = raw_des_verify (handle, algo, *out, outlen);
233 if (res != SHISHI_OK)
235 shishi_error_printf (handle, "verify failed");
236 return res;
239 return SHISHI_OK;
242 static int
243 des_crc_decrypt (Shishi * handle,
244 Shishi_key * key,
245 int keyusage,
246 const char *iv,
247 size_t ivlen,
248 const char *in, size_t inlen, char **out, size_t * outlen)
250 return des_decrypt (handle, key, keyusage, iv, ivlen,
251 in, inlen, out, outlen, GCRY_MD_CRC32_RFC1510);
254 static int
255 des_md4_decrypt (Shishi * handle,
256 Shishi_key * key,
257 int keyusage,
258 const char *iv,
259 size_t ivlen,
260 const char *in, size_t inlen, char **out, size_t * outlen)
262 return des_decrypt (handle, key, keyusage, iv, ivlen,
263 in, inlen, out, outlen, GCRY_MD_MD4);
266 static int
267 des_md5_decrypt (Shishi * handle,
268 Shishi_key * key,
269 int keyusage,
270 const char *iv,
271 size_t ivlen,
272 const char *in, size_t inlen, char **out, size_t * outlen)
274 return des_decrypt (handle, key, keyusage, iv, ivlen,
275 in, inlen, out, outlen, GCRY_MD_MD5);
278 static int
279 des_none_encrypt (Shishi * handle,
280 Shishi_key * key,
281 int keyusage,
282 const char *iv,
283 size_t ivlen,
284 const char *in, size_t inlen, char **out, size_t * outlen)
286 int res;
288 res = simplified_encrypt (handle, key, 0, iv, ivlen,
289 in, inlen, out, outlen);
290 if (res != SHISHI_OK)
291 return res;
293 return SHISHI_OK;
296 static int
297 des_none_decrypt (Shishi * handle,
298 Shishi_key * key,
299 int keyusage,
300 const char *iv,
301 size_t ivlen,
302 const char *in, size_t inlen, char **out, size_t * outlen)
304 int res;
306 res = simplified_decrypt (handle, key, 0, iv, ivlen,
307 in, inlen, out, outlen);
308 if (res != SHISHI_OK)
309 return res;
311 return SHISHI_OK;
314 static int
315 des_set_odd_key_parity (char key[8])
317 int i, j;
319 for (i = 0; i < 8; i++)
321 int n_set_bits = 0;
323 for (j = 1; j < 8; j++)
324 if (key[i] & (1 << j))
325 n_set_bits++;
327 key[i] &= ~1;
328 if ((n_set_bits % 2) == 0)
329 key[i] |= 1;
332 return SHISHI_OK;
335 static int
336 des_key_correction (Shishi * handle, char *key)
338 gcry_cipher_hd_t ch;
339 gpg_error_t err;
341 /* fixparity(key); */
342 des_set_odd_key_parity (key);
344 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
345 if (err != GPG_ERR_NO_ERROR)
347 shishi_error_printf (handle, "DES-CBC not available in libgcrypt");
348 return SHISHI_GCRYPT_ERROR;
351 /* XXX? libgcrypt tests for pseudo-weak keys, rfc 1510 doesn't */
353 err = gcry_cipher_setkey (ch, key, 8);
355 gcry_cipher_close (ch);
357 if (err != GPG_ERR_NO_ERROR)
359 if (gpg_err_code (err) == GPG_ERR_WEAK_KEY)
361 if (VERBOSECRYPTO (handle))
362 printf ("\t ;; WEAK KEY (corrected)\n");
363 key[7] ^= 0xF0;
365 else
367 shishi_error_printf (handle, "DES setkey failed");
368 shishi_error_set (handle, gpg_strerror (err));
369 return SHISHI_GCRYPT_ERROR;
373 return SHISHI_OK;
376 static int
377 des_random_to_key (Shishi * handle,
378 const char *random, size_t randomlen, Shishi_key * outkey)
380 char tmp[MAX_RANDOM_LEN];
381 int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
383 if (randomlen != shishi_key_length (outkey))
385 shishi_error_printf (handle, "DES random to key caller error");
386 return SHISHI_CRYPTO_ERROR;
389 memcpy (tmp, random, keylen);
390 des_set_odd_key_parity (tmp);
392 shishi_key_value_set (outkey, tmp);
394 return SHISHI_OK;
397 static int
398 des_cbc_check (Shishi * handle, char key[8], char *data, int n_data)
400 gcry_cipher_hd_t ch;
401 gpg_error_t err;
402 int res = SHISHI_GCRYPT_ERROR;
404 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES,
405 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
406 if (err != GPG_ERR_NO_ERROR)
408 shishi_error_printf (handle, "DES-CBC-MAC not available in libgcrypt");
409 return SHISHI_GCRYPT_ERROR;
412 err = gcry_cipher_setkey (ch, key, 8);
413 if (err != GPG_ERR_NO_ERROR)
415 shishi_error_printf (handle, "DES setkey failed");
416 shishi_error_set (handle, gpg_strerror (err));
417 goto done;
420 err = gcry_cipher_setiv (ch, key, 8);
421 if (err != GPG_ERR_NO_ERROR)
423 shishi_error_printf (handle, "DES setiv failed");
424 shishi_error_set (handle, gpg_strerror (err));
425 goto done;
428 err = gcry_cipher_encrypt (ch, key, 8, data, n_data);
429 if (err != GPG_ERR_NO_ERROR)
431 shishi_error_printf (handle, "DES encrypt failed");
432 shishi_error_set (handle, gpg_strerror (err));
433 goto done;
436 return SHISHI_OK;
438 done:
439 gcry_cipher_close (ch);
440 return res;
443 static int
444 des_string_to_key (Shishi * handle,
445 const char *string,
446 size_t stringlen,
447 const char *salt,
448 size_t saltlen, const char *parameter, Shishi_key * outkey)
450 char *s;
451 int n_s;
452 int odd;
453 char tempkey[8];
454 int i, j;
455 char temp, temp2;
456 int res;
458 if (VERBOSECRYPTO (handle))
460 printf ("des_string_to_key (string, salt)\n");
462 printf ("\t ;; String:\n");
463 escapeprint (string, stringlen);
464 hexprint (string, stringlen);
465 puts ("");
466 puts ("");
468 printf ("\t ;; Salt:\n");
469 escapeprint (salt, saltlen);
470 hexprint (salt, saltlen);
471 puts ("");
473 printf ("odd = 1;\n");
474 printf ("s = string | salt;\n");
475 printf ("tempstring = 0; /* 56-bit string */\n");
476 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
480 if (saltlen < 0)
481 saltlen = 0;
483 odd = 1;
484 n_s = stringlen + saltlen;
485 if ((n_s % 8) != 0)
486 n_s += 8 - n_s % 8;
487 s = (char *) malloc (n_s);
488 memcpy (s, string, stringlen);
489 if (saltlen > 0)
490 memcpy (s + stringlen, salt, saltlen);
491 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
492 memset (tempkey, 0, sizeof (tempkey)); /* tempkey = NULL; */
494 if (VERBOSECRYPTO (handle))
496 printf ("\t ;; s = pad(string|salt):\n");
497 escapeprint (s, n_s);
498 hexprint (s, n_s);
499 puts ("");
502 for (i = 0; i < n_s / 8; i++)
504 if (VERBOSECRYPTO (handle))
506 printf ("for (8byteblock in s) {\n");
507 printf ("\t ;; loop iteration %d\n", i);
508 printf ("\t ;; 8byteblock:\n");
509 escapeprint (&s[i * 8], 8);
510 hexprint (&s[i * 8], 8);
511 puts ("");
512 binprint (&s[i * 8], 8);
513 puts ("");
514 printf ("56bitstring = removeMSBits(8byteblock);\n");
517 for (j = 0; j < 8; j++)
518 s[i * 8 + j] = s[i * 8 + j] & ~0x80;
520 if (VERBOSECRYPTO (handle))
522 printf ("\t ;; 56bitstring:\n");
523 bin7print (&s[i * 8], 8);
524 puts ("");
525 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
528 if (odd == 0)
530 for (j = 0; j < 4; j++)
532 temp = s[i * 8 + j];
533 temp =
534 ((temp >> 6) & 0x01) |
535 ((temp >> 4) & 0x02) |
536 ((temp >> 2) & 0x04) |
537 ((temp) & 0x08) |
538 ((temp << 2) & 0x10) |
539 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
540 temp2 = s[i * 8 + 7 - j];
541 temp2 =
542 ((temp2 >> 6) & 0x01) |
543 ((temp2 >> 4) & 0x02) |
544 ((temp2 >> 2) & 0x04) |
545 ((temp2) & 0x08) |
546 ((temp2 << 2) & 0x10) |
547 ((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
548 s[i * 8 + j] = temp2;
549 s[i * 8 + 7 - j] = temp;
551 if (VERBOSECRYPTO (handle))
553 printf ("reverse(56bitstring)\n");
554 printf ("\t ;; 56bitstring after reverse\n");
555 bin7print (&s[i * 8], 8);
556 puts ("");
560 odd = !odd;
562 if (VERBOSECRYPTO (handle))
564 printf ("odd = ! odd\n");
565 printf ("tempstring = tempstring XOR 56bitstring;\n");
568 /* tempkey = tempkey XOR 8byteblock; */
569 for (j = 0; j < 8; j++)
570 tempkey[j] ^= s[i * 8 + j];
572 if (VERBOSECRYPTO (handle))
574 printf ("\t ;; tempstring\n");
575 bin7print (tempkey, 8);
576 puts ("");
577 puts ("");
581 for (j = 0; j < 8; j++)
582 tempkey[j] = tempkey[j] << 1;
584 if (VERBOSECRYPTO (handle))
586 printf ("for (8byteblock in s) {\n");
587 printf ("}\n");
588 printf ("\t ;; for loop terminated\n");
589 printf ("\t ;; tempstring as 64bitblock\n");
590 hexprint (tempkey, 8);
591 puts ("");
592 binprint (tempkey, 8);
593 puts ("");
594 printf ("/* add parity as low bit of each byte */\n");
595 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
598 res = des_key_correction (handle, tempkey);
599 if (res != SHISHI_OK)
600 return res;
602 if (VERBOSECRYPTO (handle))
604 printf ("\t ;; tempkey\n");
605 escapeprint (tempkey, 8);
606 hexprint (tempkey, 8);
607 puts ("");
608 binprint (tempkey, 8);
609 puts ("");
610 puts ("");
611 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
614 memcpy (s, string, stringlen);
615 if (saltlen > 0)
616 memcpy (s + stringlen, salt, saltlen);
617 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
619 res = des_cbc_check (handle, tempkey, s, n_s);
620 if (res != SHISHI_OK)
621 return res;
623 res = des_key_correction (handle, tempkey);
624 if (res != SHISHI_OK)
625 return res;
627 if (VERBOSECRYPTO (handle))
629 printf ("\t ;; key\n");
630 escapeprint (tempkey, 8);
631 hexprint (tempkey, 8);
632 puts ("");
633 binprint (tempkey, 8);
634 puts ("");
635 puts ("");
638 shishi_key_value_set (outkey, tempkey);
640 return SHISHI_OK;
643 static int
644 des_checksum (Shishi * handle,
645 Shishi_key * key,
646 int keyusage,
647 int cksumtype,
648 char *in, size_t inlen, char **out, size_t * outlen,
649 int algo)
651 char buffer[BUFSIZ];
652 int buflen;
653 char *keyp;
654 int i;
655 int res;
657 buflen = sizeof (buffer);
658 res = raw_des_checksum (handle, algo, in, inlen, buffer, &buflen, 0);
659 if (res != SHISHI_OK)
661 shishi_error_set (handle, "checksum failed");
662 return res;
665 keyp = shishi_key_value (key);
667 for (i = 0; i < 8; i++)
668 keyp[i] ^= 0xF0;
670 res = simplified_dencrypt (handle, key, NULL, 0, buffer, buflen,
671 out, outlen, 0);
673 for (i = 0; i < 8; i++)
674 keyp[i] ^= 0xF0;
676 if (res != SHISHI_OK)
678 shishi_error_set (handle, "encrypt failed");
679 return res;
682 return SHISHI_OK;
685 static int
686 des_md4_checksum (Shishi * handle,
687 Shishi_key * key,
688 int keyusage,
689 int cksumtype,
690 char *in, size_t inlen, char **out, size_t * outlen)
692 return des_checksum (handle, key, keyusage, cksumtype,
693 in, inlen, out, outlen,
694 GCRY_MD_MD4);
697 static int
698 des_md5_checksum (Shishi * handle,
699 Shishi_key * key,
700 int keyusage,
701 int cksumtype,
702 char *in, size_t inlen, char **out, size_t * outlen)
704 return des_checksum (handle, key, keyusage, cksumtype,
705 in, inlen, out, outlen,
706 GCRY_MD_MD5);