source: trunk/reader-videoguard2.c@ 1691

Last change on this file since 1691 was 1691, checked in by merek, 11 years ago

Merge Webinterface into Trunk - Use -DWEBIF=1 with cmake to build with Webinterface - For make add -DWEBIF to target in Makefile to build with Webinterface for, thanks to Alno and Streamboard community

File size: 45.1 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3
4#include <termios.h>
5#include <unistd.h>
6#ifdef OS_LINUX
7#include <linux/serial.h>
8#endif
9
10#define MAX_ATR_LEN 33 // max. ATR length
11#define MAX_HIST 15 // max. number of historical characters
12
13////// ====================================================================================
14
15int aes_active=0;
16AES_KEY dkey, ekey;
17int BASEYEAR = 1997;
18static void cAES_SetKey(const unsigned char *key)
19{
20 AES_set_decrypt_key(key,128,&dkey);
21 AES_set_encrypt_key(key,128,&ekey);
22 aes_active=1;
23}
24
25static int cAES_Encrypt(const unsigned char *data, int len, unsigned char *crypt)
26{
27 if(aes_active) {
28 len=(len+15)&(~15); // pad up to a multiple of 16
29 int i;
30 for(i=0; i<len; i+=16) AES_encrypt(data+i,crypt+i,(const AES_KEY *)&ekey);
31 return len;
32 }
33 return -1;
34}
35
36static int cw_is_valid(unsigned char *cw) //returns 1 if cw_is_valid, returns 0 if cw is all zeros
37{
38 int i;
39 for (i = 0; i < 8; i++)
40 if (cw[i] != 0) {//test if cw = 00
41 return OK;
42 }
43 return ERROR;
44}
45
46////// ====================================================================================
47////// special thanks to an "italian forum" !!!!
48
49
50static void postprocess_cw(unsigned char *cw, int nTableIdx)
51{
52
53 if (!cw_is_valid(cw)) //if cw is all zero, keep it that way
54 return;
55#if __BYTE_ORDER == __BIG_ENDIAN
56 static unsigned char Tb1[0xC]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,0xF8,0x61,0xCB,0x52};
57 static unsigned char Tb2[0x540]= {
58 0xEA,0xF1,0x02,0x37,0x29,0xD0,0xBA,0xD2,0xE9,0xD3,0x8B,0xAE,0x2D,0x6D,0xCD,0x1B,0x53,0x8D,0xDE,0x6B,0xA6,0x34,0xF8,0x1A,0x18,0xB5,0x50,0x87,0x14,0xEA,0x67,0x2E,
59 0xF0,0xFC,0x05,0x5E,0x62,0xE5,0xB7,0x8F,0x5D,0x09,0x00,0x03,0xE4,0xE8,0x2D,0xCE,0x6B,0xE0,0xAC,0x4E,0xF4,0x85,0x69,0x67,0xF2,0x8C,0x97,0xA0,0x01,0xEF,0x01,0x00,
60 0xC5,0x39,0xF5,0xB9,0x90,0x99,0x01,0x3A,0xD4,0xB9,0x6A,0xB5,0xEA,0x67,0x7E,0xB4,0x6C,0x30,0x4B,0xF0,0xB8,0x10,0xB0,0xB5,0xB7,0x6D,0xA7,0x51,0x1A,0xE7,0x14,0xCA,
61 0x4F,0x4F,0x15,0x86,0x26,0x08,0x10,0xB1,0xE7,0xE1,0x48,0xBE,0x7D,0xDD,0x5E,0xCB,0xCF,0xBF,0x32,0x3B,0x8B,0x31,0xB1,0x31,0x0F,0x1A,0x66,0x4B,0x01,0x40,0x01,0x00,
62 0x3C,0x7D,0xBD,0xC4,0xFE,0xC7,0x26,0xA6,0xB0,0xA0,0x6E,0x55,0xF7,0x10,0xF9,0xBF,0x00,0x23,0xE8,0x1F,0x41,0xCA,0xBE,0x32,0xB4,0x61,0xE9,0x2D,0xF1,0xAF,0x40,0x9F,
63 0xFC,0x85,0xFE,0x5B,0x7F,0xCE,0x17,0xF5,0x01,0xAB,0x4A,0x46,0xEB,0x05,0xA2,0x51,0xDC,0x6F,0xF0,0xC0,0x10,0xF0,0x1D,0x51,0xEF,0xAA,0xE9,0xBF,0x01,0x00,0x01,0x00,
64 0x18,0x19,0x0C,0xAA,0x90,0x67,0x60,0x7A,0x75,0x76,0x1C,0xBC,0xE5,0x1D,0xBF,0x77,0x7E,0xC6,0x83,0x9E,0xB6,0x95,0xF0,0x96,0xDC,0x10,0xCB,0x69,0x46,0x54,0x8E,0x68,
65 0xD6,0x2D,0x4F,0x1A,0x42,0x27,0x92,0xAC,0x90,0x64,0x6B,0xD1,0x1E,0x75,0x27,0x47,0x00,0xDA,0xA6,0xA6,0x6C,0xF1,0xD1,0x51,0xBE,0x56,0x3E,0x33,0x01,0x28,0x01,0x00,
66 0x40,0x91,0x09,0xED,0xD4,0x94,0x60,0x54,0x18,0x69,0x71,0xD5,0xB5,0x72,0x7B,0xF1,0xE9,0x25,0xEE,0x2D,0xEE,0xDE,0xA1,0x3C,0x66,0x13,0x9B,0xAB,0x12,0x2D,0x7A,0xE4,
67 0x52,0x68,0xE6,0xC9,0x50,0xCB,0x79,0xA1,0xF2,0x12,0xA0,0x62,0x6B,0x48,0x70,0xB3,0xF6,0xB0,0x06,0xD5,0xF8,0xAB,0xEC,0xF5,0x62,0x55,0xED,0xD8,0x79,0xD2,0x29,0x0A,
68 0xD3,0xCF,0x01,0x4E,0xAC,0xB3,0x8F,0x6B,0x0F,0x2C,0xA5,0xD8,0xE8,0xE0,0x86,0x3D,0x80,0xD5,0x57,0x05,0x65,0x8A,0x8B,0xC2,0xEE,0x46,0xD3,0xAE,0x01,0x99,0x01,0x00,
69 0x4A,0x35,0xAB,0xE4,0xF9,0x76,0x93,0x5A,0xA8,0xA5,0xBA,0xE9,0x24,0xD0,0x71,0xAA,0xB3,0xFE,0x09,0x5E,0xAB,0x06,0x4C,0xD5,0x2F,0x0D,0x1A,0xCB,0x59,0xF3,0x4C,0x50,
70 0xFD,0x27,0x0F,0x8E,0x19,0x1A,0xEE,0xE7,0x2F,0x49,0x3A,0x05,0x32,0x67,0x4F,0x88,0x38,0xAE,0xFC,0xE9,0x94,0x76,0x18,0xC6,0xF9,0x61,0x4E,0xF0,0x39,0xD0,0x42,0xE6,
71 0xB7,0x47,0xE6,0x25,0xB6,0x8E,0x51,0x00,0xF9,0x2A,0x86,0xFE,0xE7,0x9B,0xEE,0x91,0x21,0xD5,0x4C,0x3C,0x68,0x3D,0x5A,0xD1,0x1B,0x49,0xF4,0x07,0x01,0x94,0x01,0x00,
72 0x4B,0xF9,0xDC,0x0D,0x94,0x78,0x51,0x74,0xCB,0x4A,0x8A,0x89,0x4D,0x6A,0xFE,0xD8,0xF1,0x23,0xA8,0xCD,0xEE,0xE7,0xA6,0xD1,0xB7,0x63,0xF5,0xE2,0xE0,0x85,0x01,0xEF,
73 0xE4,0x66,0x9F,0xA3,0x2F,0x68,0x21,0x90,0x42,0x3F,0x28,0x7F,0x7F,0x3F,0x09,0xF6,0x21,0x11,0xA9,0x63,0xD0,0xBB,0x67,0x4A,0xBA,0x72,0x45,0xF9,0xF1,0x86,0xB8,0xF5,
74 0x00,0x10,0xD1,0xB9,0xB1,0x64,0x9E,0x87,0x1F,0x49,0x69,0x50,0x2D,0xBF,0x38,0xD3,0x2E,0xB0,0x3E,0x8E,0x91,0xE6,0xF6,0x88,0x7E,0x41,0x56,0x6E,0x01,0xB0,0x01,0x00,
75 0x24,0xA1,0x73,0xD8,0xA0,0xC3,0xF7,0x1B,0xA0,0xA5,0x2A,0x06,0xBA,0x46,0xFE,0xC3,0xDD,0x4C,0x52,0xCC,0xF9,0xBC,0x3B,0x7E,0x38,0x12,0x06,0x66,0xB7,0x4B,0x40,0xF8,
76 0x28,0xF2,0x7C,0x81,0xFC,0x92,0x6F,0xBD,0x53,0xD6,0x72,0xA3,0xBB,0xDF,0xB6,0xFC,0x9C,0xE5,0x23,0x31,0xD4,0xF6,0xC5,0xBB,0xE8,0xBB,0x66,0x76,0x02,0xD9,0x2F,0x0E,
77 0xD0,0x09,0xD1,0x36,0xCD,0x09,0x75,0x51,0x18,0x26,0x9D,0x9B,0x63,0xEA,0xFC,0x63,0x68,0xCD,0x36,0x72,0xCB,0x95,0xD2,0x8E,0xF1,0xCD,0x20,0xCA,0x01,0x4C,0x01,0x00,
78 0xE5,0x39,0x55,0xB7,0x98,0x9D,0x21,0xC4,0x46,0x3A,0xE6,0x8F,0xF8,0xB5,0xE5,0xC5,0x66,0x2B,0x35,0xBF,0x3C,0x50,0x01,0x31,0xF4,0xBF,0x38,0xB2,0x41,0xBC,0xB8,0x29,
79 0x02,0xB7,0x6B,0x8F,0xA2,0x5C,0xAF,0xD2,0xD8,0x4A,0x22,0x43,0x53,0xEB,0xC6,0xC9,0x2E,0x14,0x18,0x1F,0x8F,0x96,0xDF,0x0E,0x0D,0x4C,0x30,0xF6,0xFF,0xE1,0x9D,0xDA,
80 0x30,0xB6,0x77,0x7E,0xDA,0x3D,0xAF,0x77,0x20,0x5E,0xC9,0x0B,0x85,0x6B,0xB4,0x51,0x3B,0xCC,0x76,0xC2,0x8A,0xCF,0xDC,0xB1,0xA5,0xE5,0xDD,0x64,0x01,0x97,0x01,0x00,
81 0xE7,0x51,0xB6,0x61,0x04,0x04,0xDB,0x4A,0xE9,0xDD,0xA4,0x00,0xAF,0x26,0x3F,0x5E,0x90,0x4B,0xA9,0x24,0x09,0xE0,0xE7,0x2B,0x82,0x5B,0x2C,0x50,0x6F,0xD0,0x0D,0x52,
82 0x27,0x30,0xC2,0xBA,0x9E,0x44,0x58,0x15,0xFC,0x47,0xB2,0x1D,0x67,0xB8,0xF8,0xB9,0x04,0x7D,0xB0,0xAF,0x9F,0x14,0x74,0x1B,0x46,0x68,0xBE,0x54,0xDE,0x16,0xDB,0x14,
83 0x7C,0xB7,0xF2,0xB8,0x06,0x83,0x76,0x2C,0x09,0xA0,0x95,0x07,0x7F,0x92,0x02,0x2C,0xBA,0x6A,0x7D,0x52,0x0A,0xF4,0x1B,0xC3,0xB4,0x6A,0xC4,0xFD,0x01,0xC2,0x01,0x00,
84 0x76,0x11,0x66,0xF3,0xEE,0x87,0xED,0xD3,0xC5,0x59,0xEF,0xD4,0xDC,0x59,0xF8,0x6B,0x6D,0x1C,0x1C,0x85,0x9B,0xB1,0x33,0x73,0x76,0x3F,0x4E,0xBE,0x1B,0xF3,0x99,0xB5,
85 0xD7,0x21,0x97,0x8F,0xCF,0x5C,0xAC,0x51,0x09,0x84,0x74,0x62,0x8F,0x0C,0x28,0x17,0x4A,0xD9,0xFD,0x41,0x66,0x78,0x7C,0x85,0xD3,0x30,0xC9,0xF8,0x1D,0x9A,0xC6,0x22,
86 0x5A,0xE4,0xE1,0x6A,0x60,0xF6,0xFD,0x45,0x66,0x8C,0x29,0xD6,0x02,0x85,0x6B,0x92,0x92,0xC2,0x21,0xDE,0x45,0xE0,0xEF,0x3D,0x8B,0x0D,0x02,0xCD,0x01,0x98,0x01,0x00,
87 0x9E,0x6D,0x4D,0x38,0xDE,0xF9,0xE6,0xF2,0xF7,0x2E,0xB3,0x13,0x14,0xF2,0x39,0x0A,0x2D,0x67,0xC7,0x1E,0xCB,0x69,0x7F,0x66,0xD3,0xCF,0x7F,0x8A,0x81,0xD9,0x9D,0xDE,
88 0x85,0xE3,0x8F,0x29,0x36,0xEB,0xC9,0x68,0x36,0x96,0x59,0xF6,0x78,0x32,0xA7,0x8B,0xA1,0xD8,0xF5,0xCF,0xAB,0x64,0x64,0x6D,0x7A,0x2A,0xBA,0xF8,0xAA,0x87,0x41,0xC7,
89 0x51,0x20,0xDE,0x78,0x73,0x8D,0xDC,0x1A,0x26,0x8D,0x5D,0xF8,0xED,0x69,0x1C,0x8A,0xBC,0x85,0x3D,0xCD,0xAE,0x30,0x0F,0x8D,0xEC,0x89,0x3A,0xBD,0x01,0x66,0x01,0x00,
90 0xB8,0xBD,0x64,0x3B,0x74,0x8E,0xBD,0x63,0xEC,0x6F,0xE2,0x3A,0x94,0x93,0xDD,0x76,0x0A,0x62,0x77,0x4F,0xCD,0x68,0xA6,0x7A,0x9A,0x23,0xC8,0xA8,0xBD,0xE5,0x9D,0x1B,
91 0x2B,0x86,0x8B,0x36,0x54,0x28,0x1D,0xFB,0xCD,0x1D,0x07,0x13,0x29,0xC2,0x8E,0x8E,0x52,0x07,0xA1,0x3F,0x60,0x05,0x4F,0x5E,0x52,0xE0,0xE7,0xC8,0x6D,0x1C,0x3E,0x34,
92 0x58,0x1D,0x2B,0xFA,0x5E,0x1D,0xA8,0x91,0x10,0x69,0x1D,0xA4,0x39,0xA0,0xBE,0x45,0x5B,0x9A,0x73,0x33,0x6F,0x3E,0x86,0x37,0xA5,0x50,0xC9,0xE9,0x5C,0x6C,0x42,0xBA,
93 0xA7,0x12,0xC3,0xEA,0x38,0x08,0x09,0x10,0xAA,0x4D,0x5B,0x25,0xAB,0xCD,0xE6,0x80,0x96,0xAD,0x2C,0xEC,0x8E,0xBB,0xA4,0x7D,0x16,0x90,0xE8,0xFB,0x01,0xC8,0x01,0x00,
94 0x73,0xB9,0x82,0xBC,0x9E,0xBC,0xB1,0x30,0x0D,0xA5,0x86,0x17,0x9F,0x7B,0x97,0x66,0x20,0x5D,0x75,0x2D,0xB0,0x5C,0x2A,0x17,0xA7,0x5C,0x18,0xEF,0x83,0x39,0xFD,0x34,
95 0x8D,0xA2,0x79,0x70,0xD0,0xB4,0x70,0xF1,0x37,0x65,0x73,0x80,0x7C,0xAF,0x57,0x0E,0x64,0x40,0xBC,0x44,0x07,0x43,0x2D,0x02,0x04,0x19,0xA2,0x40,0x21,0x13,0x1A,0xD4,
96 0x1E,0xB5,0xBB,0xFF,0x39,0xB1,0x32,0x09,0x70,0x5F,0x15,0xF4,0xD7,0xAD,0x34,0x0B,0xC2,0xA6,0x25,0xCA,0xF4,0x12,0x95,0x70,0x0F,0x4F,0xE4,0xD5,0x16,0x14,0xE4,0x64,
97 0x91,0x1A,0x0F,0x0E,0x07,0xDA,0xA9,0x29,0x23,0x79,0xD9,0x88,0x0A,0xA6,0x3B,0x57,0xBF,0x63,0x71,0xFB,0x72,0xD5,0x26,0xCE,0xB0,0xAF,0xCF,0x45,0x01,0x1B,0x01,0x00,
98 0x99,0x99,0x98,0xFE,0xA1,0x08,0x65,0x88,0xF9,0x0B,0x45,0x54,0xFF,0x38,0x46,0x42,0x8F,0x5F,0x6C,0xC3,0x4E,0x8E,0xFF,0x7E,0x64,0xC2,0x50,0xCA,0x0E,0x7F,0xAD,0x7D,
99 0x6A,0xAB,0x33,0xC1,0xE1,0xF4,0x61,0x65,0x78,0x94,0x83,0xB9,0x0A,0x0C,0x38,0xAF,0x58,0x03,0x18,0xC0,0xFA,0x36,0x59,0x2C,0x45,0x48,0xAB,0xB8,0x15,0x27,0xAE,0xE9,
100 };
101#else
102 static unsigned char Tb1[0xC]={0x23,0x01,0x67,0x45,0xAB,0x89,0xEF,0xCD,0x61,0xF8,0x52,0xCB};
103 static unsigned char Tb2[0x540]= {
104 0xF1,0xEA,0x37,0x02,0xD0,0x29,0xD2,0xBA,0xD3,0xE9,0xAE,0x8B,0x6D,0x2D,0x1B,0xCD,0x8D,0x53,0x6B,0xDE,0x34,0xA6,0x1A,0xF8,0xB5,0x18,0x87,0x50,0xEA,0x14,0x2E,0x67,
105 0xFC,0xF0,0x5E,0x05,0xE5,0x62,0x8F,0xB7,0x09,0x5D,0x03,0x00,0xE8,0xE4,0xCE,0x2D,0xE0,0x6B,0x4E,0xAC,0x85,0xF4,0x67,0x69,0x8C,0xF2,0xA0,0x97,0xEF,0x01,0x00,0x01,
106 0x39,0xC5,0xB9,0xF5,0x99,0x90,0x3A,0x01,0xB9,0xD4,0xB5,0x6A,0x67,0xEA,0xB4,0x7E,0x30,0x6C,0xF0,0x4B,0x10,0xB8,0xB5,0xB0,0x6D,0xB7,0x51,0xA7,0xE7,0x1A,0xCA,0x14,
107 0x4F,0x4F,0x86,0x15,0x08,0x26,0xB1,0x10,0xE1,0xE7,0xBE,0x48,0xDD,0x7D,0xCB,0x5E,0xBF,0xCF,0x3B,0x32,0x31,0x8B,0x31,0xB1,0x1A,0x0F,0x4B,0x66,0x40,0x01,0x00,0x01,
108 0x7D,0x3C,0xC4,0xBD,0xC7,0xFE,0xA6,0x26,0xA0,0xB0,0x55,0x6E,0x10,0xF7,0xBF,0xF9,0x23,0x00,0x1F,0xE8,0xCA,0x41,0x32,0xBE,0x61,0xB4,0x2D,0xE9,0xAF,0xF1,0x9F,0x40,
109 0x85,0xFC,0x5B,0xFE,0xCE,0x7F,0xF5,0x17,0xAB,0x01,0x46,0x4A,0x05,0xEB,0x51,0xA2,0x6F,0xDC,0xC0,0xF0,0xF0,0x10,0x51,0x1D,0xAA,0xEF,0xBF,0xE9,0x00,0x01,0x00,0x01,
110 0x19,0x18,0xAA,0x0C,0x67,0x90,0x7A,0x60,0x76,0x75,0xBC,0x1C,0x1D,0xE5,0x77,0xBF,0xC6,0x7E,0x9E,0x83,0x95,0xB6,0x96,0xF0,0x10,0xDC,0x69,0xCB,0x54,0x46,0x68,0x8E,
111 0x2D,0xD6,0x1A,0x4F,0x27,0x42,0xAC,0x92,0x64,0x90,0xD1,0x6B,0x75,0x1E,0x47,0x27,0xDA,0x00,0xA6,0xA6,0xF1,0x6C,0x51,0xD1,0x56,0xBE,0x33,0x3E,0x28,0x01,0x00,0x01,
112 0x91,0x40,0xED,0x09,0x94,0xD4,0x54,0x60,0x69,0x18,0xD5,0x71,0x72,0xB5,0xF1,0x7B,0x25,0xE9,0x2D,0xEE,0xDE,0xEE,0x3C,0xA1,0x13,0x66,0xAB,0x9B,0x2D,0x12,0xE4,0x7A,
113 0x68,0x52,0xC9,0xE6,0xCB,0x50,0xA1,0x79,0x12,0xF2,0x62,0xA0,0x48,0x6B,0xB3,0x70,0xB0,0xF6,0xD5,0x06,0xAB,0xF8,0xF5,0xEC,0x55,0x62,0xD8,0xED,0xD2,0x79,0x0A,0x29,
114 0xCF,0xD3,0x4E,0x01,0xB3,0xAC,0x6B,0x8F,0x2C,0x0F,0xD8,0xA5,0xE0,0xE8,0x3D,0x86,0xD5,0x80,0x05,0x57,0x8A,0x65,0xC2,0x8B,0x46,0xEE,0xAE,0xD3,0x99,0x01,0x00,0x01,
115 0x35,0x4A,0xE4,0xAB,0x76,0xF9,0x5A,0x93,0xA5,0xA8,0xE9,0xBA,0xD0,0x24,0xAA,0x71,0xFE,0xB3,0x5E,0x09,0x06,0xAB,0xD5,0x4C,0x0D,0x2F,0xCB,0x1A,0xF3,0x59,0x50,0x4C,
116 0x27,0xFD,0x8E,0x0F,0x1A,0x19,0xE7,0xEE,0x49,0x2F,0x05,0x3A,0x67,0x32,0x88,0x4F,0xAE,0x38,0xE9,0xFC,0x76,0x94,0xC6,0x18,0x61,0xF9,0xF0,0x4E,0xD0,0x39,0xE6,0x42,
117 0x47,0xB7,0x25,0xE6,0x8E,0xB6,0x00,0x51,0x2A,0xF9,0xFE,0x86,0x9B,0xE7,0x91,0xEE,0xD5,0x21,0x3C,0x4C,0x3D,0x68,0xD1,0x5A,0x49,0x1B,0x07,0xF4,0x94,0x01,0x00,0x01,
118 0xF9,0x4B,0x0D,0xDC,0x78,0x94,0x74,0x51,0x4A,0xCB,0x89,0x8A,0x6A,0x4D,0xD8,0xFE,0x23,0xF1,0xCD,0xA8,0xE7,0xEE,0xD1,0xA6,0x63,0xB7,0xE2,0xF5,0x85,0xE0,0xEF,0x01,
119 0x66,0xE4,0xA3,0x9F,0x68,0x2F,0x90,0x21,0x3F,0x42,0x7F,0x28,0x3F,0x7F,0xF6,0x09,0x11,0x21,0x63,0xA9,0xBB,0xD0,0x4A,0x67,0x72,0xBA,0xF9,0x45,0x86,0xF1,0xF5,0xB8,
120 0x10,0x00,0xB9,0xD1,0x64,0xB1,0x87,0x9E,0x49,0x1F,0x50,0x69,0xBF,0x2D,0xD3,0x38,0xB0,0x2E,0x8E,0x3E,0xE6,0x91,0x88,0xF6,0x41,0x7E,0x6E,0x56,0xB0,0x01,0x00,0x01,
121 0xA1,0x24,0xD8,0x73,0xC3,0xA0,0x1B,0xF7,0xA5,0xA0,0x06,0x2A,0x46,0xBA,0xC3,0xFE,0x4C,0xDD,0xCC,0x52,0xBC,0xF9,0x7E,0x3B,0x12,0x38,0x66,0x06,0x4B,0xB7,0xF8,0x40,
122 0xF2,0x28,0x81,0x7C,0x92,0xFC,0xBD,0x6F,0xD6,0x53,0xA3,0x72,0xDF,0xBB,0xFC,0xB6,0xE5,0x9C,0x31,0x23,0xF6,0xD4,0xBB,0xC5,0xBB,0xE8,0x76,0x66,0xD9,0x02,0x0E,0x2F,
123 0x09,0xD0,0x36,0xD1,0x09,0xCD,0x51,0x75,0x26,0x18,0x9B,0x9D,0xEA,0x63,0x63,0xFC,0xCD,0x68,0x72,0x36,0x95,0xCB,0x8E,0xD2,0xCD,0xF1,0xCA,0x20,0x4C,0x01,0x00,0x01,
124 0x39,0xE5,0xB7,0x55,0x9D,0x98,0xC4,0x21,0x3A,0x46,0x8F,0xE6,0xB5,0xF8,0xC5,0xE5,0x2B,0x66,0xBF,0x35,0x50,0x3C,0x31,0x01,0xBF,0xF4,0xB2,0x38,0xBC,0x41,0x29,0xB8,
125 0xB7,0x02,0x8F,0x6B,0x5C,0xA2,0xD2,0xAF,0x4A,0xD8,0x43,0x22,0xEB,0x53,0xC9,0xC6,0x14,0x2E,0x1F,0x18,0x96,0x8F,0x0E,0xDF,0x4C,0x0D,0xF6,0x30,0xE1,0xFF,0xDA,0x9D,
126 0xB6,0x30,0x7E,0x77,0x3D,0xDA,0x77,0xAF,0x5E,0x20,0x0B,0xC9,0x6B,0x85,0x51,0xB4,0xCC,0x3B,0xC2,0x76,0xCF,0x8A,0xB1,0xDC,0xE5,0xA5,0x64,0xDD,0x97,0x01,0x00,0x01,
127 0x51,0xE7,0x61,0xB6,0x04,0x04,0x4A,0xDB,0xDD,0xE9,0x00,0xA4,0x26,0xAF,0x5E,0x3F,0x4B,0x90,0x24,0xA9,0xE0,0x09,0x2B,0xE7,0x5B,0x82,0x50,0x2C,0xD0,0x6F,0x52,0x0D,
128 0x30,0x27,0xBA,0xC2,0x44,0x9E,0x15,0x58,0x47,0xFC,0x1D,0xB2,0xB8,0x67,0xB9,0xF8,0x7D,0x04,0xAF,0xB0,0x14,0x9F,0x1B,0x74,0x68,0x46,0x54,0xBE,0x16,0xDE,0x14,0xDB,
129 0xB7,0x7C,0xB8,0xF2,0x83,0x06,0x2C,0x76,0xA0,0x09,0x07,0x95,0x92,0x7F,0x2C,0x02,0x6A,0xBA,0x52,0x7D,0xF4,0x0A,0xC3,0x1B,0x6A,0xB4,0xFD,0xC4,0xC2,0x01,0x00,0x01,
130 0x11,0x76,0xF3,0x66,0x87,0xEE,0xD3,0xED,0x59,0xC5,0xD4,0xEF,0x59,0xDC,0x6B,0xF8,0x1C,0x6D,0x85,0x1C,0xB1,0x9B,0x73,0x33,0x3F,0x76,0xBE,0x4E,0xF3,0x1B,0xB5,0x99,
131 0x21,0xD7,0x8F,0x97,0x5C,0xCF,0x51,0xAC,0x84,0x09,0x62,0x74,0x0C,0x8F,0x17,0x28,0xD9,0x4A,0x41,0xFD,0x78,0x66,0x85,0x7C,0x30,0xD3,0xF8,0xC9,0x9A,0x1D,0x22,0xC6,
132 0xE4,0x5A,0x6A,0xE1,0xF6,0x60,0x45,0xFD,0x8C,0x66,0xD6,0x29,0x85,0x02,0x92,0x6B,0xC2,0x92,0xDE,0x21,0xE0,0x45,0x3D,0xEF,0x0D,0x8B,0xCD,0x02,0x98,0x01,0x00,0x01,
133 0x6D,0x9E,0x38,0x4D,0xF9,0xDE,0xF2,0xE6,0x2E,0xF7,0x13,0xB3,0xF2,0x14,0x0A,0x39,0x67,0x2D,0x1E,0xC7,0x69,0xCB,0x66,0x7F,0xCF,0xD3,0x8A,0x7F,0xD9,0x81,0xDE,0x9D,
134 0xE3,0x85,0x29,0x8F,0xEB,0x36,0x68,0xC9,0x96,0x36,0xF6,0x59,0x32,0x78,0x8B,0xA7,0xD8,0xA1,0xCF,0xF5,0x64,0xAB,0x6D,0x64,0x2A,0x7A,0xF8,0xBA,0x87,0xAA,0xC7,0x41,
135 0x20,0x51,0x78,0xDE,0x8D,0x73,0x1A,0xDC,0x8D,0x26,0xF8,0x5D,0x69,0xED,0x8A,0x1C,0x85,0xBC,0xCD,0x3D,0x30,0xAE,0x8D,0x0F,0x89,0xEC,0xBD,0x3A,0x66,0x01,0x00,0x01,
136 0xBD,0xB8,0x3B,0x64,0x8E,0x74,0x63,0xBD,0x6F,0xEC,0x3A,0xE2,0x93,0x94,0x76,0xDD,0x62,0x0A,0x4F,0x77,0x68,0xCD,0x7A,0xA6,0x23,0x9A,0xA8,0xC8,0xE5,0xBD,0x1B,0x9D,
137 0x86,0x2B,0x36,0x8B,0x28,0x54,0xFB,0x1D,0x1D,0xCD,0x13,0x07,0xC2,0x29,0x8E,0x8E,0x07,0x52,0x3F,0xA1,0x05,0x60,0x5E,0x4F,0xE0,0x52,0xC8,0xE7,0x1C,0x6D,0x34,0x3E,
138 0x1D,0x58,0xFA,0x2B,0x1D,0x5E,0x91,0xA8,0x69,0x10,0xA4,0x1D,0xA0,0x39,0x45,0xBE,0x9A,0x5B,0x33,0x73,0x3E,0x6F,0x37,0x86,0x50,0xA5,0xE9,0xC9,0x6C,0x5C,0xBA,0x42,
139 0x12,0xA7,0xEA,0xC3,0x08,0x38,0x10,0x09,0x4D,0xAA,0x25,0x5B,0xCD,0xAB,0x80,0xE6,0xAD,0x96,0xEC,0x2C,0xBB,0x8E,0x7D,0xA4,0x90,0x16,0xFB,0xE8,0xC8,0x01,0x00,0x01,
140 0xB9,0x73,0xBC,0x82,0xBC,0x9E,0x30,0xB1,0xA5,0x0D,0x17,0x86,0x7B,0x9F,0x66,0x97,0x5D,0x20,0x2D,0x75,0x5C,0xB0,0x17,0x2A,0x5C,0xA7,0xEF,0x18,0x39,0x83,0x34,0xFD,
141 0xA2,0x8D,0x70,0x79,0xB4,0xD0,0xF1,0x70,0x65,0x37,0x80,0x73,0xAF,0x7C,0x0E,0x57,0x40,0x64,0x44,0xBC,0x43,0x07,0x02,0x2D,0x19,0x04,0x40,0xA2,0x13,0x21,0xD4,0x1A,
142 0xB5,0x1E,0xFF,0xBB,0xB1,0x39,0x09,0x32,0x5F,0x70,0xF4,0x15,0xAD,0xD7,0x0B,0x34,0xA6,0xC2,0xCA,0x25,0x12,0xF4,0x70,0x95,0x4F,0x0F,0xD5,0xE4,0x14,0x16,0x64,0xE4,
143 0x1A,0x91,0x0E,0x0F,0xDA,0x07,0x29,0xA9,0x79,0x23,0x88,0xD9,0xA6,0x0A,0x57,0x3B,0x63,0xBF,0xFB,0x71,0xD5,0x72,0xCE,0x26,0xAF,0xB0,0x45,0xCF,0x1B,0x01,0x00,0x01,
144 0x99,0x99,0xFE,0x98,0x08,0xA1,0x88,0x65,0x0B,0xF9,0x54,0x45,0x38,0xFF,0x42,0x46,0x5F,0x8F,0xC3,0x6C,0x8E,0x4E,0x7E,0xFF,0xC2,0x64,0xCA,0x50,0x7F,0x0E,0x7D,0xAD,
145 0xAB,0x6A,0xC1,0x33,0xF4,0xE1,0x65,0x61,0x94,0x78,0xB9,0x83,0x0C,0x0A,0xAF,0x38,0x03,0x58,0xC0,0x18,0x36,0xFA,0x2C,0x59,0x48,0x45,0xB8,0xAB,0x27,0x15,0xE9,0xAE,
146
147 };
148#endif
149 unsigned char tabletmp2[0x10] = {0x0B,0x04,0x07,0x08,0x05,0x09,0x0B,0x0A,0x07,0x02,0x0A,0x05,0x04,0x08,0x0D,0x0F};
150 unsigned char table40[0x40];
151 unsigned char Hash48[0x48];
152 unsigned char Hash14[0x14];
153 unsigned char counter=0,counter2=0;
154 int tmp1;
155 int h,j,k,l,m = 0;
156 int i;
157
158
159 memset(Hash48,0,0x48);
160 for (i = 0; i < 8; i++)
161 Hash48[i] = cw[i];
162 Hash48[8]=0x80;
163
164
165 memcpy(table40,&Tb2[nTableIdx*0x40],0x40);
166
167 for(i = 0; i < 12; i++) Hash14[i] = Tb1[i];
168
169 int k1 = *((short*) &Hash14); int k2 = *((short*) &Hash14+1); int k3 = *((short*) &Hash14+2);
170 int k4 = *((short*) &Hash14+3); int k5 = *((short*) &Hash14+4); int k6 = *((short*) &Hash14+5);
171 for (m = 0; m < 2; m++) {
172 int loop;
173 for (loop = 0; loop < 0x24; loop++) {
174 h=((Hash48[(loop<<1) +1]<<8)+Hash48[loop<<1])&0xFFFF;
175 if(m)
176 tmp1 = (((k2 & k4) | ((~k4) & k3)) & 0xFFFF);
177 else
178 tmp1 = (((k2 & k3) | ((~k2) & k4)) & 0xFFFF);
179 if((counter & 1))
180 k = *(((short *) table40)+(counter>>1))>>8;
181 else
182 k = *(((short *) table40)+(counter>>1));
183 l = k1; j = k2;
184 k1 = k2; k2 = k3; k3 = k4; k4 = k5; k5 = k6;
185 k6 = ((tmp1 + l + h + (k & 0xFF)) & 0xFFFF);
186 tmp1 = tabletmp2[counter2];
187 k6 = ((((k6 << tmp1) | (k6 >> (0x10 - tmp1))) + j) & 0xFFFF);
188 counter2++;
189 if(counter2 == 0x10) counter2 = 0;
190 counter++;
191 if(counter == 0x40) counter = 0;
192 }
193 }
194
195//#if __BYTE_ORDER != __BIG_ENDIAN
196 cw[0] = (k1 + *((short *)&Hash14)) & 0xFF;
197 cw[1] = (k1 + *((short *)&Hash14))>>8;
198 cw[2] = (k2 + *((short *)&Hash14+1)) & 0xFF;
199 cw[3] = (cw[0] + cw[1] + cw[2]) & 0xFF;
200 cw[4] = (k3 + *((short *)&Hash14+2)) & 0xFF;
201 cw[5] = (k3 + *((short *)&Hash14+2))>>8;
202 cw[6] = (k4 + *((short *)&Hash14+3)) & 0xFF;
203 cw[7] = (cw[4] + cw[5] + cw[6]) & 0xFF;
204/*#else
205 cw[0] = (k1 + *((short *)&Hash14))>>8;
206 cw[1] = (k1 + *((short *)&Hash14)) & 0xFF;
207 cw[2] = (k2 + *((short *)&Hash14+1))>>8;
208 cw[3] = (cw[0] + cw[1] + cw[2]) & 0xFF;
209 cw[4] = (k3 + *((short *)&Hash14+2))>>8;
210 cw[5] = (k3 + *((short *)&Hash14+2)) & 0xFF;
211 cw[6] = (k4 + *((short *)&Hash14+3))>>8;
212 cw[7] = (cw[4] + cw[5] + cw[6]) & 0xFF;
213#endif*/
214
215 cs_ddump (cw, 8, "Postprocessed DW:");
216}
217
218
219////// ====================================================================================
220
221static void swap_lb (unsigned char *buff, int len)
222{
223
224#if __BYTE_ORDER != __BIG_ENDIAN
225 return;
226
227#endif /* */
228 int i;
229 unsigned short *tmp;
230 for (i = 0; i < len / 2; i++) {
231 tmp = (unsigned short *) buff + i;
232 *tmp = ((*tmp << 8) & 0xff00) | ((*tmp >> 8) & 0x00ff);
233 }
234}
235
236static inline void __xxor(unsigned char *data, int len, const unsigned char *v1, const unsigned char *v2)
237{
238 switch(len) { // looks ugly, but the compiler can optimize it very well ;)
239 case 16:
240 *((unsigned int *)data+3) = *((unsigned int *)v1+3) ^ *((unsigned int *)v2+3);
241 *((unsigned int *)data+2) = *((unsigned int *)v1+2) ^ *((unsigned int *)v2+2);
242 case 8:
243 *((unsigned int *)data+1) = *((unsigned int *)v1+1) ^ *((unsigned int *)v2+1);
244 case 4:
245 *((unsigned int *)data+0) = *((unsigned int *)v1+0) ^ *((unsigned int *)v2+0);
246 break;
247 default:
248 while(len--) *data++ = *v1++ ^ *v2++;
249 break;
250 }
251}
252#define xor16(v1,v2,d) __xxor((d),16,(v1),(v2))
253#define val_by2on3(x) ((0xaaab*(x))>>16) //fixed point *2/3
254
255unsigned short cardkeys[3][32];
256unsigned char stateD3A[16];
257
258static void cCamCryptVG2_LongMult(unsigned short *pData, unsigned short *pLen, unsigned int mult, unsigned int carry);
259static void cCamCryptVG2_PartialMod(unsigned short val, unsigned int count, unsigned short *outkey, const unsigned short *inkey);
260static void cCamCryptVG2_RotateRightAndHash(unsigned char *p);
261static void cCamCryptVG2_Reorder16A(unsigned char *dest, const unsigned char *src);
262static void cCamCryptVG2_ReorderAndEncrypt(unsigned char *p);
263static void cCamCryptVG2_Process_D0(const unsigned char *ins, unsigned char *data);
264static void cCamCryptVG2_Process_D1(const unsigned char *ins, unsigned char *data, const unsigned char *status);
265static void cCamCryptVG2_Decrypt_D3(unsigned char *ins, unsigned char *data, const unsigned char *status);
266static void cCamCryptVG2_PostProcess_Decrypt(unsigned char *buff, int len, unsigned char *cw1, unsigned char *cw2);
267static void cCamCryptVG2_SetSeed(unsigned char *Key1, unsigned char *Key2);
268static void cCamCryptVG2_GetCamKey(unsigned char *buff);
269
270static void cCamCryptVG2_SetSeed(unsigned char *Key1, unsigned char *Key2)
271{
272 swap_lb (Key1, 64);
273 swap_lb (Key2, 64);
274 memcpy(cardkeys[1],Key1,sizeof(cardkeys[1]));
275 memcpy(cardkeys[2],Key2,sizeof(cardkeys[2]));
276 swap_lb (Key1, 64);
277 swap_lb (Key2, 64);
278}
279
280static void cCamCryptVG2_GetCamKey(unsigned char *buff)
281{
282 unsigned short *tb2=(unsigned short *)buff, c=1;
283 memset(tb2,0,64);
284 tb2[0]=1;
285 int i;
286 for(i=0; i<32; i++) cCamCryptVG2_LongMult(tb2,&c,cardkeys[1][i],0);
287 swap_lb (buff, 64);
288}
289
290static void cCamCryptVG2_PostProcess_Decrypt(unsigned char *buff, int len, unsigned char *cw1, unsigned char *cw2)
291{
292 switch(buff[0]) {
293 case 0xD0:
294 cCamCryptVG2_Process_D0(buff,buff+5);
295 break;
296 case 0xD1:
297 cCamCryptVG2_Process_D1(buff,buff+5,buff+buff[4]+5);
298 break;
299 case 0xD3:
300 cCamCryptVG2_Decrypt_D3(buff,buff+5,buff+buff[4]+5);
301 if(buff[1]==0x54) {
302 memcpy(cw1,buff+5,8);
303 memset(cw2,0,8); //set to 0 so client will know it is not valid if not overwritten with valid cw
304 int ind;
305 for(ind=13; ind<len+13-8; ind++) {
306 if(buff[ind]==0x25) {
307 //memcpy(cw2,buff+5+ind+2,8);
308 memcpy(cw2,buff+ind+3,8); //tested on viasat 093E, sky uk 0963, sky it 919 //don't care whether cw is 0 or not
309 break;
310 }
311/* if(buff[ind+1]==0) break;
312 ind+=buff[ind+1];*/
313 }
314 }
315 break;
316 }
317}
318
319static void cCamCryptVG2_Process_D0(const unsigned char *ins, unsigned char *data)
320{
321 switch(ins[1]) {
322 case 0xb4:
323 swap_lb (data, 64);
324 memcpy(cardkeys[0],data,sizeof(cardkeys[0]));
325 break;
326 case 0xbc:
327 {
328 swap_lb (data, 64);
329 unsigned short *idata=(unsigned short *)data;
330 const unsigned short *key1=(const unsigned short *)cardkeys[1];
331 unsigned short key2[32];
332 memcpy(key2,cardkeys[2],sizeof(key2));
333 int count2;
334 for(count2=0; count2<32; count2++) {
335 unsigned int rem=0, div=key1[count2];
336 int i;
337 for(i=31; i>=0; i--) {
338 unsigned int x=idata[i] | (rem<<16);
339 rem=(x%div)&0xffff;
340 }
341 unsigned int carry=1, t=val_by2on3(div) | 1;
342 while(t) {
343 if(t&1) carry=((carry*rem)%div)&0xffff;
344 rem=((rem*rem)%div)&0xffff;
345 t>>=1;
346 }
347 cCamCryptVG2_PartialMod(carry,count2,key2,key1);
348 }
349 unsigned short idatacount=0;
350 int i;
351 for(i=31; i>=0; i--) cCamCryptVG2_LongMult(idata,&idatacount,key1[i],key2[i]);
352 swap_lb (data, 64);
353 unsigned char stateD1[16];
354 cCamCryptVG2_Reorder16A(stateD1,data);
355 cAES_SetKey(stateD1);
356 break;
357 }
358 }
359}
360
361static void cCamCryptVG2_Process_D1(const unsigned char *ins, unsigned char *data, const unsigned char *status)
362{
363 unsigned char iter[16], tmp[16];
364 memset(iter,0,sizeof(iter));
365 memcpy(iter,ins,5);
366 xor16(iter,stateD3A,iter);
367 memcpy(stateD3A,iter,sizeof(iter));
368
369 int datalen=status-data;
370 int datalen1=datalen;
371 if(datalen<0) datalen1+=15;
372 int blocklen=datalen1>>4;
373 int i;
374 int iblock;
375 for(i=0,iblock=0; i<blocklen+2; i++,iblock+=16) {
376 unsigned char in[16];
377 int docalc=1;
378 if(blocklen==i && (docalc=datalen&0xf)) {
379 memset(in,0,sizeof(in));
380 memcpy(in,&data[iblock],datalen-(datalen1&~0xf));
381 }
382 else if(blocklen+1==i) {
383 memset(in,0,sizeof(in));
384 memcpy(&in[5],status,2);
385 }
386 else
387 memcpy(in,&data[iblock],sizeof(in));
388
389 if(docalc) {
390 xor16(iter,in,tmp);
391 cCamCryptVG2_ReorderAndEncrypt(tmp);
392 xor16(tmp,stateD3A,iter);
393 }
394 }
395 memcpy(stateD3A,tmp,16);
396}
397
398static void cCamCryptVG2_Decrypt_D3(unsigned char *ins, unsigned char *data, const unsigned char *status)
399{
400 if(ins[4]>16) ins[4]-=16;
401 if(ins[1]==0xbe) memset(stateD3A,0,sizeof(stateD3A));
402
403 unsigned char tmp[16];
404 memset(tmp,0,sizeof(tmp));
405 memcpy(tmp,ins,5);
406 xor16(tmp,stateD3A,stateD3A);
407
408 int len1=ins[4];
409 int blocklen=len1>>4;
410 if(ins[1]!=0xbe) blocklen++;
411
412 unsigned char iter[16], states[16][16];
413 memset(iter,0,sizeof(iter));
414 int blockindex;
415 for(blockindex=0; blockindex<blocklen; blockindex++) {
416 iter[0]+=blockindex;
417 xor16(iter,stateD3A,iter);
418 cCamCryptVG2_ReorderAndEncrypt(iter);
419 xor16(iter,&data[blockindex*16],states[blockindex]);
420 if(blockindex==(len1>>4)) {
421 int c=len1-(blockindex*16);
422 if(c<16) memset(&states[blockindex][c],0,16-c);
423 }
424 xor16(states[blockindex],stateD3A,stateD3A);
425 cCamCryptVG2_RotateRightAndHash(stateD3A);
426 }
427 memset(tmp,0,sizeof(tmp));
428 memcpy(tmp+5,status,2);
429 xor16(tmp,stateD3A,stateD3A);
430 cCamCryptVG2_ReorderAndEncrypt(stateD3A);
431
432 memcpy(stateD3A,status-16,sizeof(stateD3A));
433 cCamCryptVG2_ReorderAndEncrypt(stateD3A);
434
435 memcpy(data,states[0],len1);
436 if(ins[1]==0xbe) {
437 cCamCryptVG2_Reorder16A(tmp,states[0]);
438 cAES_SetKey(tmp);
439 }
440}
441
442static void cCamCryptVG2_ReorderAndEncrypt(unsigned char *p)
443{
444 unsigned char tmp[16];
445 cCamCryptVG2_Reorder16A(tmp,p);
446 cAES_Encrypt(tmp,16,tmp);
447 cCamCryptVG2_Reorder16A(p,tmp);
448}
449
450// reorder AAAABBBBCCCCDDDD to ABCDABCDABCDABCD
451
452static void cCamCryptVG2_Reorder16A(unsigned char *dest, const unsigned char *src)
453{
454 int i;
455 int j;
456 int k;
457 for(i=0,k=0; i<4; i++)
458 for(j=i; j<16; j+=4,k++)
459 dest[k]=src[j];
460}
461
462static void cCamCryptVG2_LongMult(unsigned short *pData, unsigned short *pLen, unsigned int mult, unsigned int carry)
463{
464 int i;
465 for(i=0; i<*pLen; i++) {
466 carry+=pData[i]*mult;
467 pData[i]=(unsigned short)carry;
468 carry>>=16;
469 }
470 if(carry) pData[(*pLen)++]=carry;
471}
472
473static void cCamCryptVG2_PartialMod(unsigned short val, unsigned int count, unsigned short *outkey, const unsigned short *inkey)
474{
475 if(count) {
476 unsigned int mod=inkey[count];
477 unsigned short mult=(inkey[count]-outkey[count-1])&0xffff;
478 unsigned int i;
479 unsigned int ib1;
480 for(i=0,ib1=count-2; i<count-1; i++,ib1--) {
481 unsigned int t=(inkey[ib1]*mult)%mod;
482 mult=t-outkey[ib1];
483 if(mult>t) mult+=mod;
484 }
485 mult+=val;
486 if((val>mult) || (mod<mult)) mult-=mod;
487 outkey[count]=(outkey[count]*mult)%mod;
488 }
489 else
490 outkey[0]=val;
491}
492
493static const unsigned char table1[256] = {
494 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5, 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
495 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0, 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
496 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc, 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
497 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a, 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
498 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0, 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
499 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b, 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
500 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85, 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
501 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5, 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
502 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17, 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
503 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88, 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
504 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c, 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
505 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9, 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
506 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6, 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
507 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e, 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
508 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94, 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
509 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68, 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16,
510 };
511
512static void cCamCryptVG2_RotateRightAndHash(unsigned char *p)
513{
514 unsigned char t1=p[15];
515 int i;
516 for(i=0; i<16; i++) {
517 unsigned char t2=t1;
518 t1=p[i]; p[i]=table1[(t1>>1)|((t2&1)<<7)];
519 }
520}
521
522////// ====================================================================================
523
524unsigned char CW1[8], CW2[8];
525
526extern uchar cta_res[];
527extern ushort cta_lr;
528
529extern int io_serial_need_dummy_char;
530
531struct CmdTabEntry {
532 unsigned char cla;
533 unsigned char cmd;
534 unsigned char len;
535 unsigned char mode;
536};
537
538struct CmdTab {
539 unsigned char index;
540 unsigned char size;
541 unsigned char Nentries;
542 unsigned char dummy;
543 struct CmdTabEntry e[1];
544};
545
546struct CmdTab *cmd_table=NULL;
547static void memorize_cmd_table (const unsigned char *mem, int size){
548 cmd_table=(struct CmdTab *)malloc(sizeof(unsigned char) * size);
549 memcpy(cmd_table,mem,size);
550}
551
552static int cmd_table_get_info(const unsigned char *cmd, unsigned char *rlen, unsigned char *rmode)
553{
554 struct CmdTabEntry *pcte=cmd_table->e;
555 int i;
556 for(i=0; i<cmd_table->Nentries; i++,pcte++)
557 if(cmd[1]==pcte->cmd) {
558 *rlen=pcte->len;
559 *rmode=pcte->mode;
560 return 1;
561 }
562 return 0;
563}
564
565static int status_ok(const unsigned char *status){
566 //cs_log("[videoguard2-reader] check status %02x%02x", status[0],status[1]);
567 return (status[0] == 0x90 || status[0] == 0x91)
568 && (status[1] == 0x00 || status[1] == 0x01
569 || status[1] == 0x20 || status[1] == 0x21
570 || status[1] == 0x80 || status[1] == 0x81
571 || status[1] == 0xa0 || status[1] == 0xa1);
572}
573
574#define write_cmd(cmd, data) (card_write(cmd, data) == 0)
575#define read_cmd(cmd, data) (card_write(cmd, NULL) == 0)
576
577static int read_cmd_len(const unsigned char *cmd)
578{
579 unsigned char cmd2[5];
580 memcpy(cmd2,cmd,5);
581 cmd2[3]=0x80;
582 cmd2[4]=1;
583 if(!read_cmd(cmd2,NULL) || cta_res[1] != 0x90 || cta_res[2] != 0x00) {
584 cs_debug("[videoguard2-reader] failed to read %02x%02x cmd length (%02x %02x)",cmd[1],cmd[2],cta_res[1],cta_res[2]);
585 return -1;
586 }
587 return cta_res[0];
588}
589
590static int do_cmd(const unsigned char *ins, const unsigned char *txbuff, unsigned char *rxbuff)
591{
592 unsigned char ins2[5];
593 memcpy(ins2,ins,5);
594 unsigned char len=0, mode=0;
595 if(cmd_table_get_info(ins2,&len,&mode)) {
596 if(len==0xFF && mode==2) {
597 if(ins2[4]==0) ins2[4]=len=read_cmd_len(ins2);
598 }
599 else if(mode!=0) ins2[4]=len;
600 }
601 if(ins2[0]==0xd3) ins2[4]=len+16;
602 len=ins2[4];
603
604 unsigned char tmp[264];
605 if(!rxbuff) rxbuff=tmp;
606 if(mode>1) {
607 if(!read_cmd(ins2,NULL) || !status_ok(cta_res+len)) return -1;
608 memcpy(rxbuff,ins2,5);
609 memcpy(rxbuff+5,cta_res,len);
610 memcpy(rxbuff+5+len,cta_res+len,2);
611 }
612 else {
613 if(!write_cmd(ins2,(uchar *)txbuff) || !status_ok(cta_res)) return -2;
614 memcpy(rxbuff,ins2,5);
615 memcpy(rxbuff+5,txbuff,len);
616 memcpy(rxbuff+5+len,cta_res,2);
617 }
618
619 cCamCryptVG2_PostProcess_Decrypt(rxbuff,len,CW1,CW2);
620
621 // Log decrypted INS54
622 ///if (rxbuff[1] == 0x54) {
623 /// cs_dump (rxbuff, 5, "Decrypted INS54:");
624 /// cs_dump (rxbuff + 5, rxbuff[4], "");
625 ///}
626
627 return len;
628}
629
630static void rev_date_calc(const unsigned char *Date, int *year, int *mon, int *day, int *hh, int *mm, int *ss)
631{
632 *year=(Date[0]/12)+BASEYEAR;
633 *mon=(Date[0]%12)+1;
634 *day=Date[1];
635 *hh=Date[2]/8;
636 *mm=(0x100*(Date[2]-*hh*8)+Date[3])/32;
637 *ss=(Date[3]-*mm*32)*2;
638}
639
640typedef struct{
641 unsigned short id;
642 char name[32];
643} tier_t;
644
645static tier_t skyit_tiers[] =
646{
647 { 0x0320, "Promo" },
648 { 0x000B, "Service" },
649 { 0x0219, "Mondo HD" },
650 { 0x021A, "Cinema HD" },
651 { 0x021B, "Cinema" },
652 { 0x0222, "Sport HD" },
653 { 0x0224, "Sky Play IT" },
654 { 0x0226, "Mondo" },
655 { 0x0228, "Sport" },
656 { 0x0229, "Disney Channel" },
657 { 0x022A, "Inter Channel" },
658 { 0x022B, "Milan Channel" },
659 { 0x022C, "Roma Channel" },
660 { 0x022D, "Classica" },
661 { 0x022E, "Music & News" },
662 { 0x022F, "Caccia e Pesca" },
663 { 0x023D, "Juventus Channel" },
664 { 0x023E, "Moto TV" },
665 { 0x026B, "Calcio HD" },
666 { 0x0275, "Promo" },
667 { 0x0295, "Calcio" },
668 { 0x0296, "Serie B" },
669 { 0x02FE, "PPV" }
670};
671
672static char *get_tier_name(unsigned short tier_id){
673 static char *empty = "";
674 unsigned int i;
675
676 switch (reader[ridx].caid[0])
677 {
678 case 0x919:
679 case 0x93b:
680 for (i = 0; i < sizeof(skyit_tiers) / sizeof(tier_t); ++i)
681 if (skyit_tiers[i].id == tier_id)
682 return skyit_tiers[i].name;
683 break;
684 }
685 return empty;
686}
687
688static void read_tiers(void)
689{
690 static const unsigned char ins2a[5] = { 0xd0,0x2a,0x00,0x00,0x00 };
691 int l;
692 l=do_cmd(ins2a,NULL,NULL);
693 if(l<0 || !status_ok(cta_res+l)) return;
694 static unsigned char ins76[5] = { 0xd0,0x76,0x00,0x00,0x00 };
695 ins76[3]=0x7f; ins76[4]=2;
696 if(!read_cmd(ins76,NULL) || !status_ok(cta_res+2)) return;
697 ins76[3]=0; ins76[4]=0;
698 int num=cta_res[1];
699 int i;
700 reader[ridx].init_history_pos = 0; //reset for re-read
701 memset(reader[ridx].init_history, 0, sizeof(reader[ridx].init_history));
702 for(i=0; i<num; i++) {
703 ins76[2]=i;
704 l=do_cmd(ins76,NULL,NULL);
705 if(l<0 || !status_ok(cta_res+l)) return;
706 if(cta_res[2]==0 && cta_res[3]==0) break;
707 int y,m,d,H,M,S;
708 rev_date_calc(&cta_res[4],&y,&m,&d,&H,&M,&S);
709 unsigned short tier_id = (cta_res[2] << 8) | cta_res[3];
710 char *tier_name = get_tier_name(tier_id);
711 cs_ri_log("[videoguard2-reader] tier: %04x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d %s",tier_id,y,m,d,H,M,S,tier_name);
712 }
713}
714
715int videoguard_card_init(ATR newatr)
716{
717 get_hist;
718 if ((hist_size < 7) || (hist[1] != 0xB0) || (hist[4] != 0xFF) || (hist[5] != 0x4A) || (hist[6] != 0x50))
719 return ERROR;
720 get_atr;
721 /* known atrs */
722 unsigned char atr_bskyb[] = { 0x3F, 0x7F, 0x13, 0x25, 0x03, 0x33, 0xB0, 0x06, 0x69, 0xFF, 0x4A, 0x50, 0xD0, 0x00, 0x00, 0x53, 0x59, 0x00, 0x00, 0x00 };
723 unsigned char atr_bskyb_new[] = { 0x3F, 0xFD, 0x13, 0x25, 0x02, 0x50, 0x00, 0x0F, 0x33, 0xB0, 0x0F, 0x69, 0xFF, 0x4A, 0x50, 0xD0, 0x00, 0x00, 0x53, 0x59, 0x02 };
724 unsigned char atr_skyitalia[] = { 0x3F, 0xFF, 0x13, 0x25, 0x03, 0x10, 0x80, 0x33, 0xB0, 0x0E, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x49, 0x54, 0x02, 0x00, 0x00 };
725 unsigned char atr_skyitalia93b[] = { 0x3F, 0xFD, 0x13, 0x25, 0x02, 0x50, 0x80, 0x0F, 0x33, 0xB0, 0x13, 0x69, 0xFF, 0x4A, 0x50, 0xD0, 0x80, 0x00, 0x49, 0x54, 0x03 };
726 unsigned char atr_directv[] = { 0x3F, 0x78, 0x13, 0x25, 0x03, 0x40, 0xB0, 0x20, 0xFF, 0xFF, 0x4A, 0x50, 0x00 };
727 unsigned char atr_yes[] = { 0x3F, 0xFF, 0x13, 0x25, 0x03, 0x10, 0x80, 0x33, 0xB0, 0x11, 0x69, 0xFF, 0x4A, 0x50, 0x50, 0x00, 0x00, 0x47, 0x54, 0x01, 0x00, 0x00 };
728 unsigned char atr_viasat_new[] = { 0x3F, 0x7D, 0x11, 0x25, 0x02, 0x41, 0xB0, 0x03, 0x69, 0xFF, 0x4A, 0x50, 0xF0, 0x80, 0x00, 0x56, 0x54, 0x03};
729 unsigned char atr_viasat_scandinavia[] = { 0x3F, 0x7F, 0x11, 0x25, 0x03, 0x33, 0xB0, 0x09, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x56, 0x54, 0x01, 0x00, 0x00 };
730 unsigned char atr_premiere[] = { 0x3F, 0xFF, 0x11, 0x25, 0x03, 0x10, 0x80, 0x41, 0xB0, 0x07, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x50, 0x31, 0x01, 0x00, 0x11 };
731 unsigned char atr_kbw[] = { 0x3F, 0xFF, 0x14, 0x25, 0x03, 0x10, 0x80, 0x54, 0xB0, 0x01, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x4B, 0x57, 0x01, 0x00, 0x00};
732 unsigned char atr_get[] = { 0x3F, 0xFF, 0x14, 0x25, 0x03, 0x10, 0x80, 0x33, 0xB0, 0x10, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x5A, 0x45, 0x01, 0x00, 0x00};
733 unsigned char atr_foxtel_90b[] = { 0x3F, 0x7F, 0x11, 0x25, 0x03, 0x33, 0xB0, 0x09, 0x69, 0xFF, 0x4A, 0x50, 0x70, 0x00, 0x00, 0x46, 0x44, 0x01, 0x00, 0x00};
734
735 if ((atr_size == sizeof (atr_bskyb)) && (memcmp (atr, atr_bskyb, atr_size) == 0))
736 {
737 cs_ri_log("[videoguard2-reader] type: VideoGuard BSkyB");
738 /* BSkyB seems to need one additionnal byte in the serial communication... */
739 io_serial_need_dummy_char = 1;
740 BASEYEAR = 2000;
741 }
742 else if ((atr_size == sizeof (atr_bskyb_new)) && (memcmp (atr, atr_bskyb_new, atr_size) == 0))
743 {
744 cs_ri_log("[videoguard2-reader] type: VideoGuard BSkyB - New");
745 }
746 else if ((atr_size == sizeof (atr_skyitalia)) && (memcmp (atr, atr_skyitalia, atr_size) == 0))
747 {
748 cs_ri_log("[videoguard2-reader] type: VideoGuard Sky Italia");
749 }
750 else if ((atr_size == sizeof (atr_directv)) && (memcmp (atr, atr_directv, atr_size) == 0))
751 {
752 cs_ri_log("[videoguard2-reader] type: VideoGuard DirecTV");
753 }
754 else if ((atr_size == sizeof (atr_yes)) && (memcmp (atr, atr_yes, atr_size) == 0))
755 {
756 cs_ri_log("[videoguard2-reader] type: VideoGuard YES DBS Israel");
757 }
758 else if ((atr_size == sizeof (atr_viasat_new)) && (memcmp (atr, atr_viasat_new, atr_size) == 0))
759 {
760 cs_ri_log("[videoguard2-reader] type: VideoGuard Viasat new (093E)");
761 BASEYEAR = 2000;
762 }
763 else if ((atr_size == sizeof (atr_viasat_scandinavia)) && (memcmp (atr, atr_viasat_scandinavia, atr_size) == 0))
764 {
765 cs_ri_log("[videoguard2-reader] type: VideoGuard Viasat Scandinavia");
766 BASEYEAR = 2000;
767 }
768 else if ((atr_size == sizeof (atr_skyitalia93b)) && (memcmp (atr, atr_skyitalia93b, atr_size) == 0))
769 {
770 cs_ri_log("[videoguard2-reader] type: VideoGuard Sky Italia new (093B)");
771 }
772 else if ((atr_size == sizeof (atr_premiere)) && (memcmp (atr, atr_premiere, atr_size) == 0))
773 {
774 cs_ri_log("[videoguard2-reader] type: VideoGuard Sky Germany");
775 }
776 else if ((atr_size == sizeof (atr_kbw)) && (memcmp (atr, atr_kbw, atr_size) == 0))
777 {
778 cs_ri_log("[videoguard2-reader] type: VideoGuard Kabel BW");
779 }
780 else if ((atr_size == sizeof (atr_get)) && (memcmp (atr, atr_get, atr_size) == 0))
781 {
782 cs_ri_log("[videoguard2-reader] type: VideoGuard Get Kabel Norway");
783 BASEYEAR = 2004;
784 }
785 else if ((atr_size == sizeof (atr_foxtel_90b)) && (memcmp (atr, atr_foxtel_90b, atr_size) == 0))
786 {
787 cs_ri_log("[videoguard2-reader] type: VideoGuard Foxtel Australia (090b)");
788 BASEYEAR = 2000;
789 }
790/* else
791 {
792 // not a known videoguard
793 return (0);
794 }*/
795 //a non videoguard2/NDS card will fail on read_cmd_len(ins7401)
796 //this way also unknown videoguard2/NDS cards will work
797
798 unsigned char ins7401[5] = { 0xD0,0x74,0x01,0x00,0x00 };
799 int l;
800 if((l=read_cmd_len(ins7401))<0) return ERROR; //not a videoguard2/NDS card or communication error
801 ins7401[4]=l;
802 if(!read_cmd(ins7401,NULL) || !status_ok(cta_res+l)) {
803 cs_log ("[videoguard2-reader] failed to read cmd list");
804 return ERROR;
805 }
806 memorize_cmd_table (cta_res,l);
807
808 unsigned char buff[256];
809
810 unsigned char ins7416[5] = { 0xD0,0x74,0x16,0x00,0x00 };
811 if(do_cmd(ins7416, NULL, NULL)<0) {
812 cs_log ("[videoguard2-reader] cmd 7416 failed");
813 return ERROR;
814 }
815
816 unsigned char ins36[5] = { 0xD0,0x36,0x00,0x00,0x00 };
817 unsigned char boxID [4];
818
819 if (reader[ridx].boxid > 0) {
820 /* the boxid is specified in the config */
821 int i;
822 for (i=0; i < 4; i++) {
823 boxID[i] = (reader[ridx].boxid >> (8 * (3 - i))) % 0x100;
824 }
825 } else {
826 /* we can try to get the boxid from the card */
827 int boxidOK=0;
828 l=do_cmd(ins36, NULL, buff);
829 if(l>=0) {
830 int i;
831 for(i=0; i<l ;i++) {
832 if(buff[i+1]==0xF3 && (buff[i]==0x00 || buff[i]==0x0A)) {
833 memcpy(&boxID,&buff[i+2],sizeof(boxID));
834 boxidOK=1;
835 break;
836 }
837 }
838 }
839
840 if(!boxidOK) {
841 cs_log ("[videoguard2-reader] no boxID available");
842 return ERROR;
843 }
844 }
845
846 unsigned char ins4C[5] = { 0xD0,0x4C,0x00,0x00,0x09 };
847 unsigned char payload4C[9] = { 0,0,0,0, 3,0,0,0,4 };
848 memcpy(payload4C,boxID,4);
849 if(!write_cmd(ins4C,payload4C) || !status_ok(cta_res+l)) {
850 cs_log("[videoguard2-reader] sending boxid failed");
851 return ERROR;
852 }
853
854 //short int SWIRDstatus = cta_res[1];
855 unsigned char ins58[5] = { 0xD0,0x58,0x00,0x00,0x00 };
856 l=do_cmd(ins58, NULL, buff);
857 if(l<0) {
858 cs_log("[videoguard2-reader] cmd ins58 failed");
859 return ERROR;
860 }
861 memset(reader[ridx].hexserial, 0, 8);
862 memcpy(reader[ridx].hexserial+2, cta_res+3, 4);
863 reader[ridx].caid[0] = cta_res[24]*0x100+cta_res[25];
864
865 /* we have one provider, 0x0000 */
866 reader[ridx].nprov = 1;
867 memset(reader[ridx].prid, 0x00, sizeof(reader[ridx].prid));
868
869 /*
870 cs_log ("[videoguard2-reader] INS58 : Fuse byte=0x%02X, IRDStatus=0x%02X", cta_res[2],SWIRDstatus);
871 if (SWIRDstatus==4) {
872 // If swMarriage=4, not married then exchange for BC Key
873 cs_log ("[videoguard2-reader] Card not married, exchange for BC Keys");
874 */
875
876 unsigned char seed1[] = {
877 0xb9, 0xd5, 0xef, 0xd5, 0xf5, 0xd5, 0xfb, 0xd5, 0x31, 0xd6, 0x43, 0xd6, 0x55, 0xd6, 0x61, 0xd6,
878 0x85, 0xd6, 0x9d, 0xd6, 0xaf, 0xd6, 0xc7, 0xd6, 0xd9, 0xd6, 0x09, 0xd7, 0x15, 0xd7, 0x21, 0xd7,
879 0x27, 0xd7, 0x3f, 0xd7, 0x45, 0xd7, 0xb1, 0xd7, 0xbd, 0xd7, 0xdb, 0xd7, 0x11, 0xd8, 0x23, 0xd8,
880 0x29, 0xd8, 0x2f, 0xd8, 0x4d, 0xd8, 0x8f, 0xd8, 0xa1, 0xd8, 0xad, 0xd8, 0xbf, 0xd8, 0xd7, 0xd8
881 };
882 unsigned char seed2[] = {
883 0x01, 0x00, 0xcf, 0x13, 0xe0, 0x60, 0x54, 0xac, 0xab, 0x99, 0xe6, 0x0c, 0x9f, 0x5b, 0x91, 0xb9,
884 0x72, 0x72, 0x4d, 0x5b, 0x5f, 0xd3, 0xb7, 0x5b, 0x01, 0x4d, 0xef, 0x9e, 0x6b, 0x8a, 0xb9, 0xd1,
885 0xc9, 0x9f, 0xa1, 0x2a, 0x8d, 0x86, 0xb6, 0xd6, 0x39, 0xb4, 0x64, 0x65, 0x13, 0x77, 0xa1, 0x0a,
886 0x0c, 0xcf, 0xb4, 0x2b, 0x3a, 0x2f, 0xd2, 0x09, 0x92, 0x15, 0x40, 0x47, 0x66, 0x5c, 0xda, 0xc9
887 };
888 cCamCryptVG2_SetSeed(seed1,seed2);
889
890 unsigned char insB4[5] = { 0xD0,0xB4,0x00,0x00,0x40 };
891 unsigned char tbuff[64];
892 cCamCryptVG2_GetCamKey(tbuff);
893 l=do_cmd(insB4, tbuff, NULL);
894 if(l<0 || !status_ok(cta_res)) {
895 cs_log ("[videoguard2-reader] cmd D0B4 failed (%02X%02X)", cta_res[0], cta_res[1]);
896 return ERROR;
897 }
898
899 unsigned char insBC[5] = { 0xD0,0xBC,0x00,0x00,0x00 };
900 l=do_cmd(insBC, NULL, NULL);
901 if(l<0) {
902 cs_log("[videoguard2-reader] cmd D0BC failed");
903 return ERROR;
904 }
905
906 unsigned char insBE[5] = { 0xD3,0xBE,0x00,0x00,0x00 };
907 l=do_cmd(insBE, NULL, NULL);
908 if(l<0) {
909 cs_log("[videoguard2-reader] cmd D3BE failed");
910 return ERROR;
911 }
912
913 unsigned char ins58a[5] = { 0xD1,0x58,0x00,0x00,0x00 };
914 l=do_cmd(ins58a, NULL, NULL);
915 if(l<0) {
916 cs_log("[videoguard2-reader] cmd D158 failed");
917 return ERROR;
918 }
919
920 unsigned char ins4Ca[5] = { 0xD1,0x4C,0x00,0x00,0x00 };
921 l=do_cmd(ins4Ca,payload4C, NULL);
922 if(l<0 || !status_ok(cta_res)) {
923 cs_log("[videoguard2-reader] cmd D14Ca failed");
924 return ERROR;
925 }
926
927 cs_ri_log("[videoguard2-reader] type: VideoGuard, caid: %04X, serial: %02X%02X%02X%02X, BoxID: %02X%02X%02X%02X",
928 reader[ridx].caid[0],
929 reader[ridx].hexserial[2],reader[ridx].hexserial[3],reader[ridx].hexserial[4],reader[ridx].hexserial[5],
930 boxID[0],boxID[1],boxID[2],boxID[3]);
931
932 ///read_tiers();
933
934 cs_log("[videoguard2-reader] ready for requests");
935
936 return OK;
937}
938
939int videoguard_do_ecm(ECM_REQUEST *er)
940{
941 static unsigned char ins40[5] = { 0xD1,0x40,0x00,0x80,0xFF };
942 static const unsigned char ins54[5] = { 0xD3,0x54,0x00,0x00,0x00};
943 int posECMpart2=er->ecm[6]+7;
944 int lenECMpart2=er->ecm[posECMpart2]+1;
945 unsigned char tbuff[264];
946 tbuff[0]=0;
947 memcpy(&tbuff[1],&(er->ecm[posECMpart2+1]),lenECMpart2-1);
948 ins40[4]=lenECMpart2;
949 int l;
950 l = do_cmd(ins40,tbuff,NULL);
951 if(l>0 && status_ok(cta_res)) {
952 l = do_cmd(ins54,NULL,NULL);
953 if(l>0 && status_ok(cta_res+l)) {
954 if (!cw_is_valid(CW1)) //sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
955 return ERROR;
956 if(er->ecm[0]&1) {
957 memcpy(er->cw+8,CW1,8);
958 memcpy(er->cw+0,CW2,8);
959 }
960 else {
961 memcpy(er->cw+0,CW1,8);
962 memcpy(er->cw+8,CW2,8);
963 }
964
965 //test for postprocessing marker
966 int posB0 = -1;
967 int i;
968 for (i = 6; i < posECMpart2; i++)
969 {
970 if (er->ecm[i] == 0xB0 && er->ecm[i+1] == 0x01 ) {
971 posB0 = i;
972 break;
973 }
974 }
975 if (posB0 != -1) {
976 postprocess_cw(er->cw+0, er->ecm[posB0+2]);
977 postprocess_cw(er->cw+8, er->ecm[posB0+2]);
978 }
979 return OK;
980 }
981 }
982 return ERROR;
983}
984
985static int num_addr(const unsigned char *data)
986{
987 return ((data[3]&0x30)>>4)+1;
988}
989
990static int addr_mode(const unsigned char *data)
991{
992 switch(data[3]&0xC0) {
993 case 0x40: return 3;
994 case 0x80: return 2;
995 default: return 0;
996 }
997}
998
999static const unsigned char * payload_addr(const unsigned char *data, const unsigned char *a)
1000{
1001 int s;
1002 int l;
1003 const unsigned char *ptr = NULL;
1004
1005 switch(addr_mode(data)) {
1006 case 2: s=3; break;
1007 case 3: case 0: s=4; break;
1008 default: return NULL;
1009 }
1010
1011 int position=-1;
1012 for(l=0;l<num_addr(data);l++) {
1013 if(!memcmp(&data[l*4+4],a+2,s)) {
1014 position=l;
1015 break;
1016 }
1017 }
1018
1019 /* skip EMM-G but not EMM from cccam */
1020 if (position == -1 && data[1] != 0x00) return NULL;
1021
1022 int num_ua = (position == -1) ? 0 : num_addr(data);
1023
1024 /* skip header and the list of addresses */
1025 ptr = data+4+4*num_ua;
1026
1027 if (*ptr != 0x02) // some clients omit 00 00 separator */
1028 {
1029 ptr += 2; // skip 00 00 separator
1030 if (*ptr == 0x00) ptr++; // skip optional 00
1031 ptr++; // skip the 1st bitmap len
1032 }
1033
1034 /* check */
1035 if (*ptr != 0x02) return NULL;
1036
1037 /* skip the 1st timestamp 02 00 or 02 06 xx aabbccdd yy */
1038 ptr += 2 + ptr[1];
1039
1040 for(l=0;l<position;l++) {
1041
1042 /* skip the payload of the previous SA */
1043 ptr += 1 + ptr [0];
1044
1045 /* skip optional 00 */
1046 if (*ptr == 0x00) ptr++;
1047
1048 /* skip the bitmap len */
1049 ptr++;
1050
1051 /* check */
1052 if (*ptr != 0x02) return NULL;
1053
1054 /* skip the timestamp 02 00 or 02 06 xx aabbccdd yy */
1055 ptr += 2 + ptr[1];
1056 }
1057
1058 return ptr;
1059}
1060
1061int videoguard_do_emm(EMM_PACKET *ep)
1062{
1063 unsigned char ins42[5] = { 0xD1,0x42,0x00,0x00,0xFF };
1064 int rc=ERROR;
1065
1066 const unsigned char *payload = payload_addr(ep->emm, reader[ridx].hexserial);
1067 while (payload) {
1068 ins42[4]=*payload;
1069 int l = do_cmd(ins42,payload+1,NULL);
1070 if(l>0 && status_ok(cta_res)) {
1071 rc=OK;
1072 }
1073
1074 cs_log("[videoguard2-reader] EMM request return code : %02X%02X", cta_res[0], cta_res[1]);
1075//cs_dump(ep->emm, 64, "EMM:");
1076 if (status_ok (cta_res) && (cta_res[1] & 0x01)) {
1077 read_tiers();
1078 }
1079
1080 if (num_addr(ep->emm) == 1 && (int)(&payload[1] - &ep->emm[0]) + *payload + 1 < ep->l) {
1081 payload += *payload + 1;
1082 if (*payload == 0x00) ++payload;
1083 ++payload;
1084 if (*payload != 0x02) break;
1085 payload += 2 + payload[1];
1086 }
1087 else
1088 payload = 0;
1089
1090 }
1091
1092 return(rc);
1093}
1094
1095int videoguard_card_info(void)
1096{
1097 /* info is displayed in init, or when processing info */
1098 cs_log("[videoguard2-reader] card detected");
1099 cs_log("[videoguard2-reader] type: VideoGuard" );
1100 read_tiers ();
1101 return OK;
1102}
Note: See TracBrowser for help on using the repository browser.