source: trunk/reader-videoguard2.c@ 1664

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

Fix CRLF linefeeds

File size: 43.8 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
640static void read_tiers(void)
641{
642 static const unsigned char ins2a[5] = { 0xd0,0x2a,0x00,0x00,0x00 };
643 int l;
644 l=do_cmd(ins2a,NULL,NULL);
645 if(l<0 || !status_ok(cta_res+l)) return;
646 static unsigned char ins76[5] = { 0xd0,0x76,0x00,0x00,0x00 };
647 ins76[3]=0x7f; ins76[4]=2;
648 if(!read_cmd(ins76,NULL) || !status_ok(cta_res+2)) return;
649 ins76[3]=0; ins76[4]=0;
650 int num=cta_res[1];
651 int i;
652 for(i=0; i<num; i++) {
653 ins76[2]=i;
654 l=do_cmd(ins76,NULL,NULL);
655 if(l<0 || !status_ok(cta_res+l)) return;
656 if(cta_res[2]==0 && cta_res[3]==0) break;
657 int y,m,d,H,M,S;
658 rev_date_calc(&cta_res[4],&y,&m,&d,&H,&M,&S);
659 cs_ri_log("[videoguard2-reader] tier: %02x%02x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d",cta_res[2],cta_res[3],y,m,d,H,M,S);
660 }
661}
662
663int videoguard_card_init(ATR newatr)
664{
665 get_hist;
666 if ((hist_size < 7) || (hist[1] != 0xB0) || (hist[4] != 0xFF) || (hist[5] != 0x4A) || (hist[6] != 0x50))
667 return ERROR;
668 get_atr;
669 /* known atrs */
670 unsigned char atr_bskyb[] = { 0x3F, 0x7F, 0x13, 0x25, 0x03, 0x33, 0xB0, 0x06, 0x69, 0xFF, 0x4A, 0x50, 0xD0, 0x00, 0x00, 0x53, 0x59, 0x00, 0x00, 0x00 };
671 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 };
672 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 };
673 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 };
674 unsigned char atr_directv[] = { 0x3F, 0x78, 0x13, 0x25, 0x03, 0x40, 0xB0, 0x20, 0xFF, 0xFF, 0x4A, 0x50, 0x00 };
675 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 };
676 unsigned char atr_viasat_new[] = { 0x3F, 0x7D, 0x11, 0x25, 0x02, 0x41, 0xB0, 0x03, 0x69, 0xFF, 0x4A, 0x50, 0xF0, 0x80, 0x00, 0x56, 0x54, 0x03};
677 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 };
678 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 };
679 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};
680 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};
681 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};
682
683 if ((atr_size == sizeof (atr_bskyb)) && (memcmp (atr, atr_bskyb, atr_size) == 0))
684 {
685 cs_ri_log("[videoguard2-reader] type: VideoGuard BSkyB");
686 /* BSkyB seems to need one additionnal byte in the serial communication... */
687 io_serial_need_dummy_char = 1;
688 BASEYEAR = 2000;
689 }
690 else if ((atr_size == sizeof (atr_bskyb_new)) && (memcmp (atr, atr_bskyb_new, atr_size) == 0))
691 {
692 cs_ri_log("[videoguard2-reader] type: VideoGuard BSkyB - New");
693 }
694 else if ((atr_size == sizeof (atr_skyitalia)) && (memcmp (atr, atr_skyitalia, atr_size) == 0))
695 {
696 cs_ri_log("[videoguard2-reader] type: VideoGuard Sky Italia");
697 }
698 else if ((atr_size == sizeof (atr_directv)) && (memcmp (atr, atr_directv, atr_size) == 0))
699 {
700 cs_ri_log("[videoguard2-reader] type: VideoGuard DirecTV");
701 }
702 else if ((atr_size == sizeof (atr_yes)) && (memcmp (atr, atr_yes, atr_size) == 0))
703 {
704 cs_ri_log("[videoguard2-reader] type: VideoGuard YES DBS Israel");
705 }
706 else if ((atr_size == sizeof (atr_viasat_new)) && (memcmp (atr, atr_viasat_new, atr_size) == 0))
707 {
708 cs_ri_log("[videoguard2-reader] type: VideoGuard Viasat new (093E)");
709 BASEYEAR = 2000;
710 }
711 else if ((atr_size == sizeof (atr_viasat_scandinavia)) && (memcmp (atr, atr_viasat_scandinavia, atr_size) == 0))
712 {
713 cs_ri_log("[videoguard2-reader] type: VideoGuard Viasat Scandinavia");
714 BASEYEAR = 2000;
715 }
716 else if ((atr_size == sizeof (atr_skyitalia93b)) && (memcmp (atr, atr_skyitalia93b, atr_size) == 0))
717 {
718 cs_ri_log("[videoguard2-reader] type: VideoGuard Sky Italia new (093B)");
719 }
720 else if ((atr_size == sizeof (atr_premiere)) && (memcmp (atr, atr_premiere, atr_size) == 0))
721 {
722 cs_ri_log("[videoguard2-reader] type: VideoGuard Sky Germany");
723 }
724 else if ((atr_size == sizeof (atr_kbw)) && (memcmp (atr, atr_kbw, atr_size) == 0))
725 {
726 cs_ri_log("[videoguard2-reader] type: VideoGuard Kabel BW");
727 }
728 else if ((atr_size == sizeof (atr_get)) && (memcmp (atr, atr_get, atr_size) == 0))
729 {
730 cs_ri_log("[videoguard2-reader] type: VideoGuard Get Kabel Norway");
731 BASEYEAR = 2004;
732 }
733 else if ((atr_size == sizeof (atr_foxtel_90b)) && (memcmp (atr, atr_foxtel_90b, atr_size) == 0))
734 {
735 cs_ri_log("[videoguard2-reader] type: VideoGuard Foxtel Australia (090b)");
736 BASEYEAR = 2000;
737 }
738/* else
739 {
740 // not a known videoguard
741 return (0);
742 }*/
743 //a non videoguard2/NDS card will fail on read_cmd_len(ins7401)
744 //this way also unknown videoguard2/NDS cards will work
745
746 unsigned char ins7401[5] = { 0xD0,0x74,0x01,0x00,0x00 };
747 int l;
748 if((l=read_cmd_len(ins7401))<0) return ERROR; //not a videoguard2/NDS card or communication error
749 ins7401[4]=l;
750 if(!read_cmd(ins7401,NULL) || !status_ok(cta_res+l)) {
751 cs_log ("[videoguard2-reader] failed to read cmd list");
752 return ERROR;
753 }
754 memorize_cmd_table (cta_res,l);
755
756 unsigned char buff[256];
757
758 unsigned char ins7416[5] = { 0xD0,0x74,0x16,0x00,0x00 };
759 if(do_cmd(ins7416, NULL, NULL)<0) {
760 cs_log ("[videoguard2-reader] cmd 7416 failed");
761 return ERROR;
762 }
763
764 unsigned char ins36[5] = { 0xD0,0x36,0x00,0x00,0x00 };
765 unsigned char boxID [4];
766
767 if (reader[ridx].boxid > 0) {
768 /* the boxid is specified in the config */
769 int i;
770 for (i=0; i < 4; i++) {
771 boxID[i] = (reader[ridx].boxid >> (8 * (3 - i))) % 0x100;
772 }
773 } else {
774 /* we can try to get the boxid from the card */
775 int boxidOK=0;
776 l=do_cmd(ins36, NULL, buff);
777 if(l>=0) {
778 int i;
779 for(i=0; i<l ;i++) {
780 if(buff[i+1]==0xF3 && (buff[i]==0x00 || buff[i]==0x0A)) {
781 memcpy(&boxID,&buff[i+2],sizeof(boxID));
782 boxidOK=1;
783 break;
784 }
785 }
786 }
787
788 if(!boxidOK) {
789 cs_log ("[videoguard2-reader] no boxID available");
790 return ERROR;
791 }
792 }
793
794 unsigned char ins4C[5] = { 0xD0,0x4C,0x00,0x00,0x09 };
795 unsigned char payload4C[9] = { 0,0,0,0, 3,0,0,0,4 };
796 memcpy(payload4C,boxID,4);
797 if(!write_cmd(ins4C,payload4C) || !status_ok(cta_res+l)) {
798 cs_log("[videoguard2-reader] sending boxid failed");
799 return ERROR;
800 }
801
802 //short int SWIRDstatus = cta_res[1];
803 unsigned char ins58[5] = { 0xD0,0x58,0x00,0x00,0x00 };
804 l=do_cmd(ins58, NULL, buff);
805 if(l<0) {
806 cs_log("[videoguard2-reader] cmd ins58 failed");
807 return ERROR;
808 }
809 memset(reader[ridx].hexserial, 0, 8);
810 memcpy(reader[ridx].hexserial+2, cta_res+3, 4);
811 reader[ridx].caid[0] = cta_res[24]*0x100+cta_res[25];
812
813 /* we have one provider, 0x0000 */
814 reader[ridx].nprov = 1;
815 memset(reader[ridx].prid, 0x00, sizeof(reader[ridx].prid));
816
817 /*
818 cs_log ("[videoguard2-reader] INS58 : Fuse byte=0x%02X, IRDStatus=0x%02X", cta_res[2],SWIRDstatus);
819 if (SWIRDstatus==4) {
820 // If swMarriage=4, not married then exchange for BC Key
821 cs_log ("[videoguard2-reader] Card not married, exchange for BC Keys");
822 */
823
824 unsigned char seed1[] = {
825 0xb9, 0xd5, 0xef, 0xd5, 0xf5, 0xd5, 0xfb, 0xd5, 0x31, 0xd6, 0x43, 0xd6, 0x55, 0xd6, 0x61, 0xd6,
826 0x85, 0xd6, 0x9d, 0xd6, 0xaf, 0xd6, 0xc7, 0xd6, 0xd9, 0xd6, 0x09, 0xd7, 0x15, 0xd7, 0x21, 0xd7,
827 0x27, 0xd7, 0x3f, 0xd7, 0x45, 0xd7, 0xb1, 0xd7, 0xbd, 0xd7, 0xdb, 0xd7, 0x11, 0xd8, 0x23, 0xd8,
828 0x29, 0xd8, 0x2f, 0xd8, 0x4d, 0xd8, 0x8f, 0xd8, 0xa1, 0xd8, 0xad, 0xd8, 0xbf, 0xd8, 0xd7, 0xd8
829 };
830 unsigned char seed2[] = {
831 0x01, 0x00, 0xcf, 0x13, 0xe0, 0x60, 0x54, 0xac, 0xab, 0x99, 0xe6, 0x0c, 0x9f, 0x5b, 0x91, 0xb9,
832 0x72, 0x72, 0x4d, 0x5b, 0x5f, 0xd3, 0xb7, 0x5b, 0x01, 0x4d, 0xef, 0x9e, 0x6b, 0x8a, 0xb9, 0xd1,
833 0xc9, 0x9f, 0xa1, 0x2a, 0x8d, 0x86, 0xb6, 0xd6, 0x39, 0xb4, 0x64, 0x65, 0x13, 0x77, 0xa1, 0x0a,
834 0x0c, 0xcf, 0xb4, 0x2b, 0x3a, 0x2f, 0xd2, 0x09, 0x92, 0x15, 0x40, 0x47, 0x66, 0x5c, 0xda, 0xc9
835 };
836 cCamCryptVG2_SetSeed(seed1,seed2);
837
838 unsigned char insB4[5] = { 0xD0,0xB4,0x00,0x00,0x40 };
839 unsigned char tbuff[64];
840 cCamCryptVG2_GetCamKey(tbuff);
841 l=do_cmd(insB4, tbuff, NULL);
842 if(l<0 || !status_ok(cta_res)) {
843 cs_log ("[videoguard2-reader] cmd D0B4 failed (%02X%02X)", cta_res[0], cta_res[1]);
844 return ERROR;
845 }
846
847 unsigned char insBC[5] = { 0xD0,0xBC,0x00,0x00,0x00 };
848 l=do_cmd(insBC, NULL, NULL);
849 if(l<0) {
850 cs_log("[videoguard2-reader] cmd D0BC failed");
851 return ERROR;
852 }
853
854 unsigned char insBE[5] = { 0xD3,0xBE,0x00,0x00,0x00 };
855 l=do_cmd(insBE, NULL, NULL);
856 if(l<0) {
857 cs_log("[videoguard2-reader] cmd D3BE failed");
858 return ERROR;
859 }
860
861 unsigned char ins58a[5] = { 0xD1,0x58,0x00,0x00,0x00 };
862 l=do_cmd(ins58a, NULL, NULL);
863 if(l<0) {
864 cs_log("[videoguard2-reader] cmd D158 failed");
865 return ERROR;
866 }
867
868 unsigned char ins4Ca[5] = { 0xD1,0x4C,0x00,0x00,0x00 };
869 l=do_cmd(ins4Ca,payload4C, NULL);
870 if(l<0 || !status_ok(cta_res)) {
871 cs_log("[videoguard2-reader] cmd D14Ca failed");
872 return ERROR;
873 }
874
875 cs_ri_log("[videoguard2-reader] type: VideoGuard, caid: %04X, serial: %02X%02X%02X%02X, BoxID: %02X%02X%02X%02X",
876 reader[ridx].caid[0],
877 reader[ridx].hexserial[2],reader[ridx].hexserial[3],reader[ridx].hexserial[4],reader[ridx].hexserial[5],
878 boxID[0],boxID[1],boxID[2],boxID[3]);
879
880 ///read_tiers();
881
882 cs_log("[videoguard2-reader] ready for requests");
883
884 return OK;
885}
886
887int videoguard_do_ecm(ECM_REQUEST *er)
888{
889 static unsigned char ins40[5] = { 0xD1,0x40,0x00,0x80,0xFF };
890 static const unsigned char ins54[5] = { 0xD3,0x54,0x00,0x00,0x00};
891 int posECMpart2=er->ecm[6]+7;
892 int lenECMpart2=er->ecm[posECMpart2]+1;
893 unsigned char tbuff[264];
894 tbuff[0]=0;
895 memcpy(&tbuff[1],&(er->ecm[posECMpart2+1]),lenECMpart2-1);
896 ins40[4]=lenECMpart2;
897 int l;
898 l = do_cmd(ins40,tbuff,NULL);
899 if(l>0 && status_ok(cta_res)) {
900 l = do_cmd(ins54,NULL,NULL);
901 if(l>0 && status_ok(cta_res+l)) {
902 if (!cw_is_valid(CW1)) //sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
903 return ERROR;
904 if(er->ecm[0]&1) {
905 memcpy(er->cw+8,CW1,8);
906 memcpy(er->cw+0,CW2,8);
907 }
908 else {
909 memcpy(er->cw+0,CW1,8);
910 memcpy(er->cw+8,CW2,8);
911 }
912
913 //test for postprocessing marker
914 int posB0 = -1;
915 int i;
916 for (i = 6; i < posECMpart2; i++)
917 {
918 if (er->ecm[i] == 0xB0 && er->ecm[i+1] == 0x01 ) {
919 posB0 = i;
920 break;
921 }
922 }
923 if (posB0 != -1) {
924 postprocess_cw(er->cw+0, er->ecm[posB0+2]);
925 postprocess_cw(er->cw+8, er->ecm[posB0+2]);
926 }
927 return OK;
928 }
929 }
930 return ERROR;
931}
932
933static int num_addr(const unsigned char *data)
934{
935 return ((data[3]&0x30)>>4)+1;
936}
937
938static int addr_mode(const unsigned char *data)
939{
940 switch(data[3]&0xC0) {
941 case 0x40: return 3;
942 case 0x80: return 2;
943 default: return 0;
944 }
945}
946
947static const unsigned char * payload_addr(const unsigned char *data, const unsigned char *a)
948{
949 int s;
950 int l;
951 const unsigned char *ptr = NULL;
952
953 switch(addr_mode(data)) {
954 case 2: s=3; break;
955 case 3: case 0: s=4; break;
956 default: return NULL;
957 }
958
959 int position=-1;
960 for(l=0;l<num_addr(data);l++) {
961 if(!memcmp(&data[l*4+4],a+2,s)) {
962 position=l;
963 break;
964 }
965 }
966
967 /* skip EMM-G but not EMM from cccam */
968 if (position == -1 && data[1] != 0x00) return NULL;
969
970 int num_ua = (position == -1) ? 0 : num_addr(data);
971
972 /* skip header and the list of addresses */
973 ptr = data+4+4*num_ua;
974
975 if (*ptr != 0x02) // some clients omit 00 00 separator */
976 {
977 ptr += 2; // skip 00 00 separator
978 if (*ptr == 0x00) ptr++; // skip optional 00
979 ptr++; // skip the 1st bitmap len
980 }
981
982 /* check */
983 if (*ptr != 0x02) return NULL;
984
985 /* skip the 1st timestamp 02 00 or 02 06 xx aabbccdd yy */
986 ptr += 2 + ptr[1];
987
988 for(l=0;l<position;l++) {
989
990 /* skip the payload of the previous SA */
991 ptr += 1 + ptr [0];
992
993 /* skip optional 00 */
994 if (*ptr == 0x00) ptr++;
995
996 /* skip the bitmap len */
997 ptr++;
998
999 /* check */
1000 if (*ptr != 0x02) return NULL;
1001
1002 /* skip the timestamp 02 00 or 02 06 xx aabbccdd yy */
1003 ptr += 2 + ptr[1];
1004 }
1005
1006 return ptr;
1007}
1008
1009int videoguard_do_emm(EMM_PACKET *ep)
1010{
1011 unsigned char ins42[5] = { 0xD1,0x42,0x00,0x00,0xFF };
1012 int rc=ERROR;
1013
1014 const unsigned char *payload = payload_addr(ep->emm, reader[ridx].hexserial);
1015 while (payload) {
1016 ins42[4]=*payload;
1017 int l = do_cmd(ins42,payload+1,NULL);
1018 if(l>0 && status_ok(cta_res)) {
1019 rc=OK;
1020 }
1021
1022 cs_log("[videoguard2-reader] EMM request return code : %02X%02X", cta_res[0], cta_res[1]);
1023//cs_dump(ep->emm, 64, "EMM:");
1024 if (status_ok (cta_res) && (cta_res[1] & 0x01)) {
1025 read_tiers();
1026 }
1027
1028 if (num_addr(ep->emm) == 1 && (int)(&payload[1] - &ep->emm[0]) + *payload + 1 < ep->l) {
1029 payload += *payload + 1;
1030 if (*payload == 0x00) ++payload;
1031 ++payload;
1032 if (*payload != 0x02) break;
1033 payload += 2 + payload[1];
1034 }
1035 else
1036 payload = 0;
1037
1038 }
1039
1040 return(rc);
1041}
1042
1043int videoguard_card_info(void)
1044{
1045 /* info is displayed in init, or when processing info */
1046 cs_log("[videoguard2-reader] card detected");
1047 cs_log("[videoguard2-reader] type: VideoGuard" );
1048 read_tiers ();
1049 return OK;
1050}
Note: See TracBrowser for help on using the repository browser.