- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / module-newcamd-des.c
blob11fc28e8d68cbf9439fc2b4d82cdc7fc7890d1a9
1 #include "globals.h"
2 #include "module-newcamd-des.h"
3 #include "oscam-string.h"
5 #define DES_ECS2_DECRYPT (DES_IP | DES_IP_1 | DES_RIGHT)
6 #define DES_ECS2_CRYPT (DES_IP | DES_IP_1)
8 #define CRYPT 0
9 #define HASH 1
10 #define F_EURO_S2 0
11 #define F_TRIPLE_DES 1
13 #define TestBit(addr, bit) ((addr) & (1 << bit))
15 extern const int32_t CWS_NETMSGSIZE;
17 static const uint8_t PC2[8][6] =
19 { 14, 17, 11, 24, 1, 5 },
20 { 3, 28, 15, 6, 21, 10 },
21 { 23, 19, 12, 4, 26, 8 },
22 { 16, 7, 27, 20, 13, 2 },
23 { 41, 52, 31, 37, 47, 55 },
24 { 30, 40, 51, 45, 33, 48 },
25 { 44, 49, 39, 56, 34, 53 },
26 { 46, 42, 50, 36, 29, 32 }
30 static const uint8_t E[8][6] =
32 { 32, 1, 2, 3, 4, 5 },
33 { 4, 5, 6, 7, 8, 9 },
34 { 8, 9, 10, 11, 12, 13 },
35 { 12, 13, 14, 15, 16, 17 },
36 { 16, 17, 18, 19, 20, 21 },
37 { 20, 21, 22, 23, 24, 25 },
38 { 24, 25, 26, 27, 28, 29 },
39 { 28, 29, 30, 31, 32, 1 }
42 static const uint8_t P[32] =
44 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
45 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
48 static const uint8_t SBOXES[4][64] =
51 0x2e, 0xe0, 0xc4, 0xbf, 0x4d, 0x27, 0x11, 0xc4,
52 0x72, 0x4e, 0xaf, 0x72, 0xbb, 0xdd, 0x68, 0x11,
53 0x83, 0x5a, 0x5a, 0x06, 0x36, 0xfc, 0xfc, 0xab,
54 0xd5, 0x39, 0x09, 0x95, 0xe0, 0x83, 0x97, 0x68,
55 0x44, 0xbf, 0x21, 0x8c, 0x1e, 0xc8, 0xb8, 0x72,
56 0xad, 0x14, 0xd6, 0xe9, 0x72, 0x21, 0x8b, 0xd7,
57 0xff, 0x65, 0x9c, 0xfb, 0xc9, 0x03, 0x57, 0x9e,
58 0x63, 0xaa, 0x3a, 0x40, 0x05, 0x56, 0xe0, 0x3d
61 0xcf, 0xa3, 0x11, 0xfd, 0xa8, 0x44, 0xfe, 0x27,
62 0x96, 0x7f, 0x2b, 0xc2, 0x63, 0x98, 0x84, 0x5e,
63 0x09, 0x6c, 0xd7, 0x10, 0x32, 0xd1, 0x4d, 0xea,
64 0xec, 0x06, 0x70, 0xb9, 0x55, 0x3b, 0xba, 0x85,
65 0x90, 0x4d, 0xee, 0x38, 0xf7, 0x2a, 0x5b, 0xc1,
66 0x2a, 0x93, 0x84, 0x5f, 0xcd, 0xf4, 0x31, 0xa2,
67 0x75, 0xbb, 0x08, 0xe6, 0x4c, 0x17, 0xa6, 0x7c,
68 0x19, 0x60, 0xd3, 0x05, 0xb2, 0x8e, 0x6f, 0xd9
71 0x4a, 0xdd, 0xb0, 0x07, 0x29, 0xb0, 0xee, 0x79,
72 0xf6, 0x43, 0x03, 0x94, 0x8f, 0x16, 0xd5, 0xaa,
73 0x31, 0xe2, 0xcd, 0x38, 0x9c, 0x55, 0x77, 0xce,
74 0x5b, 0x2c, 0xa4, 0xfb, 0x62, 0x8f, 0x18, 0x61,
75 0x1d, 0x61, 0x46, 0xba, 0xb4, 0xdd, 0xd9, 0x80,
76 0xc8, 0x16, 0x3f, 0x49, 0x73, 0xa8, 0xe0, 0x77,
77 0xab, 0x94, 0xf1, 0x5f, 0x62, 0x0e, 0x8c, 0xf3,
78 0x05, 0xeb, 0x5a, 0x25, 0x9e, 0x32, 0x27, 0xcc
81 0xd7, 0x1d, 0x2d, 0xf8, 0x8e, 0xdb, 0x43, 0x85,
82 0x60, 0xa6, 0xf6, 0x3f, 0xb9, 0x70, 0x1a, 0x43,
83 0xa1, 0xc4, 0x92, 0x57, 0x38, 0x62, 0xe5, 0xbc,
84 0x5b, 0x01, 0x0c, 0xea, 0xc4, 0x9e, 0x7f, 0x29,
85 0x7a, 0x23, 0xb6, 0x1f, 0x49, 0xe0, 0x10, 0x76,
86 0x9c, 0x4a, 0xcb, 0xa1, 0xe7, 0x8d, 0x2d, 0xd8,
87 0x0f, 0xf9, 0x61, 0xc4, 0xa3, 0x95, 0xde, 0x0b,
88 0xf5, 0x3c, 0x32, 0x57, 0x58, 0x62, 0x84, 0xbe
92 static const uint8_t PC1[][8] =
94 {57, 49, 41, 33, 25, 17, 9, 1},
95 {58, 50, 42, 34, 26, 18, 10, 2},
96 {59, 51, 43, 35, 27, 19, 11, 3},
97 {60, 52, 44, 36, 63, 55, 47, 39},
98 {31, 23, 15, 7, 62, 54, 46, 38},
99 {30, 22, 14, 6, 61, 53, 45, 37},
100 {29, 21, 13, 5, 28, 20, 12, 4}
103 void doPC1(uint8_t data[])
105 uint8_t buf[8];
106 uint8_t i, j;
108 memset(buf, 0, 8);
110 for(j = 0; j < 7; j++)
112 for(i = 0; i < 8; i++)
114 uint8_t lookup = PC1[j][i];
115 buf[j] |= ((data[(lookup >> 3)] >> (8 - (lookup & 7))) & 1) << (7 - i);
119 memcpy(data, buf, 8);
122 static void doIp(uint8_t data[])
124 uint8_t j, k;
125 uint8_t val;
126 uint8_t buf[8];
127 uint8_t *p;
128 uint8_t i = 8;
129 memset(buf, 0, sizeof(buf));
131 for(i = 0; i < 8; i++)
133 val = data[i];
134 p = &buf[3];
135 j = 4;
139 for(k = 0; k <= 4; k += 4)
141 p[k] >>= 1;
142 if(val & 1) { p[k] |= 0x80; }
143 val >>= 1;
145 p--;
147 while(--j);
150 memcpy(data, buf, 8);
153 static void doIp_1(uint8_t data[])
155 uint8_t j, k;
156 uint8_t r = 0;
157 uint8_t buf[8];
158 uint8_t *p;
159 uint8_t i = 8;
161 for(i = 0; i < 8; i++)
163 p = &data[3];
164 j = 4;
168 for(k = 0; k <= 4; k += 4)
170 r >>= 1;
171 if(p[k] & 1) { r |= 0x80; }
172 p[k] >>= 1;
174 p--;
176 while(--j);
177 buf[i] = r;
180 memcpy(data, buf, 8);
183 static void makeK(uint8_t *left, uint8_t *right, uint8_t *K)
185 uint8_t i, j;
186 uint8_t bit, val;
187 uint8_t *p;
189 for(i = 0; i < 8; i++)
191 val = 0;
192 for(j = 0; j < 6; j++)
194 bit = PC2[i][j];
195 if(bit < 29)
197 bit = 28 - bit;
198 p = left;
200 else
202 bit = 56 - bit;
203 p = right;
205 val <<= 1;
206 if(p[bit >> 3] & (1 << (bit & 7))) { val |= 1; }
208 *K = val;
209 K++;
213 static void rightRot(uint8_t key[])
215 uint8_t *p = key;
216 uint8_t i = 3;
217 uint8_t carry = 0;
219 carry = 0;
221 if(*p & 1) { carry = 0x08; }
225 *p = (*p >> 1) | ((p[1] & 1) ? 0x80 : 0);
226 p++;
228 while(--i);
230 *p = (*p >> 1) | carry;
233 static void rightRotKeys(uint8_t left[], uint8_t right[])
235 rightRot(left);
236 rightRot(right);
239 static void leftRot(uint8_t key[])
241 uint8_t i = 27;
245 rightRot(key);
247 while(--i);
250 static void leftRotKeys(uint8_t left[], uint8_t right[])
252 leftRot(left);
253 leftRot(right);
256 static void desCore(uint8_t data[], uint8_t K[], uint8_t result[])
258 uint8_t i, j;
259 uint8_t bit, val;
261 memset(result, 0, 4);
263 for(i = 0; i < 8; i++)
265 val = 0;
266 for(j = 0; j < 6; j++)
268 bit = 32 - E[i][j];
269 val <<= 1;
270 if(data[3 - (bit >> 3)] & (1 << (bit & 7))) { val |= 1; }
272 val ^= K[i];
273 val = SBOXES[i & 3][val];
274 if(i > 3)
276 val >>= 4;
278 val &= 0x0f;
279 result[i >> 1] |= (i & 1) ? val : (val << 4);
283 static void permut32(uint8_t data[])
285 uint8_t i, j;
286 uint8_t bit;
287 uint8_t r[4] = {0}; // init to keep Valgrind happy
288 uint8_t *p;
290 for(i = 0; i < 32; i++)
292 bit = 32 - P[i];
293 p = r;
294 for(j = 0; j < 3; j++)
296 *p = (*p << 1) | ((p[1] & 0x80) ? 1 : 0);
297 p++;
299 *p <<= 1;
300 if(data[3 - (bit >> 3)] & (1 << (bit & 7))) { *p |= 1; }
303 memcpy(data, r, 4);
306 static void swap(uint8_t left[], uint8_t right[])
308 uint8_t x[4];
310 memcpy(x, right, 4);
311 memcpy(right, left, 4);
312 memcpy(left, x, 4);
315 static void desRound(uint8_t left[], uint8_t right[], uint8_t data[], uint8_t mode, uint8_t k8)
317 uint8_t i;
318 uint8_t K[8];
319 uint8_t r[4];
320 uint8_t tempr[4];
321 unsigned short temp;
323 memcpy(tempr, data + 4, 4);
325 /* Viaccess */
326 temp = (short)k8 * (short)tempr[0] + (short)k8 + (short)tempr[0];
327 tempr[0] = (temp & 0xff) - ((temp >> 8) & 0xff);
328 if((temp & 0xff) - (temp >> 8) < 0)
329 { tempr[0]++; }
331 makeK(left, right, K);
332 desCore(tempr, K, r);
333 permut32(r);
335 if(mode & DES_HASH)
337 i = r[0];
338 r[0] = r[1];
339 r[1] = i;
342 for(i = 0; i < 4; i++)
344 *data ^= r[i];
345 data++;
348 swap(data - 4, data);
351 void nc_des(uint8_t key[], uint8_t mode, uint8_t data[])
353 uint8_t i;
354 uint8_t left[8];
355 uint8_t right[8];
356 uint8_t *p = left;
358 short DESShift = (mode & DES_RIGHT) ? 0x8103 : 0xc081;
360 for(i = 3; i > 0; i--)
362 *p = (key[i - 1] << 4) | (key[i] >> 4);
363 p++;
365 left[3] = key[0] >> 4;
366 right[0] = key[6];
367 right[1] = key[5];
368 right[2] = key[4];
369 right[3] = key[3] & 0x0f;
371 if(mode & DES_IP) { doIp(data); }
375 if(!(mode & DES_RIGHT))
377 leftRotKeys(left, right);
378 if(!(DESShift & 0x8000)) { leftRotKeys(left, right); }
380 desRound(left, right, data, mode, key[7]);
382 if(mode & DES_RIGHT)
384 rightRotKeys(left, right);
385 if(!(DESShift & 0x8000)) { rightRotKeys(left, right); }
387 DESShift <<= 1;
389 while(DESShift);
391 swap(data, data + 4);
392 if(mode & DES_IP_1) { doIp_1(data); }
396 /*------------------------------------------------------------------------*/
397 static void des_key_parity_adjust(uint8_t *key, uint8_t len)
399 uint8_t i, j, parity;
401 for(i = 0; i < len; i++)
403 parity = 1;
404 for(j = 1; j < 8; j++) if((key[i] >> j) & 0x1) { parity = ~parity & 0x01; }
405 key[i] |= parity;
409 static uint8_t *des_key_spread(uint8_t *normal, uint8_t *spread)
411 spread[ 0] = normal[ 0] & 0xfe;
412 spread[ 1] = ((normal[ 0] << 7) | (normal[ 1] >> 1)) & 0xfe;
413 spread[ 2] = ((normal[ 1] << 6) | (normal[ 2] >> 2)) & 0xfe;
414 spread[ 3] = ((normal[ 2] << 5) | (normal[ 3] >> 3)) & 0xfe;
415 spread[ 4] = ((normal[ 3] << 4) | (normal[ 4] >> 4)) & 0xfe;
416 spread[ 5] = ((normal[ 4] << 3) | (normal[ 5] >> 5)) & 0xfe;
417 spread[ 6] = ((normal[ 5] << 2) | (normal[ 6] >> 6)) & 0xfe;
418 spread[ 7] = normal[ 6] << 1;
419 spread[ 8] = normal[ 7] & 0xfe;
420 spread[ 9] = ((normal[ 7] << 7) | (normal[ 8] >> 1)) & 0xfe;
421 spread[10] = ((normal[ 8] << 6) | (normal[ 9] >> 2)) & 0xfe;
422 spread[11] = ((normal[ 9] << 5) | (normal[10] >> 3)) & 0xfe;
423 spread[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;
424 spread[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;
425 spread[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;
426 spread[15] = normal[13] << 1;
428 des_key_parity_adjust(spread, 16);
429 return spread;
432 static void des_random_get(uint8_t *buffer, uint8_t len)
434 uint8_t idx = 0;
435 int randomNo = 0;
437 for(idx = 0; idx < len; idx++)
439 if(!(idx % 3)) { randomNo = rand(); }
440 buffer[idx] = (randomNo >> ((idx % 3) << 3)) & 0xff;
444 static uint8_t getmask(uint8_t *OutData, uint8_t *Mask, uint8_t I, uint8_t J)
446 uint8_t K, B, M, M1 , D, DI, MI;
448 K = I ^ J;
449 DI = 7;
450 if((K & 4) == 4)
452 K ^= 7;
453 DI ^= 7;
455 MI = 3;
456 MI &= J;
457 K ^= MI;
458 K += MI;
459 if((K & 4) == 4)
461 return 0;
463 DI ^= J;
464 D = OutData[DI];
465 MI = 0;
466 MI += J;
467 M1 = Mask[MI];
468 MI ^= 4;
469 M = Mask[MI];
470 B = 0;
471 for(K = 0; K <= 7; K++)
473 if((D & 1) == 1) { B += M; }
474 D = (D >> 1) + ((B & 1) << 7);
475 B = B >> 1;
477 return D ^ M1;
480 static void v2mask(uint8_t *cw, uint8_t *mask)
482 int i, j;
484 for(i = 7; i >= 0; i--)
485 for(j = 7; j >= 4; j--)
486 { cw[i] ^= getmask(cw, mask, i, j); }
487 for(i = 0; i <= 7; i++)
488 for(j = 0; j <= 3; j++)
489 { cw[i] ^= getmask(cw, mask, i, j); }
492 static void EuroDes(uint8_t key1[], uint8_t key2[], uint8_t desMode, uint8_t operatingMode, uint8_t data[])
494 uint8_t mode;
496 if(key1[7]) /* Viaccess */
498 mode = (operatingMode == HASH) ? DES_ECM_HASH : DES_ECM_CRYPT;
500 if(key2 != NULL)
501 { v2mask(data, key2); }
502 nc_des(key1, mode, data);
503 if(key2 != NULL)
504 { v2mask(data, key2); }
506 else if(TestBit(desMode, F_TRIPLE_DES))
508 /* Eurocrypt 3-DES */
509 mode = (operatingMode == HASH) ? 0 : DES_RIGHT;
510 nc_des(key1, (uint8_t)(DES_IP | mode), data);
512 mode ^= DES_RIGHT;
513 nc_des(key2, mode, data);
515 mode ^= DES_RIGHT;
516 nc_des(key1, (uint8_t)(mode | DES_IP_1), data);
518 else
520 if(TestBit(desMode, F_EURO_S2))
522 /* Eurocrypt S2 */
523 mode = (operatingMode == HASH) ? DES_ECS2_CRYPT : DES_ECS2_DECRYPT;
525 else
527 /* Eurocrypt M */
528 mode = (operatingMode == HASH) ? DES_ECM_HASH : DES_ECM_CRYPT;
530 nc_des(key1, mode, data);
534 int nc_des_encrypt(uint8_t *buffer, int len, uint8_t *deskey)
536 uint8_t checksum = 0;
537 uint8_t noPadBytes;
538 uint8_t padBytes[7];
539 char ivec[8];
540 short i;
542 if(!deskey) { return len; }
543 noPadBytes = (8 - ((len - 1) % 8)) % 8;
544 if(len + noPadBytes + 1 >= CWS_NETMSGSIZE - 8) { return -1; }
545 des_random_get(padBytes, noPadBytes);
546 for(i = 0; i < noPadBytes; i++) { buffer[len++] = padBytes[i]; }
547 for(i = 2; i < len; i++) { checksum ^= buffer[i]; }
548 buffer[len++] = checksum;
549 des_random_get((uint8_t *)ivec, 8);
550 memcpy(buffer + len, ivec, 8);
551 for(i = 2; i < len; i += 8)
553 uint8_t j;
554 const uint8_t flags = (1 << F_EURO_S2) | (1 << F_TRIPLE_DES);
555 for(j = 0; j < 8; j++) { buffer[i + j] ^= ivec[j]; }
556 EuroDes(deskey, deskey + 8, flags, HASH, buffer + i);
557 memcpy(ivec, buffer + i, 8);
559 len += 8;
560 return len;
563 int nc_des_decrypt(uint8_t *buffer, int len, uint8_t *deskey)
565 char ivec[8];
566 char nextIvec[8];
567 int i;
568 uint8_t checksum = 0;
570 if(!deskey) { return len; }
571 if((len - 2) % 8 || (len - 2) < 16) { return -1; }
572 len -= 8;
573 memcpy(nextIvec, buffer + len, 8);
574 for(i = 2; i < len; i += 8)
576 uint8_t j;
577 const uint8_t flags = (1 << F_EURO_S2) | (1 << F_TRIPLE_DES);
579 memcpy(ivec, nextIvec, 8);
580 memcpy(nextIvec, buffer + i, 8);
581 EuroDes(deskey, deskey + 8, flags, CRYPT, buffer + i);
582 for(j = 0; j < 8; j++)
583 { buffer[i + j] ^= ivec[j]; }
585 for(i = 2; i < len; i++) { checksum ^= buffer[i]; }
586 if(checksum) { return -1; }
587 return len;
590 uint8_t *nc_des_login_key_get(uint8_t *key1, uint8_t *key2, int len, uint8_t *des16)
592 uint8_t des14[14];
593 int i;
595 memcpy(des14, key1, sizeof(des14));
596 for(i = 0; i < len; i++) { des14[i % 14] ^= key2[i]; }
597 des16 = des_key_spread(des14, des16);
598 doPC1(des16);
599 doPC1(des16 + 8);
600 return des16;