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