Support nettle as well as libgcrypt.
[shishi.git] / lib / crypto-des.c
blob35efc37cd780c43b7da62f27a7fc08ec78632da4
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.
23 #ifdef USE_GCRYPT
25 static int
26 raw_des_verify (Shishi * handle, int algo, char *out, int *outlen)
28 char md[MAX_HASH_LEN];
29 gcry_md_hd_t hd;
30 gpg_error_t err;
31 int hlen = gcry_md_get_algo_dlen (algo);
32 int ok;
33 char *p;
35 memcpy (md, out + 8, hlen);
36 memset (out + 8, 0, hlen);
38 err = gcry_md_open (&hd, algo, 0);
39 if (err != GPG_ERR_NO_ERROR)
41 shishi_error_printf (handle, "Algo %d not available in libgcrypt", algo);
42 return SHISHI_CRYPTO_INTERNAL_ERROR;
45 gcry_md_write (hd, out, *outlen);
47 p = gcry_md_read (hd, algo);
48 if (p == NULL)
50 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
51 return SHISHI_CRYPTO_INTERNAL_ERROR;
54 if (VERBOSECRYPTO (handle))
56 puts("DES verify:");
57 hexprint(md, hlen);
58 hexprint (p, hlen);
61 ok = memcmp (p, md, hlen) == 0;
63 gcry_md_close (hd);
65 if (!ok)
67 shishi_error_printf (handle, "DES verify failed");
68 return SHISHI_CRYPTO_ERROR;
71 memmove (out, out + 8 + hlen, *outlen - 8 - hlen);
72 *outlen -= 8 + hlen;
74 return SHISHI_OK;
77 static int
78 raw_des_checksum (Shishi * handle,
79 int algo,
80 const char *in, size_t inlen,
81 char *out, size_t * outlen,
82 int hashzeros)
84 gpg_error_t err;
85 int hlen = gcry_md_get_algo_dlen (algo);
86 char buffer[8 + MAX_HASH_LEN];
87 char *p;
88 gcry_md_hd_t hd;
89 int res;
91 err = gcry_md_open (&hd, algo, 0);
92 if (err != GPG_ERR_NO_ERROR)
94 shishi_error_printf (handle, "MD %d not available in libgcrypt", algo);
95 return SHISHI_CRYPTO_INTERNAL_ERROR;
98 res = shishi_randomize (handle, buffer, 8);
99 if (res != SHISHI_OK)
100 return res;
102 memset (buffer + 8, 0, hlen);
104 if (hashzeros)
105 gcry_md_write (hd, buffer, 8 + hlen);
106 else
107 gcry_md_write (hd, buffer, 8);
108 gcry_md_write (hd, in, inlen);
110 p = gcry_md_read (hd, algo);
111 if (p == NULL)
113 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
114 return SHISHI_CRYPTO_INTERNAL_ERROR;
117 memcpy(out, buffer, 8);
118 memcpy(out + 8, p, hlen);
120 gcry_md_close (hd);
122 *outlen = 8 + hlen;
124 return SHISHI_OK;
127 static int
128 _des_encrypt (Shishi * handle,
129 Shishi_key * key,
130 int keyusage,
131 const char *iv,
132 size_t ivlen,
133 const char *in, size_t inlen, char **out, size_t * outlen,
134 int algo)
136 char cksum[8 + MAX_HASH_LEN];
137 char *inpad;
138 char *pt;
139 size_t inpadlen, padzerolen = 0, ptlen, cksumlen;
140 int res;
142 if (inlen % 8)
143 padzerolen = 8 - (inlen % 8);
144 inpadlen = inlen + padzerolen;
145 inpad = xmalloc (inpadlen);
147 memcpy (inpad, in, inlen);
148 memset (inpad + inlen, 0, padzerolen);
150 res = raw_des_checksum (handle, algo, inpad, inpadlen, cksum, &cksumlen, 1);
151 if (res != SHISHI_OK)
153 shishi_error_printf (handle, "DES checksum failed");
154 return res;
157 ptlen = inpadlen + cksumlen;
158 pt = xmalloc (ptlen);
159 memcpy (pt, cksum, cksumlen);
160 memcpy (pt + cksumlen, inpad, inpadlen);
162 free (inpad);
164 res = simplified_encrypt (handle, key, 0, iv, ivlen,
165 pt, ptlen, out, outlen);
167 free (pt);
169 if (res != SHISHI_OK)
171 shishi_error_printf (handle, "DES encrypt failed");
172 return res;
175 return SHISHI_OK;
178 static int
179 des_crc_encrypt (Shishi * handle,
180 Shishi_key * key,
181 int keyusage,
182 const char *iv,
183 size_t ivlen,
184 const char *in, size_t inlen, char **out, size_t * outlen)
186 return _des_encrypt (handle, key, keyusage, iv, ivlen,
187 in, inlen, out, outlen, GCRY_MD_CRC32_RFC1510);
190 static int
191 des_md4_encrypt (Shishi * handle,
192 Shishi_key * key,
193 int keyusage,
194 const char *iv,
195 size_t ivlen,
196 const char *in, size_t inlen, char **out, size_t * outlen)
198 return _des_encrypt (handle, key, keyusage, iv, ivlen,
199 in, inlen, out, outlen, GCRY_MD_MD4);
202 static int
203 des_md5_encrypt (Shishi * handle,
204 Shishi_key * key,
205 int keyusage,
206 const char *iv,
207 size_t ivlen,
208 const char *in, size_t inlen, char **out, size_t * outlen)
210 return _des_encrypt (handle, key, keyusage, iv, ivlen,
211 in, inlen, out, outlen, GCRY_MD_MD5);
214 static int
215 _des_decrypt (Shishi * handle,
216 Shishi_key * key,
217 int keyusage,
218 const char *iv, size_t ivlen,
219 const char *in, size_t inlen,
220 char **out, size_t * outlen,
221 int algo)
223 int res;
225 res = simplified_decrypt (handle, key, 0, iv, ivlen,
226 in, inlen, out, outlen);
227 if (res != SHISHI_OK)
229 shishi_error_printf (handle, "decrypt failed");
230 return res;
233 res = raw_des_verify (handle, algo, *out, outlen);
234 if (res != SHISHI_OK)
236 shishi_error_printf (handle, "verify failed");
237 return res;
240 return SHISHI_OK;
243 static int
244 des_crc_decrypt (Shishi * handle,
245 Shishi_key * key,
246 int keyusage,
247 const char *iv,
248 size_t ivlen,
249 const char *in, size_t inlen, char **out, size_t * outlen)
251 return _des_decrypt (handle, key, keyusage, iv, ivlen,
252 in, inlen, out, outlen, GCRY_MD_CRC32_RFC1510);
255 static int
256 des_md4_decrypt (Shishi * handle,
257 Shishi_key * key,
258 int keyusage,
259 const char *iv,
260 size_t ivlen,
261 const char *in, size_t inlen, char **out, size_t * outlen)
263 return _des_decrypt (handle, key, keyusage, iv, ivlen,
264 in, inlen, out, outlen, GCRY_MD_MD4);
267 static int
268 des_md5_decrypt (Shishi * handle,
269 Shishi_key * key,
270 int keyusage,
271 const char *iv,
272 size_t ivlen,
273 const char *in, size_t inlen, char **out, size_t * outlen)
275 return _des_decrypt (handle, key, keyusage, iv, ivlen,
276 in, inlen, out, outlen, GCRY_MD_MD5);
279 static int
280 des_none_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 int res;
289 res = simplified_encrypt (handle, key, 0, iv, ivlen,
290 in, inlen, out, outlen);
291 if (res != SHISHI_OK)
292 return res;
294 return SHISHI_OK;
297 static int
298 des_none_decrypt (Shishi * handle,
299 Shishi_key * key,
300 int keyusage,
301 const char *iv,
302 size_t ivlen,
303 const char *in, size_t inlen, char **out, size_t * outlen)
305 int res;
307 res = simplified_decrypt (handle, key, 0, iv, ivlen,
308 in, inlen, out, outlen);
309 if (res != SHISHI_OK)
310 return res;
312 return SHISHI_OK;
314 #endif
316 static int
317 des_set_odd_key_parity (char key[8])
319 int i, j;
321 for (i = 0; i < 8; i++)
323 int n_set_bits = 0;
325 for (j = 1; j < 8; j++)
326 if (key[i] & (1 << j))
327 n_set_bits++;
329 key[i] &= ~1;
330 if ((n_set_bits % 2) == 0)
331 key[i] |= 1;
334 return SHISHI_OK;
337 #ifdef USE_GCRYPT
338 static int
339 des_key_correction (Shishi * handle, char *key)
341 gcry_cipher_hd_t ch;
342 gpg_error_t err;
344 /* fixparity(key); */
345 des_set_odd_key_parity (key);
347 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
348 if (err != GPG_ERR_NO_ERROR)
350 shishi_error_printf (handle, "DES-CBC not available in libgcrypt");
351 return SHISHI_CRYPTO_INTERNAL_ERROR;
354 /* XXX? libgcrypt tests for pseudo-weak keys, rfc 1510 doesn't */
356 err = gcry_cipher_setkey (ch, key, 8);
358 gcry_cipher_close (ch);
360 if (err != GPG_ERR_NO_ERROR)
362 if (gpg_err_code (err) == GPG_ERR_WEAK_KEY)
364 if (VERBOSECRYPTO (handle))
365 printf ("\t ;; WEAK KEY (corrected)\n");
366 key[7] ^= 0xF0;
368 else
370 shishi_error_printf (handle, "DES setkey failed");
371 shishi_error_set (handle, gpg_strerror (err));
372 return SHISHI_CRYPTO_INTERNAL_ERROR;
376 return SHISHI_OK;
379 static int
380 des_random_to_key (Shishi * handle,
381 const char *random, size_t randomlen, Shishi_key * outkey)
383 char tmp[MAX_RANDOM_LEN];
384 int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
386 if (randomlen != shishi_key_length (outkey))
388 shishi_error_printf (handle, "DES random to key caller error");
389 return SHISHI_CRYPTO_ERROR;
392 memcpy (tmp, random, keylen);
393 des_set_odd_key_parity (tmp);
395 shishi_key_value_set (outkey, tmp);
397 return SHISHI_OK;
400 static int
401 des_cbc_check (Shishi * handle, char key[8], char *data, int n_data)
403 gcry_cipher_hd_t ch;
404 gpg_error_t err;
405 int res = SHISHI_CRYPTO_INTERNAL_ERROR;
407 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES,
408 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
409 if (err != GPG_ERR_NO_ERROR)
411 shishi_error_printf (handle, "DES-CBC-MAC not available in libgcrypt");
412 return SHISHI_CRYPTO_INTERNAL_ERROR;
415 err = gcry_cipher_setkey (ch, key, 8);
416 if (err != GPG_ERR_NO_ERROR)
418 shishi_error_printf (handle, "DES setkey failed");
419 shishi_error_set (handle, gpg_strerror (err));
420 goto done;
423 err = gcry_cipher_setiv (ch, key, 8);
424 if (err != GPG_ERR_NO_ERROR)
426 shishi_error_printf (handle, "DES setiv failed");
427 shishi_error_set (handle, gpg_strerror (err));
428 goto done;
431 err = gcry_cipher_encrypt (ch, key, 8, data, n_data);
432 if (err != GPG_ERR_NO_ERROR)
434 shishi_error_printf (handle, "DES encrypt failed");
435 shishi_error_set (handle, gpg_strerror (err));
436 goto done;
439 return SHISHI_OK;
441 done:
442 gcry_cipher_close (ch);
443 return res;
446 static int
447 des_string_to_key (Shishi * handle,
448 const char *string,
449 size_t stringlen,
450 const char *salt,
451 size_t saltlen, const char *parameter, Shishi_key * outkey)
453 char *s;
454 int n_s;
455 int odd;
456 char tempkey[8];
457 int i, j;
458 char temp, temp2;
459 int res;
461 if (VERBOSECRYPTO (handle))
463 printf ("des_string_to_key (string, salt)\n");
465 printf ("\t ;; String:\n");
466 escapeprint (string, stringlen);
467 hexprint (string, stringlen);
468 puts ("");
469 puts ("");
471 printf ("\t ;; Salt:\n");
472 escapeprint (salt, saltlen);
473 hexprint (salt, saltlen);
474 puts ("");
476 printf ("odd = 1;\n");
477 printf ("s = string | salt;\n");
478 printf ("tempstring = 0; /* 56-bit string */\n");
479 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
483 if (saltlen < 0)
484 saltlen = 0;
486 odd = 1;
487 n_s = stringlen + saltlen;
488 if ((n_s % 8) != 0)
489 n_s += 8 - n_s % 8;
490 s = (char *) malloc (n_s);
491 memcpy (s, string, stringlen);
492 if (saltlen > 0)
493 memcpy (s + stringlen, salt, saltlen);
494 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
495 memset (tempkey, 0, sizeof (tempkey)); /* tempkey = NULL; */
497 if (VERBOSECRYPTO (handle))
499 printf ("\t ;; s = pad(string|salt):\n");
500 escapeprint (s, n_s);
501 hexprint (s, n_s);
502 puts ("");
505 for (i = 0; i < n_s / 8; i++)
507 if (VERBOSECRYPTO (handle))
509 printf ("for (8byteblock in s) {\n");
510 printf ("\t ;; loop iteration %d\n", i);
511 printf ("\t ;; 8byteblock:\n");
512 escapeprint (&s[i * 8], 8);
513 hexprint (&s[i * 8], 8);
514 puts ("");
515 binprint (&s[i * 8], 8);
516 puts ("");
517 printf ("56bitstring = removeMSBits(8byteblock);\n");
520 for (j = 0; j < 8; j++)
521 s[i * 8 + j] = s[i * 8 + j] & ~0x80;
523 if (VERBOSECRYPTO (handle))
525 printf ("\t ;; 56bitstring:\n");
526 bin7print (&s[i * 8], 8);
527 puts ("");
528 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
531 if (odd == 0)
533 for (j = 0; j < 4; j++)
535 temp = s[i * 8 + j];
536 temp =
537 ((temp >> 6) & 0x01) |
538 ((temp >> 4) & 0x02) |
539 ((temp >> 2) & 0x04) |
540 ((temp) & 0x08) |
541 ((temp << 2) & 0x10) |
542 ((temp << 4) & 0x20) | ((temp << 6) & 0x40);
543 temp2 = s[i * 8 + 7 - j];
544 temp2 =
545 ((temp2 >> 6) & 0x01) |
546 ((temp2 >> 4) & 0x02) |
547 ((temp2 >> 2) & 0x04) |
548 ((temp2) & 0x08) |
549 ((temp2 << 2) & 0x10) |
550 ((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
551 s[i * 8 + j] = temp2;
552 s[i * 8 + 7 - j] = temp;
554 if (VERBOSECRYPTO (handle))
556 printf ("reverse(56bitstring)\n");
557 printf ("\t ;; 56bitstring after reverse\n");
558 bin7print (&s[i * 8], 8);
559 puts ("");
563 odd = !odd;
565 if (VERBOSECRYPTO (handle))
567 printf ("odd = ! odd\n");
568 printf ("tempstring = tempstring XOR 56bitstring;\n");
571 /* tempkey = tempkey XOR 8byteblock; */
572 for (j = 0; j < 8; j++)
573 tempkey[j] ^= s[i * 8 + j];
575 if (VERBOSECRYPTO (handle))
577 printf ("\t ;; tempstring\n");
578 bin7print (tempkey, 8);
579 puts ("");
580 puts ("");
584 for (j = 0; j < 8; j++)
585 tempkey[j] = tempkey[j] << 1;
587 if (VERBOSECRYPTO (handle))
589 printf ("for (8byteblock in s) {\n");
590 printf ("}\n");
591 printf ("\t ;; for loop terminated\n");
592 printf ("\t ;; tempstring as 64bitblock\n");
593 hexprint (tempkey, 8);
594 puts ("");
595 binprint (tempkey, 8);
596 puts ("");
597 printf ("/* add parity as low bit of each byte */\n");
598 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
601 res = des_key_correction (handle, tempkey);
602 if (res != SHISHI_OK)
603 return res;
605 if (VERBOSECRYPTO (handle))
607 printf ("\t ;; tempkey\n");
608 escapeprint (tempkey, 8);
609 hexprint (tempkey, 8);
610 puts ("");
611 binprint (tempkey, 8);
612 puts ("");
613 puts ("");
614 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
617 memcpy (s, string, stringlen);
618 if (saltlen > 0)
619 memcpy (s + stringlen, salt, saltlen);
620 memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
622 res = des_cbc_check (handle, tempkey, s, n_s);
623 if (res != SHISHI_OK)
624 return res;
626 res = des_key_correction (handle, tempkey);
627 if (res != SHISHI_OK)
628 return res;
630 if (VERBOSECRYPTO (handle))
632 printf ("\t ;; key\n");
633 escapeprint (tempkey, 8);
634 hexprint (tempkey, 8);
635 puts ("");
636 binprint (tempkey, 8);
637 puts ("");
638 puts ("");
641 shishi_key_value_set (outkey, tempkey);
643 return SHISHI_OK;
646 static int
647 des_checksum (Shishi * handle,
648 Shishi_key * key,
649 int keyusage,
650 int cksumtype,
651 char *in, size_t inlen, char **out, size_t * outlen,
652 int algo)
654 char buffer[BUFSIZ];
655 int buflen;
656 char *keyp;
657 int i;
658 int res;
660 buflen = sizeof (buffer);
661 res = raw_des_checksum (handle, algo, in, inlen, buffer, &buflen, 0);
662 if (res != SHISHI_OK)
664 shishi_error_set (handle, "checksum failed");
665 return res;
668 keyp = shishi_key_value (key);
670 for (i = 0; i < 8; i++)
671 keyp[i] ^= 0xF0;
673 res = simplified_dencrypt (handle, key, NULL, 0, buffer, buflen,
674 out, outlen, 0);
676 for (i = 0; i < 8; i++)
677 keyp[i] ^= 0xF0;
679 if (res != SHISHI_OK)
681 shishi_error_set (handle, "encrypt failed");
682 return res;
685 return SHISHI_OK;
688 static int
689 des_md4_checksum (Shishi * handle,
690 Shishi_key * key,
691 int keyusage,
692 int cksumtype,
693 char *in, size_t inlen, char **out, size_t * outlen)
695 return des_checksum (handle, key, keyusage, cksumtype,
696 in, inlen, out, outlen,
697 GCRY_MD_MD4);
700 static int
701 des_md5_checksum (Shishi * handle,
702 Shishi_key * key,
703 int keyusage,
704 int cksumtype,
705 char *in, size_t inlen, char **out, size_t * outlen)
707 return des_checksum (handle, key, keyusage, cksumtype,
708 in, inlen, out, outlen,
709 GCRY_MD_MD5);
711 #endif