revert breaks some stupid old compilers
[oscam.git] / module-newcamd-des.c
blob3e687d8f6b806b4e63702abdb42c00397cabab02
1 #include "globals.h"
2 #include "module-newcamd-des.h"
3 #include "oscam-string.h"
5 #define DES_IP 1
6 #define DES_IP_1 2
7 #define DES_RIGHT 4
8 #define DES_HASH 8
10 #define DES_ECM_CRYPT 0
11 #define DES_ECM_HASH DES_HASH
12 #define DES_ECS2_DECRYPT (DES_IP | DES_IP_1 | DES_RIGHT)
13 #define DES_ECS2_CRYPT (DES_IP | DES_IP_1)
16 #define CRYPT 0
17 #define HASH 1
18 #define F_EURO_S2 0
19 #define F_TRIPLE_DES 1
21 #define TestBit(addr, bit) ((addr) & (1 << bit))
23 extern const int32_t CWS_NETMSGSIZE;
25 static const unsigned char PC2[8][6] =
27 { 14, 17, 11, 24, 1, 5 },
28 { 3, 28, 15, 6, 21, 10 },
29 { 23, 19, 12, 4, 26, 8 },
30 { 16, 7, 27, 20, 13, 2 },
31 { 41, 52, 31, 37, 47, 55 },
32 { 30, 40, 51, 45, 33, 48 },
33 { 44, 49, 39, 56, 34, 53 },
34 { 46, 42, 50, 36, 29, 32 }
38 static const unsigned char E[8][6] =
40 { 32, 1, 2, 3, 4, 5 },
41 { 4, 5, 6, 7, 8, 9 },
42 { 8, 9, 10, 11, 12, 13 },
43 { 12, 13, 14, 15, 16, 17 },
44 { 16, 17, 18, 19, 20, 21 },
45 { 20, 21, 22, 23, 24, 25 },
46 { 24, 25, 26, 27, 28, 29 },
47 { 28, 29, 30, 31, 32, 1 }
50 static const unsigned char P[32] =
52 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
53 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
56 static const unsigned char SBOXES[4][64] =
59 0x2e, 0xe0, 0xc4, 0xbf, 0x4d, 0x27, 0x11, 0xc4,
60 0x72, 0x4e, 0xaf, 0x72, 0xbb, 0xdd, 0x68, 0x11,
61 0x83, 0x5a, 0x5a, 0x06, 0x36, 0xfc, 0xfc, 0xab,
62 0xd5, 0x39, 0x09, 0x95, 0xe0, 0x83, 0x97, 0x68,
63 0x44, 0xbf, 0x21, 0x8c, 0x1e, 0xc8, 0xb8, 0x72,
64 0xad, 0x14, 0xd6, 0xe9, 0x72, 0x21, 0x8b, 0xd7,
65 0xff, 0x65, 0x9c, 0xfb, 0xc9, 0x03, 0x57, 0x9e,
66 0x63, 0xaa, 0x3a, 0x40, 0x05, 0x56, 0xe0, 0x3d
69 0xcf, 0xa3, 0x11, 0xfd, 0xa8, 0x44, 0xfe, 0x27,
70 0x96, 0x7f, 0x2b, 0xc2, 0x63, 0x98, 0x84, 0x5e,
71 0x09, 0x6c, 0xd7, 0x10, 0x32, 0xd1, 0x4d, 0xea,
72 0xec, 0x06, 0x70, 0xb9, 0x55, 0x3b, 0xba, 0x85,
73 0x90, 0x4d, 0xee, 0x38, 0xf7, 0x2a, 0x5b, 0xc1,
74 0x2a, 0x93, 0x84, 0x5f, 0xcd, 0xf4, 0x31, 0xa2,
75 0x75, 0xbb, 0x08, 0xe6, 0x4c, 0x17, 0xa6, 0x7c,
76 0x19, 0x60, 0xd3, 0x05, 0xb2, 0x8e, 0x6f, 0xd9
79 0x4a, 0xdd, 0xb0, 0x07, 0x29, 0xb0, 0xee, 0x79,
80 0xf6, 0x43, 0x03, 0x94, 0x8f, 0x16, 0xd5, 0xaa,
81 0x31, 0xe2, 0xcd, 0x38, 0x9c, 0x55, 0x77, 0xce,
82 0x5b, 0x2c, 0xa4, 0xfb, 0x62, 0x8f, 0x18, 0x61,
83 0x1d, 0x61, 0x46, 0xba, 0xb4, 0xdd, 0xd9, 0x80,
84 0xc8, 0x16, 0x3f, 0x49, 0x73, 0xa8, 0xe0, 0x77,
85 0xab, 0x94, 0xf1, 0x5f, 0x62, 0x0e, 0x8c, 0xf3,
86 0x05, 0xeb, 0x5a, 0x25, 0x9e, 0x32, 0x27, 0xcc
89 0xd7, 0x1d, 0x2d, 0xf8, 0x8e, 0xdb, 0x43, 0x85,
90 0x60, 0xa6, 0xf6, 0x3f, 0xb9, 0x70, 0x1a, 0x43,
91 0xa1, 0xc4, 0x92, 0x57, 0x38, 0x62, 0xe5, 0xbc,
92 0x5b, 0x01, 0x0c, 0xea, 0xc4, 0x9e, 0x7f, 0x29,
93 0x7a, 0x23, 0xb6, 0x1f, 0x49, 0xe0, 0x10, 0x76,
94 0x9c, 0x4a, 0xcb, 0xa1, 0xe7, 0x8d, 0x2d, 0xd8,
95 0x0f, 0xf9, 0x61, 0xc4, 0xa3, 0x95, 0xde, 0x0b,
96 0xf5, 0x3c, 0x32, 0x57, 0x58, 0x62, 0x84, 0xbe
100 static const unsigned char PC1[][8] =
102 {57, 49, 41, 33, 25, 17, 9, 1},
103 {58, 50, 42, 34, 26, 18, 10, 2},
104 {59, 51, 43, 35, 27, 19, 11, 3},
105 {60, 52, 44, 36, 63, 55, 47, 39},
106 {31, 23, 15, 7, 62, 54, 46, 38},
107 {30, 22, 14, 6, 61, 53, 45, 37},
108 {29, 21, 13, 5, 28, 20, 12, 4}
111 void doPC1(unsigned char data[])
113 unsigned char buf[8];
114 unsigned char i, j;
116 memset(buf, 0, 8);
118 for(j = 0; j < 7; j++)
120 for(i = 0; i < 8; i++)
122 unsigned char lookup = PC1[j][i];
123 buf[j] |= ((data[(lookup >> 3)] >> (8 - (lookup & 7))) & 1) << (7 - i);
127 memcpy(data, buf, 8);
130 static void doIp(unsigned char data[])
132 unsigned char j, k;
133 unsigned char val;
134 unsigned char buf[8];
135 unsigned char *p;
136 unsigned char i = 8;
137 memset(buf, 0, sizeof(buf));
139 for(i = 0; i < 8; i++)
141 val = data[i];
142 p = &buf[3];
143 j = 4;
147 for(k = 0; k <= 4; k += 4)
149 p[k] >>= 1;
150 if(val & 1) { p[k] |= 0x80; }
151 val >>= 1;
153 p--;
155 while(--j);
158 memcpy(data, buf, 8);
161 static void doIp_1(unsigned char data[])
163 unsigned char j, k;
164 unsigned char r = 0;
165 unsigned char buf[8];
166 unsigned char *p;
167 unsigned char i = 8;
169 for(i = 0; i < 8; i++)
171 p = &data[3];
172 j = 4;
176 for(k = 0; k <= 4; k += 4)
178 r >>= 1;
179 if(p[k] & 1) { r |= 0x80; }
180 p[k] >>= 1;
182 p--;
184 while(--j);
185 buf[i] = r;
188 memcpy(data, buf, 8);
191 static void makeK(unsigned char *left, unsigned char *right, unsigned char *K)
193 unsigned char i, j;
194 unsigned char bit, val;
195 unsigned char *p;
197 for(i = 0; i < 8; i++)
199 val = 0;
200 for(j = 0; j < 6; j++)
202 bit = PC2[i][j];
203 if(bit < 29)
205 bit = 28 - bit;
206 p = left;
208 else
210 bit = 56 - bit;
211 p = right;
213 val <<= 1;
214 if(p[bit >> 3] & (1 << (bit & 7))) { val |= 1; }
216 *K = val;
217 K++;
221 static void rightRot(unsigned char key[])
223 unsigned char *p = key;
224 unsigned char i = 3;
225 unsigned char carry = 0;
227 carry = 0;
229 if(*p & 1) { carry = 0x08; }
233 *p = (*p >> 1) | ((p[1] & 1) ? 0x80 : 0);
234 p++;
236 while(--i);
238 *p = (*p >> 1) | carry;
241 static void rightRotKeys(unsigned char left[], unsigned char right[])
243 rightRot(left);
244 rightRot(right);
247 static void leftRot(unsigned char key[])
249 unsigned char i = 27;
253 rightRot(key);
255 while(--i);
258 static void leftRotKeys(unsigned char left[], unsigned char right[])
260 leftRot(left);
261 leftRot(right);
264 static void desCore(unsigned char data[], unsigned char K[], unsigned char result[])
266 unsigned char i, j;
267 unsigned char bit, val;
269 memset(result, 0, 4);
271 for(i = 0; i < 8; i++)
273 val = 0;
274 for(j = 0; j < 6; j++)
276 bit = 32 - E[i][j];
277 val <<= 1;
278 if(data[3 - (bit >> 3)] & (1 << (bit & 7))) { val |= 1; }
280 val ^= K[i];
281 val = SBOXES[i & 3][val];
282 if(i > 3)
284 val >>= 4;
286 val &= 0x0f;
287 result[i >> 1] |= (i & 1) ? val : (val << 4);
291 static void permut32(unsigned char data[])
293 unsigned char i, j;
294 unsigned char bit;
295 unsigned char r[4] = {0}; // init to keep Valgrind happy
296 unsigned char *p;
298 for(i = 0; i < 32; i++)
300 bit = 32 - P[i];
301 p = r;
302 for(j = 0; j < 3; j++)
304 *p = (*p << 1) | ((p[1] & 0x80) ? 1 : 0);
305 p++;
307 *p <<= 1;
308 if(data[3 - (bit >> 3)] & (1 << (bit & 7))) { *p |= 1; }
311 memcpy(data, r, 4);
314 static void swap(unsigned char left[], unsigned char right[])
316 unsigned char x[4];
318 memcpy(x, right, 4);
319 memcpy(right, left, 4);
320 memcpy(left, x, 4);
323 static void desRound(unsigned char left[], unsigned char right[], unsigned char data[], unsigned char mode, unsigned char k8)
325 unsigned char i;
326 unsigned char K[8];
327 unsigned char r[4];
328 unsigned char tempr[4];
329 unsigned short temp;
331 memcpy(tempr, data + 4, 4);
333 /* Viaccess */
334 temp = (short)k8 * (short)tempr[0] + (short)k8 + (short)tempr[0];
335 tempr[0] = (temp & 0xff) - ((temp >> 8) & 0xff);
336 if((temp & 0xff) - (temp >> 8) < 0)
337 { tempr[0]++; }
339 makeK(left, right, K);
340 desCore(tempr, K, r);
341 permut32(r);
343 if(mode & DES_HASH)
345 i = r[0];
346 r[0] = r[1];
347 r[1] = i;
350 for(i = 0; i < 4; i++)
352 *data ^= r[i];
353 data++;
356 swap(data - 4, data);
359 static void nc_des(unsigned char key[], unsigned char mode, unsigned char data[])
361 unsigned char i;
362 unsigned char left[8];
363 unsigned char right[8];
364 unsigned char *p = left;
366 short DESShift = (mode & DES_RIGHT) ? 0x8103 : 0xc081;
368 for(i = 3; i > 0; i--)
370 *p = (key[i - 1] << 4) | (key[i] >> 4);
371 p++;
373 left[3] = key[0] >> 4;
374 right[0] = key[6];
375 right[1] = key[5];
376 right[2] = key[4];
377 right[3] = key[3] & 0x0f;
379 if(mode & DES_IP) { doIp(data); }
383 if(!(mode & DES_RIGHT))
385 leftRotKeys(left, right);
386 if(!(DESShift & 0x8000)) { leftRotKeys(left, right); }
388 desRound(left, right, data, mode, key[7]);
390 if(mode & DES_RIGHT)
392 rightRotKeys(left, right);
393 if(!(DESShift & 0x8000)) { rightRotKeys(left, right); }
395 DESShift <<= 1;
397 while(DESShift);
399 swap(data, data + 4);
400 if(mode & DES_IP_1) { doIp_1(data); }
404 /*------------------------------------------------------------------------*/
405 static void des_key_parity_adjust(unsigned char *key, unsigned char len)
407 unsigned char i, j, parity;
409 for(i = 0; i < len; i++)
411 parity = 1;
412 for(j = 1; j < 8; j++) if((key[i] >> j) & 0x1) { parity = ~parity & 0x01; }
413 key[i] |= parity;
417 static unsigned char *des_key_spread(unsigned char *normal, unsigned char *spread)
419 spread[ 0] = normal[ 0] & 0xfe;
420 spread[ 1] = ((normal[ 0] << 7) | (normal[ 1] >> 1)) & 0xfe;
421 spread[ 2] = ((normal[ 1] << 6) | (normal[ 2] >> 2)) & 0xfe;
422 spread[ 3] = ((normal[ 2] << 5) | (normal[ 3] >> 3)) & 0xfe;
423 spread[ 4] = ((normal[ 3] << 4) | (normal[ 4] >> 4)) & 0xfe;
424 spread[ 5] = ((normal[ 4] << 3) | (normal[ 5] >> 5)) & 0xfe;
425 spread[ 6] = ((normal[ 5] << 2) | (normal[ 6] >> 6)) & 0xfe;
426 spread[ 7] = normal[ 6] << 1;
427 spread[ 8] = normal[ 7] & 0xfe;
428 spread[ 9] = ((normal[ 7] << 7) | (normal[ 8] >> 1)) & 0xfe;
429 spread[10] = ((normal[ 8] << 6) | (normal[ 9] >> 2)) & 0xfe;
430 spread[11] = ((normal[ 9] << 5) | (normal[10] >> 3)) & 0xfe;
431 spread[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;
432 spread[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;
433 spread[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;
434 spread[15] = normal[13] << 1;
436 des_key_parity_adjust(spread, 16);
437 return spread;
440 static void des_random_get(unsigned char *buffer, unsigned char len)
442 unsigned char idx = 0;
443 int randomNo = 0;
445 for(idx = 0; idx < len; idx++)
447 if(!(idx % 3)) { randomNo = rand(); }
448 buffer[idx] = (randomNo >> ((idx % 3) << 3)) & 0xff;
452 static unsigned char getmask(unsigned char *OutData, unsigned char *Mask, unsigned char I, unsigned char J)
454 unsigned char K, B, M, M1 , D, DI, MI;
456 K = I ^ J;
457 DI = 7;
458 if((K & 4) == 4)
460 K ^= 7;
461 DI ^= 7;
463 MI = 3;
464 MI &= J;
465 K ^= MI;
466 K += MI;
467 if((K & 4) == 4)
469 return 0;
471 DI ^= J;
472 D = OutData[DI];
473 MI = 0;
474 MI += J;
475 M1 = Mask[MI];
476 MI ^= 4;
477 M = Mask[MI];
478 B = 0;
479 for(K = 0; K <= 7; K++)
481 if((D & 1) == 1) { B += M; }
482 D = (D >> 1) + ((B & 1) << 7);
483 B = B >> 1;
485 return D ^ M1;
488 static void v2mask(unsigned char *cw, unsigned char *mask)
490 int i, j;
492 for(i = 7; i >= 0; i--)
493 for(j = 7; j >= 4; j--)
494 { cw[i] ^= getmask(cw, mask, i, j); }
495 for(i = 0; i <= 7; i++)
496 for(j = 0; j <= 3; j++)
497 { cw[i] ^= getmask(cw, mask, i, j); }
500 static void EuroDes(unsigned char key1[], unsigned char key2[], unsigned char desMode, unsigned char operatingMode, unsigned char data[])
502 unsigned char mode;
504 if(key1[7]) /* Viaccess */
506 mode = (operatingMode == HASH) ? DES_ECM_HASH : DES_ECM_CRYPT;
508 if(key2 != NULL)
509 { v2mask(data, key2); }
510 nc_des(key1, mode, data);
511 if(key2 != NULL)
512 { v2mask(data, key2); }
514 else if(TestBit(desMode, F_TRIPLE_DES))
516 /* Eurocrypt 3-DES */
517 mode = (operatingMode == HASH) ? 0 : DES_RIGHT;
518 nc_des(key1, (unsigned char)(DES_IP | mode), data);
520 mode ^= DES_RIGHT;
521 nc_des(key2, mode, data);
523 mode ^= DES_RIGHT;
524 nc_des(key1, (unsigned char)(mode | DES_IP_1), data);
526 else
528 if(TestBit(desMode, F_EURO_S2))
530 /* Eurocrypt S2 */
531 mode = (operatingMode == HASH) ? DES_ECS2_CRYPT : DES_ECS2_DECRYPT;
533 else
535 /* Eurocrypt M */
536 mode = (operatingMode == HASH) ? DES_ECM_HASH : DES_ECM_CRYPT;
538 nc_des(key1, mode, data);
542 int nc_des_encrypt(unsigned char *buffer, int len, unsigned char *deskey)
544 unsigned char checksum = 0;
545 unsigned char noPadBytes;
546 unsigned char padBytes[7];
547 char ivec[8];
548 short i;
550 if(!deskey) { return len; }
551 noPadBytes = (8 - ((len - 1) % 8)) % 8;
552 if(len + noPadBytes + 1 >= CWS_NETMSGSIZE - 8) { return -1; }
553 des_random_get(padBytes, noPadBytes);
554 for(i = 0; i < noPadBytes; i++) { buffer[len++] = padBytes[i]; }
555 for(i = 2; i < len; i++) { checksum ^= buffer[i]; }
556 buffer[len++] = checksum;
557 des_random_get((unsigned char *)ivec, 8);
558 memcpy(buffer + len, ivec, 8);
559 for(i = 2; i < len; i += 8)
561 unsigned char j;
562 const unsigned char flags = (1 << F_EURO_S2) | (1 << F_TRIPLE_DES);
563 for(j = 0; j < 8; j++) { buffer[i + j] ^= ivec[j]; }
564 EuroDes(deskey, deskey + 8, flags, HASH, buffer + i);
565 memcpy(ivec, buffer + i, 8);
567 len += 8;
568 return len;
571 int nc_des_decrypt(unsigned char *buffer, int len, unsigned char *deskey)
573 char ivec[8];
574 char nextIvec[8];
575 int i;
576 unsigned char checksum = 0;
578 if(!deskey) { return len; }
579 if((len - 2) % 8 || (len - 2) < 16) { return -1; }
580 len -= 8;
581 memcpy(nextIvec, buffer + len, 8);
582 for(i = 2; i < len; i += 8)
584 unsigned char j;
585 const unsigned char flags = (1 << F_EURO_S2) | (1 << F_TRIPLE_DES);
587 memcpy(ivec, nextIvec, 8);
588 memcpy(nextIvec, buffer + i, 8);
589 EuroDes(deskey, deskey + 8, flags, CRYPT, buffer + i);
590 for(j = 0; j < 8; j++)
591 { buffer[i + j] ^= ivec[j]; }
593 for(i = 2; i < len; i++) { checksum ^= buffer[i]; }
594 if(checksum) { return -1; }
595 return len;
598 unsigned char *nc_des_login_key_get(unsigned char *key1, unsigned char *key2, int len, unsigned char *des16)
600 unsigned char des14[14];
601 int i;
603 memcpy(des14, key1, sizeof(des14));
604 for(i = 0; i < len; i++) { des14[i % 14] ^= key2[i]; }
605 des16 = des_key_spread(des14, des16);
606 doPC1(des16);
607 doPC1(des16 + 8);
608 return des16;