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)
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 },
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
[])
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
[])
129 memset(buf
, 0, sizeof(buf
));
131 for(i
= 0; i
< 8; i
++)
139 for(k
= 0; k
<= 4; k
+= 4)
142 if(val
& 1) { p
[k
] |= 0x80; }
150 memcpy(data
, buf
, 8);
153 static void doIp_1(uint8_t data
[])
161 for(i
= 0; i
< 8; i
++)
168 for(k
= 0; k
<= 4; k
+= 4)
171 if(p
[k
] & 1) { r
|= 0x80; }
180 memcpy(data
, buf
, 8);
183 static void makeK(uint8_t *left
, uint8_t *right
, uint8_t *K
)
189 for(i
= 0; i
< 8; i
++)
192 for(j
= 0; j
< 6; j
++)
206 if(p
[bit
>> 3] & (1 << (bit
& 7))) { val
|= 1; }
213 static void rightRot(uint8_t key
[])
221 if(*p
& 1) { carry
= 0x08; }
225 *p
= (*p
>> 1) | ((p
[1] & 1) ? 0x80 : 0);
230 *p
= (*p
>> 1) | carry
;
233 static void rightRotKeys(uint8_t left
[], uint8_t right
[])
239 static void leftRot(uint8_t key
[])
250 static void leftRotKeys(uint8_t left
[], uint8_t right
[])
256 static void desCore(uint8_t data
[], uint8_t K
[], uint8_t result
[])
261 memset(result
, 0, 4);
263 for(i
= 0; i
< 8; i
++)
266 for(j
= 0; j
< 6; j
++)
270 if(data
[3 - (bit
>> 3)] & (1 << (bit
& 7))) { val
|= 1; }
273 val
= SBOXES
[i
& 3][val
];
279 result
[i
>> 1] |= (i
& 1) ? val
: (val
<< 4);
283 static void permut32(uint8_t data
[])
287 uint8_t r
[4] = {0}; // init to keep Valgrind happy
290 for(i
= 0; i
< 32; i
++)
294 for(j
= 0; j
< 3; j
++)
296 *p
= (*p
<< 1) | ((p
[1] & 0x80) ? 1 : 0);
300 if(data
[3 - (bit
>> 3)] & (1 << (bit
& 7))) { *p
|= 1; }
306 static void swap(uint8_t left
[], uint8_t right
[])
311 memcpy(right
, left
, 4);
315 static void desRound(uint8_t left
[], uint8_t right
[], uint8_t data
[], uint8_t mode
, uint8_t k8
)
323 memcpy(tempr
, data
+ 4, 4);
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)
331 makeK(left
, right
, K
);
332 desCore(tempr
, K
, r
);
342 for(i
= 0; i
< 4; i
++)
348 swap(data
- 4, data
);
351 void nc_des(uint8_t key
[], uint8_t mode
, uint8_t data
[])
358 short DESShift
= (mode
& DES_RIGHT
) ? 0x8103 : 0xc081;
360 for(i
= 3; i
> 0; i
--)
362 *p
= (key
[i
- 1] << 4) | (key
[i
] >> 4);
365 left
[3] = key
[0] >> 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]);
384 rightRotKeys(left
, right
);
385 if(!(DESShift
& 0x8000)) { rightRotKeys(left
, right
); }
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
++)
404 for(j
= 1; j
< 8; j
++) if((key
[i
] >> j
) & 0x1) { parity
= ~parity
& 0x01; }
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);
432 static void des_random_get(uint8_t *buffer
, uint8_t len
)
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
;
471 for(K
= 0; K
<= 7; K
++)
473 if((D
& 1) == 1) { B
+= M
; }
474 D
= (D
>> 1) + ((B
& 1) << 7);
480 static void v2mask(uint8_t *cw
, uint8_t *mask
)
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
[])
496 if(key1
[7]) /* Viaccess */
498 mode
= (operatingMode
== HASH
) ? DES_ECM_HASH
: DES_ECM_CRYPT
;
501 { v2mask(data
, key2
); }
502 nc_des(key1
, mode
, data
);
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
);
513 nc_des(key2
, mode
, data
);
516 nc_des(key1
, (uint8_t)(mode
| DES_IP_1
), data
);
520 if(TestBit(desMode
, F_EURO_S2
))
523 mode
= (operatingMode
== HASH
) ? DES_ECS2_CRYPT
: DES_ECS2_DECRYPT
;
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;
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)
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);
563 int nc_des_decrypt(uint8_t *buffer
, int len
, uint8_t *deskey
)
568 uint8_t checksum
= 0;
570 if(!deskey
) { return len
; }
571 if((len
- 2) % 8 || (len
- 2) < 16) { return -1; }
573 memcpy(nextIvec
, buffer
+ len
, 8);
574 for(i
= 2; i
< len
; i
+= 8)
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; }
590 uint8_t *nc_des_login_key_get(uint8_t *key1
, uint8_t *key2
, int len
, uint8_t *des16
)
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
);