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.
25 raw_des_verify (Shishi
* handle
, int algo
, char *out
, int *outlen
)
27 char md
[MAX_HASH_LEN
];
30 int hlen
= gcry_md_get_algo_dlen (algo
);
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
);
49 shishi_error_printf (handle
, "Libgcrypt failed to compute hash");
50 return SHISHI_GCRYPT_ERROR
;
53 if (VERBOSECRYPTO (handle
))
60 ok
= memcmp (p
, md
, hlen
) == 0;
66 shishi_error_printf (handle
, "DES verify failed");
67 return SHISHI_CRYPTO_ERROR
;
70 memmove (out
, out
+ 8 + hlen
, *outlen
- 8 - hlen
);
77 raw_des_checksum (Shishi
* handle
,
79 const char *in
, size_t inlen
,
80 char *out
, size_t * outlen
,
84 int hlen
= gcry_md_get_algo_dlen (algo
);
85 char buffer
[8 + MAX_HASH_LEN
];
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);
101 memset (buffer
+ 8, 0, hlen
);
104 gcry_md_write (hd
, buffer
, 8 + hlen
);
106 gcry_md_write (hd
, buffer
, 8);
107 gcry_md_write (hd
, in
, inlen
);
109 p
= gcry_md_read (hd
, algo
);
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
);
127 des_encrypt (Shishi
* handle
,
132 const char *in
, size_t inlen
, char **out
, size_t * outlen
,
135 char cksum
[8 + MAX_HASH_LEN
];
138 size_t inpadlen
, padzerolen
= 0, ptlen
, cksumlen
;
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");
156 ptlen
= inpadlen
+ cksumlen
;
157 pt
= xmalloc (ptlen
);
158 memcpy (pt
, cksum
, cksumlen
);
159 memcpy (pt
+ cksumlen
, inpad
, inpadlen
);
163 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
164 pt
, ptlen
, out
, outlen
);
168 if (res
!= SHISHI_OK
)
170 shishi_error_printf (handle
, "DES encrypt failed");
178 des_crc_encrypt (Shishi
* handle
,
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
);
190 des_md4_encrypt (Shishi
* handle
,
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
);
202 des_md5_encrypt (Shishi
* handle
,
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
);
214 des_decrypt (Shishi
* handle
,
217 const char *iv
, size_t ivlen
,
218 const char *in
, size_t inlen
,
219 char **out
, size_t * outlen
,
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");
232 res
= raw_des_verify (handle
, algo
, *out
, outlen
);
233 if (res
!= SHISHI_OK
)
235 shishi_error_printf (handle
, "verify failed");
243 des_crc_decrypt (Shishi
* handle
,
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
);
255 des_md4_decrypt (Shishi
* handle
,
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
);
267 des_md5_decrypt (Shishi
* handle
,
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
);
279 des_none_encrypt (Shishi
* handle
,
284 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
288 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
,
289 in
, inlen
, out
, outlen
);
290 if (res
!= SHISHI_OK
)
297 des_none_decrypt (Shishi
* handle
,
302 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
306 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
,
307 in
, inlen
, out
, outlen
);
308 if (res
!= SHISHI_OK
)
315 des_set_odd_key_parity (char key
[8])
319 for (i
= 0; i
< 8; i
++)
323 for (j
= 1; j
< 8; j
++)
324 if (key
[i
] & (1 << j
))
328 if ((n_set_bits
% 2) == 0)
336 des_key_correction (Shishi
* handle
, char *key
)
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");
367 shishi_error_printf (handle
, "DES setkey failed");
368 shishi_error_set (handle
, gpg_strerror (err
));
369 return SHISHI_GCRYPT_ERROR
;
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
);
398 des_cbc_check (Shishi
* handle
, char key
[8], char *data
, int n_data
)
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
));
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
));
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
));
439 gcry_cipher_close (ch
);
444 des_string_to_key (Shishi
* handle
,
448 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
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
);
468 printf ("\t ;; Salt:\n");
469 escapeprint (salt
, saltlen
);
470 hexprint (salt
, saltlen
);
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");
484 n_s
= stringlen
+ saltlen
;
487 s
= (char *) malloc (n_s
);
488 memcpy (s
, string
, stringlen
);
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
);
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);
512 binprint (&s
[i
* 8], 8);
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);
525 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
530 for (j
= 0; j
< 4; j
++)
534 ((temp
>> 6) & 0x01) |
535 ((temp
>> 4) & 0x02) |
536 ((temp
>> 2) & 0x04) |
538 ((temp
<< 2) & 0x10) |
539 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
540 temp2
= s
[i
* 8 + 7 - j
];
542 ((temp2
>> 6) & 0x01) |
543 ((temp2
>> 4) & 0x02) |
544 ((temp2
>> 2) & 0x04) |
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);
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);
581 for (j
= 0; j
< 8; j
++)
582 tempkey
[j
] = tempkey
[j
] << 1;
584 if (VERBOSECRYPTO (handle
))
586 printf ("for (8byteblock in s) {\n");
588 printf ("\t ;; for loop terminated\n");
589 printf ("\t ;; tempstring as 64bitblock\n");
590 hexprint (tempkey
, 8);
592 binprint (tempkey
, 8);
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
)
602 if (VERBOSECRYPTO (handle
))
604 printf ("\t ;; tempkey\n");
605 escapeprint (tempkey
, 8);
606 hexprint (tempkey
, 8);
608 binprint (tempkey
, 8);
611 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
614 memcpy (s
, string
, stringlen
);
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
)
623 res
= des_key_correction (handle
, tempkey
);
624 if (res
!= SHISHI_OK
)
627 if (VERBOSECRYPTO (handle
))
629 printf ("\t ;; key\n");
630 escapeprint (tempkey
, 8);
631 hexprint (tempkey
, 8);
633 binprint (tempkey
, 8);
638 shishi_key_value_set (outkey
, tempkey
);
644 des_checksum (Shishi
* handle
,
648 char *in
, size_t inlen
, char **out
, size_t * outlen
,
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");
665 keyp
= shishi_key_value (key
);
667 for (i
= 0; i
< 8; i
++)
670 res
= simplified_dencrypt (handle
, key
, NULL
, 0, buffer
, buflen
,
673 for (i
= 0; i
< 8; i
++)
676 if (res
!= SHISHI_OK
)
678 shishi_error_set (handle
, "encrypt failed");
686 des_md4_checksum (Shishi
* handle
,
690 char *in
, size_t inlen
, char **out
, size_t * outlen
)
692 return des_checksum (handle
, key
, keyusage
, cksumtype
,
693 in
, inlen
, out
, outlen
,
698 des_md5_checksum (Shishi
* handle
,
702 char *in
, size_t inlen
, char **out
, size_t * outlen
)
704 return des_checksum (handle
, key
, keyusage
, cksumtype
,
705 in
, inlen
, out
, outlen
,