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.
26 raw_des_verify (Shishi
* handle
, int algo
, char *out
, int *outlen
)
28 char md
[MAX_HASH_LEN
];
31 int hlen
= gcry_md_get_algo_dlen (algo
);
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
);
50 shishi_error_printf (handle
, "Libgcrypt failed to compute hash");
51 return SHISHI_CRYPTO_INTERNAL_ERROR
;
54 if (VERBOSECRYPTO (handle
))
61 ok
= memcmp (p
, md
, hlen
) == 0;
67 shishi_error_printf (handle
, "DES verify failed");
68 return SHISHI_CRYPTO_ERROR
;
71 memmove (out
, out
+ 8 + hlen
, *outlen
- 8 - hlen
);
78 raw_des_checksum (Shishi
* handle
,
80 const char *in
, size_t inlen
,
81 char *out
, size_t * outlen
,
85 int hlen
= gcry_md_get_algo_dlen (algo
);
86 char buffer
[8 + MAX_HASH_LEN
];
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);
102 memset (buffer
+ 8, 0, hlen
);
105 gcry_md_write (hd
, buffer
, 8 + hlen
);
107 gcry_md_write (hd
, buffer
, 8);
108 gcry_md_write (hd
, in
, inlen
);
110 p
= gcry_md_read (hd
, algo
);
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
);
128 _des_encrypt (Shishi
* handle
,
133 const char *in
, size_t inlen
, char **out
, size_t * outlen
,
136 char cksum
[8 + MAX_HASH_LEN
];
139 size_t inpadlen
, padzerolen
= 0, ptlen
, cksumlen
;
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");
157 ptlen
= inpadlen
+ cksumlen
;
158 pt
= xmalloc (ptlen
);
159 memcpy (pt
, cksum
, cksumlen
);
160 memcpy (pt
+ cksumlen
, inpad
, inpadlen
);
164 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
165 pt
, ptlen
, out
, outlen
);
169 if (res
!= SHISHI_OK
)
171 shishi_error_printf (handle
, "DES encrypt failed");
179 des_crc_encrypt (Shishi
* handle
,
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
);
191 des_md4_encrypt (Shishi
* handle
,
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
);
203 des_md5_encrypt (Shishi
* handle
,
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
);
215 _des_decrypt (Shishi
* handle
,
218 const char *iv
, size_t ivlen
,
219 const char *in
, size_t inlen
,
220 char **out
, size_t * outlen
,
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");
233 res
= raw_des_verify (handle
, algo
, *out
, outlen
);
234 if (res
!= SHISHI_OK
)
236 shishi_error_printf (handle
, "verify failed");
244 des_crc_decrypt (Shishi
* handle
,
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
);
256 des_md4_decrypt (Shishi
* handle
,
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
);
268 des_md5_decrypt (Shishi
* handle
,
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
);
280 des_none_encrypt (Shishi
* handle
,
285 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
289 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
290 in
, inlen
, out
, outlen
);
291 if (res
!= SHISHI_OK
)
298 des_none_decrypt (Shishi
* handle
,
303 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
307 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
308 in
, inlen
, out
, outlen
);
309 if (res
!= SHISHI_OK
)
317 des_set_odd_key_parity (char key
[8])
321 for (i
= 0; i
< 8; i
++)
325 for (j
= 1; j
< 8; j
++)
326 if (key
[i
] & (1 << j
))
330 if ((n_set_bits
% 2) == 0)
339 des_key_correction (Shishi
* handle
, char *key
)
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");
370 shishi_error_printf (handle
, "DES setkey failed");
371 shishi_error_set (handle
, gpg_strerror (err
));
372 return SHISHI_CRYPTO_INTERNAL_ERROR
;
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
);
401 des_cbc_check (Shishi
* handle
, char key
[8], char *data
, int n_data
)
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
));
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
));
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
));
442 gcry_cipher_close (ch
);
447 des_string_to_key (Shishi
* handle
,
451 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
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
);
471 printf ("\t ;; Salt:\n");
472 escapeprint (salt
, saltlen
);
473 hexprint (salt
, saltlen
);
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");
487 n_s
= stringlen
+ saltlen
;
490 s
= (char *) malloc (n_s
);
491 memcpy (s
, string
, stringlen
);
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
);
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);
515 binprint (&s
[i
* 8], 8);
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);
528 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
533 for (j
= 0; j
< 4; j
++)
537 ((temp
>> 6) & 0x01) |
538 ((temp
>> 4) & 0x02) |
539 ((temp
>> 2) & 0x04) |
541 ((temp
<< 2) & 0x10) |
542 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
543 temp2
= s
[i
* 8 + 7 - j
];
545 ((temp2
>> 6) & 0x01) |
546 ((temp2
>> 4) & 0x02) |
547 ((temp2
>> 2) & 0x04) |
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);
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);
584 for (j
= 0; j
< 8; j
++)
585 tempkey
[j
] = tempkey
[j
] << 1;
587 if (VERBOSECRYPTO (handle
))
589 printf ("for (8byteblock in s) {\n");
591 printf ("\t ;; for loop terminated\n");
592 printf ("\t ;; tempstring as 64bitblock\n");
593 hexprint (tempkey
, 8);
595 binprint (tempkey
, 8);
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
)
605 if (VERBOSECRYPTO (handle
))
607 printf ("\t ;; tempkey\n");
608 escapeprint (tempkey
, 8);
609 hexprint (tempkey
, 8);
611 binprint (tempkey
, 8);
614 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
617 memcpy (s
, string
, stringlen
);
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
)
626 res
= des_key_correction (handle
, tempkey
);
627 if (res
!= SHISHI_OK
)
630 if (VERBOSECRYPTO (handle
))
632 printf ("\t ;; key\n");
633 escapeprint (tempkey
, 8);
634 hexprint (tempkey
, 8);
636 binprint (tempkey
, 8);
641 shishi_key_value_set (outkey
, tempkey
);
647 des_checksum (Shishi
* handle
,
651 char *in
, size_t inlen
, char **out
, size_t * outlen
,
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");
668 keyp
= shishi_key_value (key
);
670 for (i
= 0; i
< 8; i
++)
673 res
= simplified_dencrypt (handle
, key
, NULL
, 0, buffer
, buflen
,
676 for (i
= 0; i
< 8; i
++)
679 if (res
!= SHISHI_OK
)
681 shishi_error_set (handle
, "encrypt failed");
689 des_md4_checksum (Shishi
* handle
,
693 char *in
, size_t inlen
, char **out
, size_t * outlen
)
695 return des_checksum (handle
, key
, keyusage
, cksumtype
,
696 in
, inlen
, out
, outlen
,
701 des_md5_checksum (Shishi
* handle
,
705 char *in
, size_t inlen
, char **out
, size_t * outlen
)
707 return des_checksum (handle
, key
, keyusage
, cksumtype
,
708 in
, inlen
, out
, outlen
,