1 /* crypto-des.c --- DES crypto functions.
2  * Copyright (C) 2002-2013 Simon Josefsson
3  *
4  * This file is part of Shishi.
5  *
6  * Shishi is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Shishi is distributed in the hope that it will be useful, but
12  * 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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Shishi; if not, see http://www.gnu.org/licenses or write
18  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19  * Floor, Boston, MA 02110-1301, USA
20  *
21  */
22 
23 #include "internal.h"
24 
25 /* Get prototypes. */
26 #include "crypto.h"
27 
28 /* Get _shishi_escapeprint, etc. */
29 #include "utils.h"
30 
31 static int
raw_des_checksum0(Shishi * handle,int algo,const char * in,size_t inlen,char * out,size_t * outlen)32 raw_des_checksum0 (Shishi * handle, int algo,
33 		   const char *in, size_t inlen, char *out, size_t * outlen)
34 {
35   char *tmp;
36   size_t tmplen;
37   char *p;
38   int blen = 8;
39   int hlen = (algo == SHISHI_DES_CBC_CRC) ? 4 : 16;
40   int rc;
41 
42   rc = shishi_randomize (handle, 0, out, blen);
43   if (rc != SHISHI_OK)
44     return rc;
45 
46   tmplen = blen + inlen;
47   tmp = xmalloc (tmplen);
48 
49   memcpy (tmp, out, blen);
50   memcpy (tmp + blen, in, inlen);
51 
52   switch (algo)
53     {
54     case SHISHI_DES_CBC_CRC:
55       rc = shishi_crc (handle, tmp, tmplen, &p);
56       break;
57 
58     case SHISHI_DES_CBC_MD4:
59       rc = shishi_md4 (handle, tmp, tmplen, &p);
60       break;
61 
62     case SHISHI_DES_CBC_MD5:
63       rc = shishi_md5 (handle, tmp, tmplen, &p);
64       break;
65 
66     default:
67       shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
68       return SHISHI_CRYPTO_INTERNAL_ERROR;
69       break;
70     }
71 
72   memcpy (out + blen, p, hlen);
73 
74   *outlen = blen + hlen;
75 
76   return SHISHI_OK;
77 }
78 
79 static int
raw_des_checksum1(Shishi * handle,int algo,const char * in,size_t inlen,char * out,size_t * outlen)80 raw_des_checksum1 (Shishi * handle, int algo,
81 		   const char *in, size_t inlen, char *out, size_t * outlen)
82 {
83   char *tmp;
84   size_t tmplen;
85   char *p;
86   int blen = 8;
87   int hlen = (algo == SHISHI_DES_CBC_CRC) ? 4 : 16;
88   int rc;
89 
90   rc = shishi_randomize (handle, 0, out, blen);
91   if (rc != SHISHI_OK)
92     return rc;
93 
94   memset (out + blen, 0, hlen);
95 
96   tmplen = blen + hlen + inlen;
97   tmp = xmalloc (tmplen);
98 
99   memcpy (tmp, out, blen + hlen);
100   memcpy (tmp + blen + hlen, in, inlen);
101 
102   switch (algo)
103     {
104     case SHISHI_DES_CBC_CRC:
105       rc = shishi_crc (handle, tmp, tmplen, &p);
106       break;
107 
108     case SHISHI_DES_CBC_MD4:
109       rc = shishi_md4 (handle, tmp, tmplen, &p);
110       break;
111 
112     case SHISHI_DES_CBC_MD5:
113       rc = shishi_md5 (handle, tmp, tmplen, &p);
114       break;
115 
116     default:
117       shishi_error_printf (handle, "MD %d unknown in raw des checksum", algo);
118       return SHISHI_CRYPTO_INTERNAL_ERROR;
119       break;
120     }
121 
122   free (tmp);
123 
124   memcpy (out + blen, p, hlen);
125 
126   free (p);
127 
128   *outlen = blen + hlen;
129 
130   return SHISHI_OK;
131 }
132 
133 static int
des_encrypt_checksum(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen,int algo)134 des_encrypt_checksum (Shishi * handle,
135 		      Shishi_key * key,
136 		      int keyusage,
137 		      const char *iv, size_t ivlen,
138 		      char **ivout, size_t * ivoutlen,
139 		      const char *in, size_t inlen,
140 		      char **out, size_t * outlen, int algo)
141 {
142   char cksum[8 + MAX_HASH_LEN];
143   char *inpad;
144   char *pt;
145   size_t inpadlen, padzerolen = 0, ptlen, cksumlen;
146   int hlen = (algo == SHISHI_DES_CBC_CRC) ? 4 : 16;
147   int res;
148 
149   if ((inlen + hlen) % 8)
150     padzerolen = 8 - ((inlen + hlen) % 8);
151   inpadlen = inlen + padzerolen;
152   inpad = xmalloc (inpadlen);
153 
154   memcpy (inpad, in, inlen);
155   memset (inpad + inlen, 0, padzerolen);
156 
157   res = raw_des_checksum1 (handle, algo, inpad, inpadlen, cksum, &cksumlen);
158   if (res != SHISHI_OK)
159     {
160       shishi_error_printf (handle, "DES checksum failed");
161       return res;
162     }
163 
164   ptlen = inpadlen + cksumlen;
165   pt = xmalloc (ptlen);
166   memcpy (pt, cksum, cksumlen);
167   memcpy (pt + cksumlen, inpad, inpadlen);
168 
169   free (inpad);
170 
171   res = _shishi_simplified_encrypt (handle, key, 0, iv, ivlen,
172 				    ivout, ivoutlen, pt, ptlen, out, outlen);
173 
174   free (pt);
175 
176   if (res != SHISHI_OK)
177     {
178       shishi_error_printf (handle, "DES encrypt failed");
179       return res;
180     }
181 
182   return SHISHI_OK;
183 }
184 
185 static int
des_crc_encrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)186 des_crc_encrypt (Shishi * handle,
187 		 Shishi_key * key,
188 		 int keyusage,
189 		 const char *iv, size_t ivlen,
190 		 char **ivout, size_t * ivoutlen,
191 		 const char *in, size_t inlen, char **out, size_t * outlen)
192 {
193   return des_encrypt_checksum (handle, key, keyusage,
194 			       shishi_key_value (key),
195 			       shishi_key_length (key), ivout, ivoutlen, in,
196 			       inlen, out, outlen, SHISHI_DES_CBC_CRC);
197 }
198 
199 static int
des_md4_encrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)200 des_md4_encrypt (Shishi * handle,
201 		 Shishi_key * key,
202 		 int keyusage,
203 		 const char *iv,
204 		 size_t ivlen,
205 		 char **ivout, size_t * ivoutlen,
206 		 const char *in, size_t inlen, char **out, size_t * outlen)
207 {
208   return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
209 			       ivoutlen, in, inlen, out, outlen,
210 			       SHISHI_DES_CBC_MD4);
211 }
212 
213 static int
des_md5_encrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)214 des_md5_encrypt (Shishi * handle,
215 		 Shishi_key * key,
216 		 int keyusage,
217 		 const char *iv,
218 		 size_t ivlen,
219 		 char **ivout, size_t * ivoutlen,
220 		 const char *in, size_t inlen, char **out, size_t * outlen)
221 {
222   return des_encrypt_checksum (handle, key, keyusage, iv, ivlen, ivout,
223 			       ivoutlen, in, inlen, out, outlen,
224 			       SHISHI_DES_CBC_MD5);
225 }
226 
227 static int
des_none_encrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)228 des_none_encrypt (Shishi * handle,
229 		  Shishi_key * key,
230 		  int keyusage,
231 		  const char *iv,
232 		  size_t ivlen,
233 		  char **ivout, size_t * ivoutlen,
234 		  const char *in, size_t inlen, char **out, size_t * outlen)
235 {
236   return _shishi_simplified_encrypt (handle, key, 0, iv, ivlen, ivout,
237 				     ivoutlen, in, inlen, out, outlen);
238 }
239 
240 static int
des_decrypt_verify(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen,int algo)241 des_decrypt_verify (Shishi * handle,
242 		    Shishi_key * key,
243 		    int keyusage,
244 		    const char *iv, size_t ivlen,
245 		    char **ivout, size_t * ivoutlen,
246 		    const char *in, size_t inlen,
247 		    char **out, size_t * outlen, int algo)
248 {
249   int res;
250   char incoming[16];
251   char *computed;
252   size_t hlen = (algo == SHISHI_DES_CBC_CRC) ? 4 : 16;
253 
254   res = _shishi_simplified_decrypt (handle, key, 0, iv, ivlen,
255 				    ivout, ivoutlen, in, inlen, out, outlen);
256   if (res != SHISHI_OK)
257     {
258       shishi_error_printf (handle, "decrypt failed");
259       return res;
260     }
261 
262   if (VERBOSECRYPTONOISE (handle))
263     {
264       puts ("verify decrypted:");
265       _shishi_escapeprint (*out, *outlen);
266       _shishi_hexprint (*out, *outlen);
267     }
268 
269   memcpy (incoming, *out + 8, hlen);
270   memset (*out + 8, 0, hlen);
271 
272   if (VERBOSECRYPTONOISE (handle))
273     {
274       puts ("cksum pt:");
275       _shishi_hexprint (*out, *outlen);
276     }
277 
278   switch (algo)
279     {
280     case SHISHI_DES_CBC_CRC:
281       shishi_crc (handle, *out, *outlen, &computed);
282       break;
283 
284     case SHISHI_DES_CBC_MD4:
285       shishi_md4 (handle, *out, *outlen, &computed);
286       break;
287 
288     case SHISHI_DES_CBC_MD5:
289       shishi_md5 (handle, *out, *outlen, &computed);
290       break;
291 
292     default:
293       shishi_error_printf (handle, "MD %d unknown in raw des verify", algo);
294       return SHISHI_CRYPTO_ERROR;
295       break;
296     }
297 
298   if (VERBOSECRYPTONOISE (handle))
299     {
300       puts ("DES verify:");
301       _shishi_hexprint (incoming, hlen);
302       _shishi_hexprint (computed, hlen);
303     }
304 
305   if (memcmp (computed, incoming, hlen) != 0)
306     {
307       shishi_error_printf (handle, "DES hash verify failed");
308       return SHISHI_CRYPTO_ERROR;
309     }
310 
311   free (computed);
312 
313   memmove (*out, *out + 8 + hlen, *outlen - 8 - hlen);
314   *outlen -= 8 + hlen;
315 
316   return SHISHI_OK;
317 }
318 
319 static int
des_crc_decrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)320 des_crc_decrypt (Shishi * handle,
321 		 Shishi_key * key,
322 		 int keyusage,
323 		 const char *iv,
324 		 size_t ivlen,
325 		 char **ivout, size_t * ivoutlen,
326 		 const char *in, size_t inlen, char **out, size_t * outlen)
327 {
328   return des_decrypt_verify (handle, key, keyusage,
329 			     shishi_key_value (key), shishi_key_length (key),
330 			     ivout, ivoutlen, in, inlen, out, outlen,
331 			     SHISHI_DES_CBC_CRC);
332 }
333 
334 static int
des_md4_decrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)335 des_md4_decrypt (Shishi * handle,
336 		 Shishi_key * key,
337 		 int keyusage,
338 		 const char *iv,
339 		 size_t ivlen,
340 		 char **ivout, size_t * ivoutlen,
341 		 const char *in, size_t inlen, char **out, size_t * outlen)
342 {
343   return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
344 			     ivoutlen, in, inlen, out, outlen,
345 			     SHISHI_DES_CBC_MD4);
346 }
347 
348 static int
des_md5_decrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)349 des_md5_decrypt (Shishi * handle,
350 		 Shishi_key * key,
351 		 int keyusage,
352 		 const char *iv,
353 		 size_t ivlen,
354 		 char **ivout, size_t * ivoutlen,
355 		 const char *in, size_t inlen, char **out, size_t * outlen)
356 {
357   return des_decrypt_verify (handle, key, keyusage, iv, ivlen, ivout,
358 			     ivoutlen, in, inlen, out, outlen,
359 			     SHISHI_DES_CBC_MD5);
360 }
361 
362 static int
des_none_decrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)363 des_none_decrypt (Shishi * handle,
364 		  Shishi_key * key,
365 		  int keyusage,
366 		  const char *iv,
367 		  size_t ivlen,
368 		  char **ivout, size_t * ivoutlen,
369 		  const char *in, size_t inlen, char **out, size_t * outlen)
370 {
371   return _shishi_simplified_decrypt (handle, key, 0, iv, ivlen, ivout,
372 				     ivoutlen, in, inlen, out, outlen);
373 }
374 
375 static void
des_set_odd_key_parity(char key[8])376 des_set_odd_key_parity (char key[8])
377 {
378   int i, j;
379 
380   for (i = 0; i < 8; i++)
381     {
382       int n_set_bits = 0;
383 
384       for (j = 1; j < 8; j++)
385 	if (key[i] & (1 << j))
386 	  n_set_bits++;
387 
388       key[i] &= ~1;
389       if ((n_set_bits % 2) == 0)
390 	key[i] |= 1;
391     }
392 }
393 
394 static char weak_des_keys[16][8] = {
395   /* Weak keys */
396   "\x01\x01\x01\x01\x01\x01\x01\x01",
397   "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E",
398   "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1",
399   "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE",
400   /* Semiweak keys */
401   "\x01\xFE\x01\xFE\x01\xFE\x01\xFE",
402   "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1",
403   "\x01\xE0\x01\xE0\x01\xF1\x01\xF1",
404   "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE",
405   "\x01\x1F\x01\x1F\x01\x0E\x01\x0E",
406   "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE",
407   "\xFE\x01\xFE\x01\xFE\x01\xFE\x01",
408   "\xE0\x1F\xE1\x0F\xF1\x0E\xF1\x0E",
409   "\xE0\x01\xE0\x01\xF1\x01\xF1\x01",
410   "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E",
411   "\x1F\x01\x1F\x01\x0E\x01\x0E\x01",
412   "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1"
413 };
414 
415 static void
des_key_correction(Shishi * handle,char key[8])416 des_key_correction (Shishi * handle, char key[8])
417 {
418   size_t i;
419 
420   /* fixparity(key); */
421   des_set_odd_key_parity (key);
422 
423   /* This loop could be replaced by optimized code (compare nettle),
424      but let's not do that. */
425   for (i = 0; i < 16; i++)
426     if (memcmp (key, weak_des_keys[i], 8) == 0)
427       {
428 	if (VERBOSECRYPTONOISE (handle))
429 	  printf ("\t ;; WEAK KEY (corrected)\n");
430 	key[7] ^= 0xF0;
431 	break;
432       }
433 }
434 
435 static int
des_random_to_key(Shishi * handle,const char * rnd,size_t rndlen,Shishi_key * outkey)436 des_random_to_key (Shishi * handle,
437 		   const char *rnd, size_t rndlen, Shishi_key * outkey)
438 {
439   char tmp[MAX_RANDOM_LEN];
440   int keylen = shishi_cipher_keylen (shishi_key_type (outkey));
441 
442   if (rndlen != shishi_key_length (outkey))
443     {
444       shishi_error_printf (handle, "DES random to key caller error");
445       return SHISHI_CRYPTO_ERROR;
446     }
447 
448   memcpy (tmp, rnd, keylen);
449   des_set_odd_key_parity (tmp);
450 
451   shishi_key_value_set (outkey, tmp);
452 
453   return SHISHI_OK;
454 }
455 
456 static int
des_string_to_key(Shishi * handle,const char * string,size_t stringlen,const char * salt,size_t saltlen,const char * parameter,Shishi_key * outkey)457 des_string_to_key (Shishi * handle,
458 		   const char *string,
459 		   size_t stringlen,
460 		   const char *salt,
461 		   size_t saltlen, const char *parameter, Shishi_key * outkey)
462 {
463   char *s;
464   int n_s;
465   int odd;
466   char tempkey[8];
467   char *p;
468   int i, j;
469   char temp, temp2;
470   int res;
471 
472   if (VERBOSECRYPTO (handle))
473     {
474       printf ("des_string_to_key (string, salt)\n");
475       printf ("\t ;; String:\n");
476       _shishi_escapeprint (string, stringlen);
477       _shishi_hexprint (string, stringlen);
478       printf ("\t ;; Salt:\n");
479       _shishi_escapeprint (salt, saltlen);
480       _shishi_hexprint (salt, saltlen);
481     }
482 
483   if (VERBOSECRYPTONOISE (handle))
484     {
485       printf ("odd = 1;\n");
486       printf ("s = string | salt;\n");
487       printf ("tempstring = 0; /* 56-bit string */\n");
488       printf ("pad(s); /* with nulls to 8 byte boundary */\n");
489 
490     }
491 
492   odd = 1;
493   n_s = stringlen + saltlen;
494   if ((n_s % 8) != 0)
495     n_s += 8 - n_s % 8;
496   s = xmalloc (n_s);
497   memcpy (s, string, stringlen);
498   if (saltlen > 0)
499     memcpy (s + stringlen, salt, saltlen);
500   memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
501   memset (tempkey, 0, sizeof (tempkey));	/* tempkey = NULL; */
502 
503   if (VERBOSECRYPTONOISE (handle))
504     {
505       printf ("\t ;; s = pad(string|salt):\n");
506       _shishi_escapeprint (s, n_s);
507       _shishi_hexprint (s, n_s);
508     }
509 
510   for (i = 0; i < n_s / 8; i++)
511     {
512       if (VERBOSECRYPTONOISE (handle))
513 	{
514 	  printf ("for (8byteblock in s) {\n");
515 	  printf ("\t ;; loop iteration %d\n", i);
516 	  printf ("\t ;; 8byteblock:\n");
517 	  _shishi_escapeprint (&s[i * 8], 8);
518 	  _shishi_hexprint (&s[i * 8], 8);
519 	  _shishi_binprint (&s[i * 8], 8);
520 	  printf ("56bitstring = removeMSBits(8byteblock);\n");
521 	}
522 
523       for (j = 0; j < 8; j++)
524 	s[i * 8 + j] = s[i * 8 + j] & ~0x80;
525 
526       if (VERBOSECRYPTONOISE (handle))
527 	{
528 	  printf ("\t ;; 56bitstring:\n");
529 	  _shishi_bin7print (&s[i * 8], 8);
530 	  printf ("if (odd == 0) reverse(56bitstring);\t ;; odd=%d\n", odd);
531 	}
532 
533       if (odd == 0)
534 	{
535 	  for (j = 0; j < 4; j++)
536 	    {
537 	      temp = s[i * 8 + j];
538 	      temp =
539 		((temp >> 6) & 0x01) |
540 		((temp >> 4) & 0x02) |
541 		((temp >> 2) & 0x04) |
542 		((temp) & 0x08) |
543 		((temp << 2) & 0x10) |
544 		((temp << 4) & 0x20) | ((temp << 6) & 0x40);
545 	      temp2 = s[i * 8 + 7 - j];
546 	      temp2 =
547 		((temp2 >> 6) & 0x01) |
548 		((temp2 >> 4) & 0x02) |
549 		((temp2 >> 2) & 0x04) |
550 		((temp2) & 0x08) |
551 		((temp2 << 2) & 0x10) |
552 		((temp2 << 4) & 0x20) | ((temp2 << 6) & 0x40);
553 	      s[i * 8 + j] = temp2;
554 	      s[i * 8 + 7 - j] = temp;
555 	    }
556 	  if (VERBOSECRYPTONOISE (handle))
557 	    {
558 	      printf ("reverse(56bitstring)\n");
559 	      printf ("\t ;; 56bitstring after reverse\n");
560 	      _shishi_bin7print (&s[i * 8], 8);
561 	    }
562 	}
563 
564       odd = !odd;
565 
566       if (VERBOSECRYPTONOISE (handle))
567 	{
568 	  printf ("odd = ! odd\n");
569 	  printf ("tempstring = tempstring XOR 56bitstring;\n");
570 	}
571 
572       /* tempkey = tempkey XOR 8byteblock; */
573       for (j = 0; j < 8; j++)
574 	tempkey[j] ^= s[i * 8 + j];
575 
576       if (VERBOSECRYPTONOISE (handle))
577 	{
578 	  printf ("\t ;; tempstring\n");
579 	  _shishi_bin7print (tempkey, 8);
580 	}
581     }
582 
583   for (j = 0; j < 8; j++)
584     tempkey[j] = tempkey[j] << 1;
585 
586   if (VERBOSECRYPTONOISE (handle))
587     {
588       printf ("for (8byteblock in s) {\n");
589       printf ("}\n");
590       printf ("\t ;; for loop terminated\n");
591       printf ("\t ;; tempstring as 64bitblock\n");
592       _shishi_hexprint (tempkey, 8);
593       _shishi_binprint (tempkey, 8);
594       printf ("/* add parity as low bit of each byte */\n");
595       printf ("tempkey = key_correction(add_parity_bits(tempstring));\n");
596     }
597 
598   des_key_correction (handle, tempkey);
599 
600   if (VERBOSECRYPTONOISE (handle))
601     {
602       printf ("\t ;; tempkey\n");
603       _shishi_escapeprint (tempkey, 8);
604       _shishi_hexprint (tempkey, 8);
605       _shishi_binprint (tempkey, 8);
606       printf ("key = key_correction(DES-CBC-check(s,tempkey));\n");
607     }
608 
609   memcpy (s, string, stringlen);
610   if (saltlen > 0)
611     memcpy (s + stringlen, salt, saltlen);
612   memset (s + stringlen + saltlen, 0, n_s - stringlen - saltlen);
613 
614   res = shishi_des_cbc_mac (handle, tempkey, tempkey, s, n_s, &p);
615   if (res != SHISHI_OK)
616     return res;
617   free (s);
618   memcpy (tempkey, p, 8);
619   free (p);
620 
621   des_key_correction (handle, tempkey);
622 
623   if (VERBOSECRYPTO (handle))
624     {
625       printf ("\t ;; key\n");
626       _shishi_escapeprint (tempkey, 8);
627       _shishi_hexprint (tempkey, 8);
628       _shishi_binprint (tempkey, 8);
629     }
630 
631   shishi_key_value_set (outkey, tempkey);
632 
633   return SHISHI_OK;
634 }
635 
636 static int
des_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen,int algo)637 des_checksum (Shishi * handle,
638 	      Shishi_key * key,
639 	      int keyusage,
640 	      int cksumtype,
641 	      const char *in, size_t inlen,
642 	      char **out, size_t * outlen, int algo)
643 {
644   char cksum[8 + MAX_HASH_LEN];
645   size_t cksumlen;
646   char *keyp;
647   int i;
648   int res;
649 
650   res = raw_des_checksum0 (handle, algo, in, inlen, cksum, &cksumlen);
651   if (res != SHISHI_OK)
652     {
653       shishi_error_set (handle, "raw des checksum failed");
654       return res;
655     }
656 
657   keyp = (char *) shishi_key_value (key);
658 
659   for (i = 0; i < 8; i++)
660     keyp[i] ^= 0xF0;
661 
662   res = _shishi_simplified_dencrypt (handle, key, NULL, 0, NULL, NULL,
663 				     cksum, cksumlen, out, outlen, 0);
664 
665   for (i = 0; i < 8; i++)
666     keyp[i] ^= 0xF0;
667 
668   if (res != SHISHI_OK)
669     {
670       shishi_error_set (handle, "encrypt failed");
671       return res;
672     }
673 
674   return SHISHI_OK;
675 }
676 
677 static int
des_crc_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)678 des_crc_checksum (Shishi * handle,
679 		  Shishi_key * key,
680 		  int keyusage,
681 		  int cksumtype,
682 		  const char *in, size_t inlen, char **out, size_t * outlen)
683 {
684   return des_checksum (handle, key, keyusage, cksumtype,
685 		       in, inlen, out, outlen, SHISHI_DES_CBC_CRC);
686 }
687 
688 static int
des_md4_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)689 des_md4_checksum (Shishi * handle,
690 		  Shishi_key * key,
691 		  int keyusage,
692 		  int cksumtype,
693 		  const char *in, size_t inlen, char **out, size_t * outlen)
694 {
695   return des_checksum (handle, key, keyusage, cksumtype,
696 		       in, inlen, out, outlen, SHISHI_DES_CBC_MD4);
697 }
698 
699 static int
des_md5_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)700 des_md5_checksum (Shishi * handle,
701 		  Shishi_key * key,
702 		  int keyusage,
703 		  int cksumtype,
704 		  const char *in, size_t inlen, char **out, size_t * outlen)
705 {
706   return des_checksum (handle, key, keyusage, cksumtype,
707 		       in, inlen, out, outlen, SHISHI_DES_CBC_MD5);
708 }
709 
710 static int
gss_des_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)711 gss_des_checksum (Shishi * handle,
712 		  Shishi_key * key,
713 		  int keyusage,
714 		  int cksumtype,
715 		  const char *in, size_t inlen, char **out, size_t * outlen)
716 {
717   char *p;
718   int rc;
719 
720   rc = shishi_md5 (handle, in, inlen, &p);
721   if (rc != SHISHI_OK)
722     return rc;
723 
724   *outlen = 8;
725   rc = shishi_des_cbc_mac (handle, shishi_key_value (key), NULL, p, 16, out);
726 
727   free (p);
728 
729   if (rc != SHISHI_OK)
730     return rc;
731 
732   return SHISHI_OK;
733 }
734 
735 static int
des_verify(Shishi * handle,int algo,Shishi_key * key,const char * in,size_t inlen,const char * cksum,size_t cksumlen)736 des_verify (Shishi * handle, int algo,
737 	    Shishi_key * key,
738 	    const char *in, size_t inlen, const char *cksum, size_t cksumlen)
739 {
740   char *out;
741   size_t outlen;
742   char *md;
743   size_t tmplen;
744   char *tmp;
745   char *keyp;
746   size_t i;
747   int res;
748 
749   if (cksumlen != 8 + 16)
750     return SHISHI_VERIFY_FAILED;
751 
752   /*
753    * get_mic                   des-cbc(key XOR 0xF0F0F0F0F0F0F0F0,
754    *                                   conf | rsa-md5(conf | msg))
755    * verify_mic                decrypt and verify rsa-md5 checksum
756    */
757 
758   keyp = (char *) shishi_key_value (key);
759 
760   for (i = 0; i < 8; i++)
761     keyp[i] ^= 0xF0;
762 
763   res = _shishi_simplified_decrypt (handle, key, 0, NULL, 0, NULL, NULL,
764 				    cksum, cksumlen, &out, &outlen);
765 
766   for (i = 0; i < 8; i++)
767     keyp[i] ^= 0xF0;
768 
769   if (res != SHISHI_OK)
770     {
771       shishi_error_set (handle, "decrypt failed");
772       return res;
773     }
774 
775   tmplen = 8 + inlen;
776   tmp = xmalloc (tmplen);
777   memcpy (tmp, out, 8);
778   memcpy (tmp + 8, in, inlen);
779 
780   switch (algo)
781     {
782     case SHISHI_RSA_MD4_DES:
783       res = shishi_md4 (handle, tmp, tmplen, &md);
784       break;
785 
786     case SHISHI_RSA_MD5_DES:
787       res = shishi_md5 (handle, tmp, tmplen, &md);
788       break;
789 
790     default:
791       res = SHISHI_CRYPTO_ERROR;
792     }
793 
794   if (res != SHISHI_OK)
795     {
796       shishi_error_printf (handle, "DES verify MD error");
797       return res;
798     }
799 
800   if (memcmp (out + 8, md, 16) != 0)
801     return SHISHI_VERIFY_FAILED;
802 
803   return SHISHI_OK;
804 }
805 
806 static int
des_md4_verify(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,const char * cksum,size_t cksumlen)807 des_md4_verify (Shishi * handle,
808 		Shishi_key * key,
809 		int keyusage,
810 		int cksumtype,
811 		const char *in, size_t inlen,
812 		const char *cksum, size_t cksumlen)
813 {
814   return des_verify (handle, SHISHI_RSA_MD4_DES, key,
815 		     in, inlen, cksum, cksumlen);
816 }
817 
818 static int
des_md5_verify(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,const char * cksum,size_t cksumlen)819 des_md5_verify (Shishi * handle,
820 		Shishi_key * key,
821 		int keyusage,
822 		int cksumtype,
823 		const char *in, size_t inlen,
824 		const char *cksum, size_t cksumlen)
825 {
826   return des_verify (handle, SHISHI_RSA_MD5_DES, key,
827 		     in, inlen, cksum, cksumlen);
828 }
829 
830 cipherinfo des_cbc_crc_info = {
831   SHISHI_DES_CBC_CRC,
832   "des-cbc-crc",
833   8,
834   8,
835   8,
836   8,
837   SHISHI_CRC32,
838   des_random_to_key,
839   des_string_to_key,
840   des_crc_encrypt,
841   des_crc_decrypt
842 };
843 
844 cipherinfo des_cbc_md4_info = {
845   SHISHI_DES_CBC_MD4,
846   "des-cbc-md4",
847   8,
848   8,
849   8,
850   8,
851   SHISHI_RSA_MD4_DES,
852   des_random_to_key,
853   des_string_to_key,
854   des_md4_encrypt,
855   des_md4_decrypt
856 };
857 
858 cipherinfo des_cbc_md5_info = {
859   SHISHI_DES_CBC_MD5,
860   "des-cbc-md5",
861   8,
862   8,
863   8,
864   8,
865   SHISHI_RSA_MD5_DES,
866   des_random_to_key,
867   des_string_to_key,
868   des_md5_encrypt,
869   des_md5_decrypt
870 };
871 
872 cipherinfo des_cbc_none_info = {
873   SHISHI_DES_CBC_NONE,
874   "des-cbc-none",
875   8,
876   8,
877   8,
878   8,
879   SHISHI_RSA_MD5_DES,
880   des_random_to_key,
881   des_string_to_key,
882   des_none_encrypt,
883   des_none_decrypt
884 };
885 
886 checksuminfo crc32_info = {
887   SHISHI_CRC32,
888   "crc32",
889   4,
890   des_crc_checksum,
891   NULL
892 };
893 
894 checksuminfo md4_des_info = {
895   SHISHI_RSA_MD4_DES,
896   "rsa-md4-des",
897   24,
898   des_md4_checksum,
899   des_md4_verify
900 };
901 
902 checksuminfo md5_des_info = {
903   SHISHI_RSA_MD5_DES,
904   "rsa-md5-des",
905   24,
906   des_md5_checksum,
907   des_md5_verify
908 };
909 
910 checksuminfo md5_gss_info = {
911   SHISHI_RSA_MD5_DES_GSS,
912   "rsa-md5-des-gss",
913   8,
914   gss_des_checksum,
915   NULL
916 };
917