source: trunk/cscrypt/des.c@ 1

Last change on this file since 1 was 1, checked in by root, 14 years ago

initial import

File size: 12.1 KB
Line 
1#include <stdio.h>
2#include <string.h>
3#include "des.h"
4
5static byte PC2[8][6] =
6{
7 { 14, 17, 11, 24, 1, 5 },
8 { 3, 28, 15, 6, 21, 10 },
9 { 23, 19, 12, 4, 26, 8 },
10 { 16, 7, 27, 20, 13, 2 },
11 { 41, 52, 31, 37, 47, 55 },
12 { 30, 40, 51, 45, 33, 48 },
13 { 44, 49, 39, 56, 34, 53 },
14 { 46, 42, 50, 36, 29, 32 }
15};
16
17
18static byte E[8][6] =
19{
20 { 32, 1, 2, 3, 4, 5 },
21 { 4, 5, 6, 7, 8, 9 },
22 { 8, 9, 10, 11, 12, 13 },
23 { 12, 13, 14, 15, 16, 17 },
24 { 16, 17, 18, 19, 20, 21 },
25 { 20, 21, 22, 23, 24, 25 },
26 { 24, 25, 26, 27, 28, 29 },
27 { 28, 29, 30, 31, 32, 1 }
28};
29
30
31
32static byte P[32] =
33{
34 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
35 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
36};
37
38
39static byte SBOXES[4][64] =
40{
41 {
42 0x2e, 0xe0, 0xc4, 0xbf, 0x4d, 0x27, 0x11, 0xc4,
43 0x72, 0x4e, 0xaf, 0x72, 0xbb, 0xdd, 0x68, 0x11,
44 0x83, 0x5a, 0x5a, 0x06, 0x36, 0xfc, 0xfc, 0xab,
45 0xd5, 0x39, 0x09, 0x95, 0xe0, 0x83, 0x97, 0x68,
46 0x44, 0xbf, 0x21, 0x8c, 0x1e, 0xc8, 0xb8, 0x72,
47 0xad, 0x14, 0xd6, 0xe9, 0x72, 0x21, 0x8b, 0xd7,
48 0xff, 0x65, 0x9c, 0xfb, 0xc9, 0x03, 0x57, 0x9e,
49 0x63, 0xaa, 0x3a, 0x40, 0x05, 0x56, 0xe0, 0x3d
50 },
51 {
52 0xcf, 0xa3, 0x11, 0xfd, 0xa8, 0x44, 0xfe, 0x27,
53 0x96, 0x7f, 0x2b, 0xc2, 0x63, 0x98, 0x84, 0x5e,
54 0x09, 0x6c, 0xd7, 0x10, 0x32, 0xd1, 0x4d, 0xea,
55 0xec, 0x06, 0x70, 0xb9, 0x55, 0x3b, 0xba, 0x85,
56 0x90, 0x4d, 0xee, 0x38, 0xf7, 0x2a, 0x5b, 0xc1,
57 0x2a, 0x93, 0x84, 0x5f, 0xcd, 0xf4, 0x31, 0xa2,
58 0x75, 0xbb, 0x08, 0xe6, 0x4c, 0x17, 0xa6, 0x7c,
59 0x19, 0x60, 0xd3, 0x05, 0xb2, 0x8e, 0x6f, 0xd9
60 },
61 {
62 0x4a, 0xdd, 0xb0, 0x07, 0x29, 0xb0, 0xee, 0x79,
63 0xf6, 0x43, 0x03, 0x94, 0x8f, 0x16, 0xd5, 0xaa,
64 0x31, 0xe2, 0xcd, 0x38, 0x9c, 0x55, 0x77, 0xce,
65 0x5b, 0x2c, 0xa4, 0xfb, 0x62, 0x8f, 0x18, 0x61,
66 0x1d, 0x61, 0x46, 0xba, 0xb4, 0xdd, 0xd9, 0x80,
67 0xc8, 0x16, 0x3f, 0x49, 0x73, 0xa8, 0xe0, 0x77,
68 0xab, 0x94, 0xf1, 0x5f, 0x62, 0x0e, 0x8c, 0xf3,
69 0x05, 0xeb, 0x5a, 0x25, 0x9e, 0x32, 0x27, 0xcc
70 },
71 {
72 0xd7, 0x1d, 0x2d, 0xf8, 0x8e, 0xdb, 0x43, 0x85,
73 0x60, 0xa6, 0xf6, 0x3f, 0xb9, 0x70, 0x1a, 0x43,
74 0xa1, 0xc4, 0x92, 0x57, 0x38, 0x62, 0xe5, 0xbc,
75 0x5b, 0x01, 0x0c, 0xea, 0xc4, 0x9e, 0x7f, 0x29,
76 0x7a, 0x23, 0xb6, 0x1f, 0x49, 0xe0, 0x10, 0x76,
77 0x9c, 0x4a, 0xcb, 0xa1, 0xe7, 0x8d, 0x2d, 0xd8,
78 0x0f, 0xf9, 0x61, 0xc4, 0xa3, 0x95, 0xde, 0x0b,
79 0xf5, 0x3c, 0x32, 0x57, 0x58, 0x62, 0x84, 0xbe
80 }
81};
82
83
84
85static byte PC1[][8] =
86{
87 {57, 49, 41, 33, 25, 17, 9, 1},
88 {58, 50, 42, 34, 26, 18, 10, 2},
89 {59, 51, 43, 35, 27, 19, 11, 3},
90 {60, 52, 44, 36, 63, 55, 47,39},
91 {31, 23, 15, 7, 62, 54, 46,38},
92 {30, 22, 14, 6, 61, 53, 45,37},
93 {29, 21, 13, 5, 28, 20, 12, 4}
94};
95
96
97void doPC1(byte data[])
98{
99 byte buf[8];
100 byte i, j;
101
102 memset(buf, 0, 8);
103
104 for(j=0; j<7; j++) {
105 for(i=0; i<8; i++) {
106 byte lookup = PC1[j][i];
107 buf[j] |= ((data[(lookup>>3)]>>(8-(lookup & 7))) & 1) << (7-i);
108 }
109 }
110
111 memcpy(data, buf, 8);
112}
113
114static void doIp(byte data[])
115{
116 unsigned char j, k;
117 byte val;
118 byte buf[8];
119 byte *p;
120 byte i = 8;
121
122 for(i=0; i<8; i++)
123 {
124 val = data[i];
125 p = &buf[3];
126 j = 4;
127
128 do
129 {
130 for(k=0; k<=4; k+=4)
131 {
132 p[k] >>= 1;
133 if(val & 1) p[k] |= 0x80;
134 val >>= 1;
135 }
136 p--;
137 } while(--j);
138 }
139
140 memcpy(data, buf, 8);
141}
142
143static void doIp_1(byte data[])
144{
145 unsigned char j, k;
146 byte r = 0;
147 byte buf[8];
148 byte *p;
149 byte i = 8;
150
151 for(i=0; i<8; i++)
152 {
153 p = &data[3];
154 j = 4;
155
156 do
157 {
158 for(k=0; k<=4; k+=4)
159 {
160 r >>= 1;
161 if(p[k] & 1) r |= 0x80;
162 p[k] >>= 1;
163 }
164 p--;
165 } while(--j);
166 buf[i] = r;
167 }
168
169 memcpy(data, buf, 8);
170}
171
172
173
174static void makeK(byte *left, byte *right, byte *K)
175{
176 byte i, j;
177 byte bit, val;
178 byte *p;
179
180 for(i=0; i<8; i++)
181 {
182 val = 0;
183 for(j=0; j<6; j++)
184 {
185 bit = PC2[i][j];
186 if(bit < 29)
187 {
188 bit = 28-bit;
189 p = left;
190 }
191 else
192 {
193 bit = 56-bit;
194 p = right;
195 }
196 val <<= 1;
197 if( p[bit >> 3] & (1 << (bit & 7)) ) val |= 1;
198 }
199 *K = val;
200 K++;
201 }
202}
203
204static void rightRot(byte key[])
205{
206 byte *p = key;
207 byte i = 3;
208 byte carry = 0;
209
210 carry = 0;
211
212 if(*p & 1) carry = 0x08;
213
214 do {
215 *p = (*p >> 1) | ((p[1] & 1) ? 0x80 : 0);
216 p++;
217 } while(--i);
218
219 *p = (*p >> 1) | carry;
220}
221
222static void rightRotKeys(byte left[], byte right[])
223{
224 rightRot(left);
225 rightRot(right);
226}
227
228static void leftRot(byte key[])
229{
230 byte i = 27;
231
232 do {
233 rightRot(key);
234 } while(--i);
235}
236
237static void leftRotKeys(byte left[], byte right[])
238{
239 leftRot(left);
240 leftRot(right);
241}
242
243static void desCore(byte data[], byte K[], byte result[])
244{
245 byte i, j;
246 byte bit, val;
247
248 memset(result, 0, 4);
249
250 for(i=0; i<8; i++)
251 {
252 val = 0;
253 for(j=0; j<6; j++)
254 {
255 bit = 32-E[i][j];
256 val <<= 1;
257 if( data[3 - (bit >> 3)] & (1 << (bit & 7)) ) val |= 1;
258 }
259 val ^= K[i];
260 val = SBOXES[i & 3][val];
261 if(i > 3)
262 {
263 val >>= 4;
264 }
265 val &= 0x0f;
266 result[i >> 1] |= (i & 1) ? val : (val << 4);
267 }
268}
269
270static void permut32(byte data[])
271{
272 byte i, j;
273 byte bit;
274 byte r[4];
275 byte *p;
276
277 for(i=0; i<32; i++)
278 {
279 bit = 32-P[i];
280 p = r;
281 for(j=0; j<3; j++)
282 {
283 *p = (*p << 1) | ((p[1] & 0x80) ? 1 : 0);
284 p++;
285 }
286 *p <<= 1;
287 if( data[3 - (bit >> 3)] & (1 << (bit & 7)) ) *p |= 1;
288 }
289
290 memcpy(data, r, 4);
291}
292
293static void swap(byte left[], byte right[])
294{
295 byte x[4];
296
297 memcpy(x, right, 4);
298 memcpy(right, left, 4);
299 memcpy(left, x, 4);
300}
301
302static void desRound(byte left[], byte right[], byte data[], byte mode, byte k8)
303{
304 byte i;
305 byte K[8];
306 byte r[4];
307 byte tempr[4];
308 unsigned short temp;
309
310 memcpy(tempr, data+4, 4);
311
312 /* Viaccess */
313 temp = (short)k8*(short)tempr[0]+(short)k8+(short)tempr[0];
314 tempr[0] = (temp & 0xff) - ((temp>>8) & 0xff);
315 if((temp & 0xff) - (temp>>8) < 0)
316 tempr[0]++;
317
318 makeK(left, right, K);
319 desCore(tempr, K, r);
320 permut32(r);
321
322 if(mode & DES_HASH)
323 {
324 i = r[0];
325 r[0] = r[1];
326 r[1] = i;
327 }
328
329 for(i=0; i<4; i++)
330 {
331 *data ^= r[i];
332 data++;
333 }
334
335 swap(data-4, data);
336}
337
338void des(byte key[], byte mode, byte data[])
339{
340 byte i;
341 byte left[8];
342 byte right[8];
343 byte *p = left;
344
345 short DESShift = (mode & DES_RIGHT) ? 0x8103 : 0xc081;
346
347 for(i=3; i>0; i--)
348 {
349 *p = (key[i-1] << 4) | (key[i] >> 4);
350 p++;
351 }
352 left[3] = key[0] >> 4;
353 right[0] = key[6];
354 right[1] = key[5];
355 right[2] = key[4];
356 right[3] = key[3] & 0x0f;
357
358 if(mode & DES_IP) doIp(data);
359
360 do {
361 if(!(mode & DES_RIGHT))
362 {
363 leftRotKeys(left, right);
364 if(!(DESShift & 0x8000)) leftRotKeys(left, right);
365 }
366 desRound(left, right, data, mode, key[7]);
367
368 if(mode & DES_RIGHT)
369 {
370 rightRotKeys(left, right);
371 if(!(DESShift & 0x8000)) rightRotKeys(left, right);
372 }
373 DESShift <<= 1;
374 } while(DESShift);
375
376 swap(data, data+4);
377 if(mode & DES_IP_1) doIp_1(data);
378
379}
380
381static byte getmask(byte *OutData, byte *Mask, byte I, byte J)
382{
383 byte K, B, M, M1 , D, DI, MI;
384
385 K = I ^ J;
386 DI = 7;
387 if ((K & 4) == 4) {
388 K ^= 7;
389 DI ^= 7;
390 }
391 MI = 3;
392 MI &= J;
393 K ^= MI;
394 K += MI;
395 if ((K & 4) == 4) {
396 return 0;
397 }
398 DI ^= J;
399 D = OutData[DI];
400 MI = 0;
401 MI += J;
402 M1 = Mask[MI];
403 MI ^= 4;
404 M = Mask[MI];
405 B = 0;
406 for(K = 0; K <=7; K++)
407 {
408 if ((D & 1) == 1) B += M;
409 D = (D >> 1) + ((B & 1) << 7);
410 B = B >> 1;
411 }
412 return D ^ M1;
413}
414
415static void v2mask(byte *cw, byte *mask)
416{
417 int i, j;
418
419 for(i = 7; i >= 0; i--)
420 for(j = 7; j >=4; j--)
421 cw[i] ^= getmask(cw, mask, i, j);
422 for(i = 0; i <= 7; i++)
423 for(j = 0; j <=3; j++)
424 cw[i] ^= getmask(cw, mask, i, j);
425}
426
427
428void EuroDes(byte key1[], byte key2[], byte desMode, byte operatingMode, byte data[])
429{
430 byte mode;
431
432 if(key1[7]) { /* Viaccess */
433 mode = (operatingMode == HASH) ? DES_ECM_HASH : DES_ECM_CRYPT;
434
435 if(key2 != NULL)
436 v2mask(data, key2);
437 des(key1, mode, data);
438 if(key2 != NULL)
439 v2mask(data, key2);
440 }
441 else if(TestBit(desMode, F_TRIPLE_DES))
442 {
443 /* Eurocrypt 3-DES */
444 mode = (operatingMode == HASH) ? 0 : DES_RIGHT;
445 des(key1, (byte)(DES_IP | mode), data);
446
447 mode ^= DES_RIGHT;
448 des(key2, mode, data);
449
450 mode ^= DES_RIGHT;
451 des(key1, (byte)(mode | DES_IP_1), data);
452 }
453 else
454 {
455 if(TestBit(desMode, F_EURO_S2))
456 {
457 /* Eurocrypt S2 */
458 mode = (operatingMode == HASH) ? DES_ECS2_CRYPT : DES_ECS2_DECRYPT;
459 }
460 else
461 {
462 /* Eurocrypt M */
463 mode = (operatingMode == HASH) ? DES_ECM_HASH : DES_ECM_CRYPT;
464 }
465 des(key1, mode, data);
466 }
467}
468
469/*------------------------------------------------------------------------*/
470static void des_key_parity_adjust(byte *key, byte len)
471{
472 byte i, j, parity;
473
474 for (i = 0; i < len; i++)
475 {
476 parity = 1;
477 for (j = 1; j < 8; j++) if ((key[i] >> j) & 0x1) parity = ~parity & 0x01;
478 key[i] |= parity;
479 }
480}
481
482static byte *des_key_spread(byte *normal)
483{
484 static byte spread[16];
485
486 spread[ 0] = normal[ 0] & 0xfe;
487 spread[ 1] = ((normal[ 0] << 7) | (normal[ 1] >> 1)) & 0xfe;
488 spread[ 2] = ((normal[ 1] << 6) | (normal[ 2] >> 2)) & 0xfe;
489 spread[ 3] = ((normal[ 2] << 5) | (normal[ 3] >> 3)) & 0xfe;
490 spread[ 4] = ((normal[ 3] << 4) | (normal[ 4] >> 4)) & 0xfe;
491 spread[ 5] = ((normal[ 4] << 3) | (normal[ 5] >> 5)) & 0xfe;
492 spread[ 6] = ((normal[ 5] << 2) | (normal[ 6] >> 6)) & 0xfe;
493 spread[ 7] = normal[ 6] << 1;
494 spread[ 8] = normal[ 7] & 0xfe;
495 spread[ 9] = ((normal[ 7] << 7) | (normal[ 8] >> 1)) & 0xfe;
496 spread[10] = ((normal[ 8] << 6) | (normal[ 9] >> 2)) & 0xfe;
497 spread[11] = ((normal[ 9] << 5) | (normal[10] >> 3)) & 0xfe;
498 spread[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;
499 spread[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;
500 spread[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;
501 spread[15] = normal[13] << 1;
502
503 des_key_parity_adjust(spread, 16);
504 return spread;
505}
506
507static void des_random_get(byte *buffer, byte len)
508{
509 byte idx = 0;
510 int randomNo = 0;
511
512 for (idx = 0; idx < len; idx++)
513 {
514 if (!(idx % 3)) randomNo = rand();
515 buffer[idx] = (randomNo >> ((idx % 3) << 3)) & 0xff;
516 }
517}
518
519#define CWS_NETMSGSIZE 256
520
521int des_encrypt(byte *buffer, int len, byte *deskey)
522{
523 byte checksum = 0;
524 byte noPadBytes;
525 byte padBytes[7];
526 char ivec[8];
527 short i;
528
529 if (!deskey) return len;
530 noPadBytes = (8 - ((len - 1) % 8)) % 8;
531 if (len + noPadBytes + 1 >= CWS_NETMSGSIZE-8) return -1;
532 des_random_get(padBytes, noPadBytes);
533 for (i = 0; i < noPadBytes; i++) buffer[len++] = padBytes[i];
534 for (i = 2; i < len; i++) checksum ^= buffer[i];
535 buffer[len++] = checksum;
536 des_random_get((byte *)ivec, 8);
537 memcpy(buffer+len, ivec, 8);
538 for (i = 2; i < len; i += 8)
539 {
540 byte j;
541 const byte flags = (1 << F_EURO_S2) | (1 << F_TRIPLE_DES);
542 for(j=0; j<8; j++) buffer[i+j] ^= ivec[j];
543 EuroDes(deskey, deskey+8, flags, 1, buffer+i);
544 memcpy(ivec, buffer+i, 8);
545 }
546 len += 8;
547 return len;
548}
549
550int des_decrypt(byte *buffer, int len, byte *deskey)
551{
552 char ivec[8];
553 char nextIvec[8];
554 int i;
555 byte checksum = 0;
556
557 if (!deskey) return len;
558 if ((len-2) % 8 || (len-2) < 16) return -1;
559 len -= 8;
560 memcpy(nextIvec, buffer+len, 8);
561 for (i = 2; i < len; i += 8)
562 {
563 byte j;
564 const byte flags = (1 << F_EURO_S2) | (1 << F_TRIPLE_DES);
565
566 memcpy(ivec, nextIvec, 8);
567 memcpy(nextIvec, buffer+i, 8);
568 EuroDes(deskey, deskey+8, flags, 0, buffer+i);
569 for(j=0; j<8; j++)
570 buffer[i+j] ^= ivec[j];
571 }
572 for (i = 2; i < len; i++) checksum ^= buffer[i];
573 if (checksum) return -1;
574 return len;
575}
576
577byte *des_login_key_get(byte *key1, byte *key2, int len)
578{
579 byte des14[14];
580 static byte *des16;
581 int i;
582
583 memcpy(des14, key1, sizeof(des14));
584 for (i = 0; i < len; i++) des14[i%14] ^= key2[i];
585 des16 = des_key_spread(des14);
586 doPC1(des16);
587 doPC1(des16+8);
588 return des16;
589}
Note: See TracBrowser for help on using the repository browser.