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_checksum0 (Shishi
* handle
, int algo
,
26 const char *in
, size_t inlen
,
27 char *out
, size_t * outlen
)
36 rc
= shishi_randomize (handle
, out
, blen
);
40 tmplen
= blen
+ inlen
;
41 tmp
= xmalloc (tmplen
);
43 memcpy (tmp
, out
, blen
);
44 memcpy (tmp
+ blen
, in
, inlen
);
48 case SHISHI_DES_CBC_MD4
:
49 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
);
52 case SHISHI_DES_CBC_MD5
:
53 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
);
57 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
58 return SHISHI_CRYPTO_INTERNAL_ERROR
;
62 memcpy (out
+ blen
, p
, hlen
);
64 *outlen
= blen
+ hlen
;
70 raw_des_checksum1 (Shishi
* handle
, int algo
,
71 const char *in
, size_t inlen
,
72 char *out
, size_t * outlen
)
81 rc
= shishi_randomize (handle
, out
, blen
);
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
);
95 case SHISHI_DES_CBC_MD4
:
96 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
);
99 case SHISHI_DES_CBC_MD5
:
100 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
);
104 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
105 return SHISHI_CRYPTO_INTERNAL_ERROR
;
109 memcpy (out
+ blen
, p
, hlen
);
111 *outlen
= blen
+ hlen
;
117 des_encrypt_checksum (Shishi
* handle
,
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
];
128 size_t inpadlen
, padzerolen
= 0, ptlen
, cksumlen
;
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");
146 ptlen
= inpadlen
+ cksumlen
;
147 pt
= xmalloc (ptlen
);
148 memcpy (pt
, cksum
, cksumlen
);
149 memcpy (pt
+ cksumlen
, inpad
, inpadlen
);
153 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
154 pt
, ptlen
, out
, outlen
);
158 if (res
!= SHISHI_OK
)
160 shishi_error_printf (handle
, "DES encrypt failed");
168 des_crc_encrypt (Shishi
* handle
,
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
,
181 des_md4_encrypt (Shishi
* handle
,
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
,
195 des_md5_encrypt (Shishi
* handle
,
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
,
209 des_none_encrypt (Shishi
* handle
,
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
);
222 des_decrypt_verify (Shishi
* handle
,
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
)
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");
243 memcpy (incoming
, *out
+ 8, hlen
);
244 memset (*out
+ 8, 0, hlen
);
248 case SHISHI_DES_CBC_MD4
:
249 shishi_md4 (handle
, *out
, *outlen
, &computed
);
252 case SHISHI_DES_CBC_MD5
:
253 shishi_md5 (handle
, *out
, *outlen
, &computed
);
257 shishi_error_printf (handle
, "MD %d unknown in raw des verify", algo
);
258 return SHISHI_CRYPTO_ERROR
;
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
;
277 memmove (*out
, *out
+ 8 + hlen
, *outlen
- 8 - hlen
);
284 des_crc_decrypt (Shishi
* handle
,
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
,
298 des_md4_decrypt (Shishi
* handle
,
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
,
312 des_md5_decrypt (Shishi
* handle
,
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
,
326 des_none_decrypt (Shishi
* handle
,
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
);
339 des_set_odd_key_parity (char key
[8])
343 for (i
= 0; i
< 8; i
++)
347 for (j
= 1; j
< 8; j
++)
348 if (key
[i
] & (1 << j
))
352 if ((n_set_bits
% 2) == 0)
359 static char weak_des_keys
[16][8] = {
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",
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"
381 des_key_correction (Shishi
* handle
, char key
[8])
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");
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
);
424 des_string_to_key (Shishi
* handle
,
428 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
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");
456 n_s
= stringlen
+ saltlen
;
459 s
= (char *) xmalloc (n_s
);
460 memcpy (s
, string
, stringlen
);
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
);
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
);
498 for (j
= 0; j
< 4; j
++)
502 ((temp
>> 6) & 0x01) |
503 ((temp
>> 4) & 0x02) |
504 ((temp
>> 2) & 0x04) |
506 ((temp
<< 2) & 0x10) |
507 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
508 temp2
= s
[i
* 8 + 7 - j
];
510 ((temp2
>> 6) & 0x01) |
511 ((temp2
>> 4) & 0x02) |
512 ((temp2
>> 2) & 0x04) |
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);
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");
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
)
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
);
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
)
582 memcpy (tempkey
, p
, 8);
585 res
= des_key_correction (handle
, tempkey
);
586 if (res
!= SHISHI_OK
)
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
);
603 des_checksum (Shishi
* handle
,
607 const char *in
, size_t inlen
,
608 char **out
, size_t * outlen
, int algo
)
610 char cksum
[8 + MAX_HASH_LEN
];
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");
623 keyp
= shishi_key_value (key
);
625 for (i
= 0; i
< 8; i
++)
628 res
= simplified_dencrypt (handle
, key
, NULL
, 0, NULL
, NULL
,
629 cksum
, cksumlen
, out
, outlen
, 0);
631 for (i
= 0; i
< 8; i
++)
634 if (res
!= SHISHI_OK
)
636 shishi_error_set (handle
, "encrypt failed");
644 des_md4_checksum (Shishi
* handle
,
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
);
655 des_md5_checksum (Shishi
* handle
,
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
);
666 gss_des_checksum (Shishi
* handle
,
670 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
675 rc
= shishi_md5 (handle
, in
, inlen
, &p
);
680 rc
= shishi_des_cbc_mac (handle
, shishi_key_value (key
), NULL
, p
, 16, out
);
691 des_verify (Shishi
* handle
, int algo
,
693 const char *in
, size_t inlen
,
694 const char *cksum
, size_t cksumlen
)
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
++)
719 res
= simplified_decrypt (handle
, key
, 0, NULL
, 0, NULL
, NULL
,
720 cksum
, cksumlen
, &out
, &outlen
);
722 for (i
= 0; i
< 8; i
++)
725 if (res
!= SHISHI_OK
)
727 shishi_error_set (handle
, "decrypt failed");
732 tmp
= xmalloc (tmplen
);
733 memcpy (tmp
, out
, 8);
734 memcpy (tmp
+ 8, in
, inlen
);
738 case SHISHI_RSA_MD4_DES
:
739 res
= shishi_md4 (handle
, tmp
, tmplen
, &md
);
742 case SHISHI_RSA_MD5_DES
:
743 res
= shishi_md5 (handle
, tmp
, tmplen
, &md
);
747 res
= SHISHI_CRYPTO_ERROR
;
750 if (res
!= SHISHI_OK
)
752 shishi_error_printf (handle
, "DES verify MD error");
756 if (memcmp (out
+ 8, md
, 16) != 0)
757 return SHISHI_VERIFY_FAILED
;
763 des_md4_verify (Shishi
* handle
,
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
);
775 des_md5_verify (Shishi
* handle
,
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
);