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
)
37 rc
= shishi_randomize (handle
, out
, blen
);
41 tmplen
= blen
+ inlen
;
42 tmp
= xmalloc (tmplen
);
44 memcpy (tmp
, out
, blen
);
45 memcpy (tmp
+ blen
, in
, inlen
);
49 case SHISHI_DES_CBC_MD4
:
50 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
, &plen
);
53 case SHISHI_DES_CBC_MD5
:
54 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
, &plen
);
58 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
59 return SHISHI_CRYPTO_INTERNAL_ERROR
;
63 memcpy (out
+ blen
, p
, plen
);
65 *outlen
= blen
+ hlen
;
71 raw_des_checksum1 (Shishi
* handle
, int algo
,
72 const char *in
, size_t inlen
,
73 char *out
, size_t * outlen
)
83 rc
= shishi_randomize (handle
, out
, blen
);
87 memset (out
+ blen
, 0, hlen
);
89 tmplen
= blen
+ hlen
+ inlen
;
90 tmp
= xmalloc (tmplen
);
92 memcpy (tmp
, out
, blen
+ hlen
);
93 memcpy (tmp
+ blen
+ hlen
, in
, inlen
);
97 case SHISHI_DES_CBC_MD4
:
98 rc
= shishi_md4 (handle
, tmp
, tmplen
, &p
, &plen
);
101 case SHISHI_DES_CBC_MD5
:
102 rc
= shishi_md5 (handle
, tmp
, tmplen
, &p
, &plen
);
106 shishi_error_printf (handle
, "MD %d unknown in raw des checksum", algo
);
107 return SHISHI_CRYPTO_INTERNAL_ERROR
;
111 memcpy (out
+ blen
, p
, plen
);
113 *outlen
= blen
+ hlen
;
119 des_encrypt_checksum (Shishi
* handle
,
122 const char *iv
, size_t ivlen
,
123 char **ivout
, size_t * ivoutlen
,
124 const char *in
, size_t inlen
,
125 char **out
, size_t * outlen
, int algo
)
127 char cksum
[8 + MAX_HASH_LEN
];
130 size_t inpadlen
, padzerolen
= 0, ptlen
, cksumlen
;
134 padzerolen
= 8 - (inlen
% 8);
135 inpadlen
= inlen
+ padzerolen
;
136 inpad
= xmalloc (inpadlen
);
138 memcpy (inpad
, in
, inlen
);
139 memset (inpad
+ inlen
, 0, padzerolen
);
141 res
= raw_des_checksum1 (handle
, algo
, inpad
, inpadlen
, cksum
, &cksumlen
);
142 if (res
!= SHISHI_OK
)
144 shishi_error_printf (handle
, "DES checksum failed");
148 ptlen
= inpadlen
+ cksumlen
;
149 pt
= xmalloc (ptlen
);
150 memcpy (pt
, cksum
, cksumlen
);
151 memcpy (pt
+ cksumlen
, inpad
, inpadlen
);
155 res
= simplified_encrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
156 pt
, ptlen
, out
, outlen
);
160 if (res
!= SHISHI_OK
)
162 shishi_error_printf (handle
, "DES encrypt failed");
170 des_crc_encrypt (Shishi
* handle
,
173 const char *iv
, size_t ivlen
,
174 char **ivout
, size_t * ivoutlen
,
175 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
177 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
178 ivoutlen
, in
, inlen
, out
, outlen
,
183 des_md4_encrypt (Shishi
* handle
,
188 char **ivout
, size_t * ivoutlen
,
189 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
191 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
192 ivoutlen
, in
, inlen
, out
, outlen
,
197 des_md5_encrypt (Shishi
* handle
,
202 char **ivout
, size_t * ivoutlen
,
203 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
205 return des_encrypt_checksum (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
206 ivoutlen
, in
, inlen
, out
, outlen
,
211 des_none_encrypt (Shishi
* handle
,
216 char **ivout
, size_t * ivoutlen
,
217 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
219 return simplified_encrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
220 in
, inlen
, out
, outlen
);
224 des_decrypt_verify (Shishi
* handle
,
227 const char *iv
, size_t ivlen
,
228 char **ivout
, size_t * ivoutlen
,
229 const char *in
, size_t inlen
,
230 char **out
, size_t * outlen
, int algo
)
237 res
= simplified_decrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
238 in
, inlen
, out
, outlen
);
239 if (res
!= SHISHI_OK
)
241 shishi_error_printf (handle
, "decrypt failed");
245 memcpy (incoming
, *out
+ 8, hlen
);
246 memset (*out
+ 8, 0, hlen
);
250 case SHISHI_DES_CBC_MD4
:
251 shishi_md4 (handle
, *out
, *outlen
, &computed
, &hlen
);
254 case SHISHI_DES_CBC_MD5
:
255 shishi_md5 (handle
, *out
, *outlen
, &computed
, &hlen
);
259 shishi_error_printf (handle
, "MD %d unknown in raw des verify", algo
);
260 return SHISHI_CRYPTO_ERROR
;
264 if (VERBOSECRYPTO (handle
))
266 puts ("DES verify:");
267 hexprint (incoming
, hlen
);
269 hexprint (computed
, hlen
);
273 if (memcmp (computed
, incoming
, hlen
) != 0)
275 shishi_error_printf (handle
, "DES hash verify failed");
276 return SHISHI_CRYPTO_ERROR
;
281 memmove (*out
, *out
+ 8 + hlen
, *outlen
- 8 - hlen
);
288 des_crc_decrypt (Shishi
* handle
,
293 char **ivout
, size_t * ivoutlen
,
294 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
296 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
297 ivoutlen
, in
, inlen
, out
, outlen
,
302 des_md4_decrypt (Shishi
* handle
,
307 char **ivout
, size_t * ivoutlen
,
308 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
310 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
311 ivoutlen
, in
, inlen
, out
, outlen
,
316 des_md5_decrypt (Shishi
* handle
,
321 char **ivout
, size_t * ivoutlen
,
322 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
324 return des_decrypt_verify (handle
, key
, keyusage
, iv
, ivlen
, ivout
,
325 ivoutlen
, in
, inlen
, out
, outlen
,
330 des_none_decrypt (Shishi
* handle
,
335 char **ivout
, size_t * ivoutlen
,
336 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
338 return simplified_decrypt (handle
, key
, 0, iv
, ivlen
, ivout
, ivoutlen
,
339 in
, inlen
, out
, outlen
);
343 des_set_odd_key_parity (char key
[8])
347 for (i
= 0; i
< 8; i
++)
351 for (j
= 1; j
< 8; j
++)
352 if (key
[i
] & (1 << j
))
356 if ((n_set_bits
% 2) == 0)
363 static char weak_des_keys
[16][8] = {
365 "\x01\x01\x01\x01\x01\x01\x01\x01",
366 "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
367 "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
368 "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
370 "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
371 "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
372 "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
373 "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
374 "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
375 "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
376 "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
377 "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
378 "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
379 "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
380 "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
381 "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
385 des_key_correction (Shishi
* handle
, char key
[8])
389 /* fixparity(key); */
390 des_set_odd_key_parity (key
);
392 /* This loop could be replaced by optimized code (compare nettle),
393 but let's not do that. */
394 for (i
= 0; i
< 16; i
++)
395 if (memcmp (key
, weak_des_keys
[i
], 8) == 0)
397 if (VERBOSECRYPTO (handle
))
398 printf ("\t ;; WEAK KEY (corrected)\n");
407 des_random_to_key (Shishi
* handle
,
408 const char *random
, size_t randomlen
, Shishi_key
* outkey
)
410 char tmp
[MAX_RANDOM_LEN
];
411 int keylen
= shishi_cipher_keylen (shishi_key_type (outkey
));
413 if (randomlen
!= shishi_key_length (outkey
))
415 shishi_error_printf (handle
, "DES random to key caller error");
416 return SHISHI_CRYPTO_ERROR
;
419 memcpy (tmp
, random
, keylen
);
420 des_set_odd_key_parity (tmp
);
422 shishi_key_value_set (outkey
, tmp
);
428 des_string_to_key (Shishi
* handle
,
432 size_t saltlen
, const char *parameter
, Shishi_key
* outkey
)
443 if (VERBOSECRYPTO (handle
))
445 printf ("des_string_to_key (string, salt)\n");
447 printf ("\t ;; String:\n");
448 escapeprint (string
, stringlen
);
449 hexprint (string
, stringlen
);
453 printf ("\t ;; Salt:\n");
454 escapeprint (salt
, saltlen
);
455 hexprint (salt
, saltlen
);
458 printf ("odd = 1;\n");
459 printf ("s = string | salt;\n");
460 printf ("tempstring = 0; /* 56-bit string */\n");
461 printf ("pad(s); /* with nulls to 8 byte boundary */\n");
466 n_s
= stringlen
+ saltlen
;
469 s
= (char *) xmalloc (n_s
);
470 memcpy (s
, string
, stringlen
);
472 memcpy (s
+ stringlen
, salt
, saltlen
);
473 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
474 memset (tempkey
, 0, sizeof (tempkey
)); /* tempkey = NULL; */
476 if (VERBOSECRYPTO (handle
))
478 printf ("\t ;; s = pad(string|salt):\n");
479 escapeprint (s
, n_s
);
484 for (i
= 0; i
< n_s
/ 8; i
++)
486 if (VERBOSECRYPTO (handle
))
488 printf ("for (8byteblock in s) {\n");
489 printf ("\t ;; loop iteration %d\n", i
);
490 printf ("\t ;; 8byteblock:\n");
491 escapeprint (&s
[i
* 8], 8);
492 hexprint (&s
[i
* 8], 8);
494 binprint (&s
[i
* 8], 8);
496 printf ("56bitstring = removeMSBits(8byteblock);\n");
499 for (j
= 0; j
< 8; j
++)
500 s
[i
* 8 + j
] = s
[i
* 8 + j
] & ~0x80;
502 if (VERBOSECRYPTO (handle
))
504 printf ("\t ;; 56bitstring:\n");
505 bin7print (&s
[i
* 8], 8);
507 printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd
);
512 for (j
= 0; j
< 4; j
++)
516 ((temp
>> 6) & 0x01) |
517 ((temp
>> 4) & 0x02) |
518 ((temp
>> 2) & 0x04) |
520 ((temp
<< 2) & 0x10) |
521 ((temp
<< 4) & 0x20) | ((temp
<< 6) & 0x40);
522 temp2
= s
[i
* 8 + 7 - j
];
524 ((temp2
>> 6) & 0x01) |
525 ((temp2
>> 4) & 0x02) |
526 ((temp2
>> 2) & 0x04) |
528 ((temp2
<< 2) & 0x10) |
529 ((temp2
<< 4) & 0x20) | ((temp2
<< 6) & 0x40);
530 s
[i
* 8 + j
] = temp2
;
531 s
[i
* 8 + 7 - j
] = temp
;
533 if (VERBOSECRYPTO (handle
))
535 printf ("reverse(56bitstring)\n");
536 printf ("\t ;; 56bitstring after reverse\n");
537 bin7print (&s
[i
* 8], 8);
544 if (VERBOSECRYPTO (handle
))
546 printf ("odd = ! odd\n");
547 printf ("tempstring = tempstring XOR 56bitstring;\n");
550 /* tempkey = tempkey XOR 8byteblock; */
551 for (j
= 0; j
< 8; j
++)
552 tempkey
[j
] ^= s
[i
* 8 + j
];
554 if (VERBOSECRYPTO (handle
))
556 printf ("\t ;; tempstring\n");
557 bin7print (tempkey
, 8);
563 for (j
= 0; j
< 8; j
++)
564 tempkey
[j
] = tempkey
[j
] << 1;
566 if (VERBOSECRYPTO (handle
))
568 printf ("for (8byteblock in s) {\n");
570 printf ("\t ;; for loop terminated\n");
571 printf ("\t ;; tempstring as 64bitblock\n");
572 hexprint (tempkey
, 8);
574 binprint (tempkey
, 8);
576 printf ("/* add parity as low bit of each byte */\n");
577 printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
580 res
= des_key_correction (handle
, tempkey
);
581 if (res
!= SHISHI_OK
)
584 if (VERBOSECRYPTO (handle
))
586 printf ("\t ;; tempkey\n");
587 escapeprint (tempkey
, 8);
588 hexprint (tempkey
, 8);
590 binprint (tempkey
, 8);
593 printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
596 memcpy (s
, string
, stringlen
);
598 memcpy (s
+ stringlen
, salt
, saltlen
);
599 memset (s
+ stringlen
+ saltlen
, 0, n_s
- stringlen
- saltlen
);
601 res
= shishi_des_cbc_mac (handle
, tempkey
, tempkey
, s
, n_s
, &p
);
602 if (res
!= SHISHI_OK
)
604 memcpy (tempkey
, p
, 8);
607 res
= des_key_correction (handle
, tempkey
);
608 if (res
!= SHISHI_OK
)
611 if (VERBOSECRYPTO (handle
))
613 printf ("\t ;; key\n");
614 escapeprint (tempkey
, 8);
615 hexprint (tempkey
, 8);
617 binprint (tempkey
, 8);
622 shishi_key_value_set (outkey
, tempkey
);
628 des_checksum (Shishi
* handle
,
632 const char *in
, size_t inlen
,
633 char **out
, size_t * outlen
, int algo
)
635 char cksum
[8 + MAX_HASH_LEN
];
641 res
= raw_des_checksum0 (handle
, algo
, in
, inlen
, cksum
, &cksumlen
);
642 if (res
!= SHISHI_OK
)
644 shishi_error_set (handle
, "raw des checksum failed");
648 keyp
= shishi_key_value (key
);
650 for (i
= 0; i
< 8; i
++)
653 res
= simplified_dencrypt (handle
, key
, NULL
, 0, NULL
, NULL
,
654 cksum
, cksumlen
, out
, outlen
, 0);
656 for (i
= 0; i
< 8; i
++)
659 if (res
!= SHISHI_OK
)
661 shishi_error_set (handle
, "encrypt failed");
669 des_md4_checksum (Shishi
* handle
,
673 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
675 return des_checksum (handle
, key
, keyusage
, cksumtype
,
676 in
, inlen
, out
, outlen
, SHISHI_DES_CBC_MD4
);
680 des_md5_checksum (Shishi
* handle
,
684 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
686 return des_checksum (handle
, key
, keyusage
, cksumtype
,
687 in
, inlen
, out
, outlen
, SHISHI_DES_CBC_MD5
);
691 gss_des_checksum (Shishi
* handle
,
695 const char *in
, size_t inlen
, char **out
, size_t * outlen
)
701 rc
= shishi_md5 (handle
, in
, inlen
, &p
, &plen
);
706 rc
= shishi_des_cbc_mac (handle
, shishi_key_value (key
), NULL
, p
, plen
, out
);
717 des_verify (Shishi
* handle
, int algo
,
719 const char *in
, size_t inlen
,
720 const char *cksum
, size_t cksumlen
)
732 if (cksumlen
!= 8 + 16)
733 return SHISHI_VERIFY_FAILED
;
736 * get_mic des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
737 * conf | rsa-md5(conf | msg))
738 * verify_mic decrypt and verify rsa-md5 checksum
741 keyp
= xmemdup (key
, 8);
742 for (i
= 0; i
< 8; i
++)
745 res
= simplified_decrypt (handle
, key
, 0, NULL
, 0, NULL
, NULL
,
746 cksum
, cksumlen
, &out
, &outlen
);
750 if (res
!= SHISHI_OK
)
752 shishi_error_set (handle
, "decrypt failed");
757 tmp
= xmalloc (tmplen
);
758 memcpy (tmp
, out
, 8);
759 memcpy (tmp
+ 8, in
, inlen
);
763 case SHISHI_RSA_MD4_DES
:
764 res
= shishi_md4 (handle
, tmp
, tmplen
, &md
, &mdlen
);
767 case SHISHI_RSA_MD5_DES
:
768 res
= shishi_md5 (handle
, tmp
, tmplen
, &md
, &mdlen
);
772 res
= SHISHI_CRYPTO_ERROR
;
775 if (res
!= SHISHI_OK
)
777 shishi_error_printf (handle
, "DES verify MD error");
781 if (memcmp (out
+ 8, md
, 16) != 0)
782 return SHISHI_VERIFY_FAILED
;
788 des_md4_verify (Shishi
* handle
,
792 const char *in
, size_t inlen
,
793 const char *cksum
, size_t cksumlen
)
795 return des_verify (handle
, SHISHI_RSA_MD4_DES
, shishi_key_value (key
),
796 in
, inlen
, cksum
, cksumlen
);
800 des_md5_verify (Shishi
* handle
,
804 const char *in
, size_t inlen
,
805 const char *cksum
, size_t cksumlen
)
807 return des_verify (handle
, SHISHI_RSA_MD5_DES
, shishi_key_value (key
),
808 in
, inlen
, cksum
, cksumlen
);