source: trunk/reader-irdeto.c@ 8431

Last change on this file since 8431 was 8431, checked in by gf, 9 years ago

irdeto: Fix UNIQUE EMM filter for EMMs addressed at provider.

Patch by malakudi posted in ticket #3198.

  • Property svn:eol-style set to LF
File size: 32.5 KB
Line 
1#include "globals.h"
2#ifdef READER_IRDETO
3#include "oscam-time.h"
4#include "reader-common.h"
5
6static const uchar CryptTable[256] =
7{
8 0xDA, 0x26, 0xE8, 0x72, 0x11, 0x52, 0x3E, 0x46,
9 0x32, 0xFF, 0x8C, 0x1E, 0xA7, 0xBE, 0x2C, 0x29,
10 0x5F, 0x86, 0x7E, 0x75, 0x0A, 0x08, 0xA5, 0x21,
11 0x61, 0xFB, 0x7A, 0x58, 0x60, 0xF7, 0x81, 0x4F,
12 0xE4, 0xFC, 0xDF, 0xB1, 0xBB, 0x6A, 0x02, 0xB3,
13 0x0B, 0x6E, 0x5D, 0x5C, 0xD5, 0xCF, 0xCA, 0x2A,
14 0x14, 0xB7, 0x90, 0xF3, 0xD9, 0x37, 0x3A, 0x59,
15 0x44, 0x69, 0xC9, 0x78, 0x30, 0x16, 0x39, 0x9A,
16 0x0D, 0x05, 0x1F, 0x8B, 0x5E, 0xEE, 0x1B, 0xC4,
17 0x76, 0x43, 0xBD, 0xEB, 0x42, 0xEF, 0xF9, 0xD0,
18 0x4D, 0xE3, 0xF4, 0x57, 0x56, 0xA3, 0x0F, 0xA6,
19 0x50, 0xFD, 0xDE, 0xD2, 0x80, 0x4C, 0xD3, 0xCB,
20 0xF8, 0x49, 0x8F, 0x22, 0x71, 0x84, 0x33, 0xE0,
21 0x47, 0xC2, 0x93, 0xBC, 0x7C, 0x3B, 0x9C, 0x7D,
22 0xEC, 0xC3, 0xF1, 0x89, 0xCE, 0x98, 0xA2, 0xE1,
23 0xC1, 0xF2, 0x27, 0x12, 0x01, 0xEA, 0xE5, 0x9B,
24 0x25, 0x87, 0x96, 0x7B, 0x34, 0x45, 0xAD, 0xD1,
25 0xB5, 0xDB, 0x83, 0x55, 0xB0, 0x9E, 0x19, 0xD7,
26 0x17, 0xC6, 0x35, 0xD8, 0xF0, 0xAE, 0xD4, 0x2B,
27 0x1D, 0xA0, 0x99, 0x8A, 0x15, 0x00, 0xAF, 0x2D,
28 0x09, 0xA8, 0xF5, 0x6C, 0xA1, 0x63, 0x67, 0x51,
29 0x3C, 0xB2, 0xC0, 0xED, 0x94, 0x03, 0x6F, 0xBA,
30 0x3F, 0x4E, 0x62, 0x92, 0x85, 0xDD, 0xAB, 0xFE,
31 0x10, 0x2E, 0x68, 0x65, 0xE7, 0x04, 0xF6, 0x0C,
32 0x20, 0x1C, 0xA9, 0x53, 0x40, 0x77, 0x2F, 0xA4,
33 0xFA, 0x6D, 0x73, 0x28, 0xE2, 0xCD, 0x79, 0xC8,
34 0x97, 0x66, 0x8E, 0x82, 0x74, 0x06, 0xC7, 0x88,
35 0x1A, 0x4A, 0x6B, 0xCC, 0x41, 0xE9, 0x9D, 0xB8,
36 0x23, 0x9F, 0x3D, 0xBF, 0x8D, 0x95, 0xC5, 0x13,
37 0xB9, 0x24, 0x5A, 0xDC, 0x64, 0x18, 0x38, 0x91,
38 0x7F, 0x5B, 0x70, 0x54, 0x07, 0xB6, 0x4B, 0x0E,
39 0x36, 0xAC, 0x31, 0xE6, 0xD6, 0x48, 0xAA, 0xB4
40};
41
42static const uchar
43 sc_GetCountryCode[] = { 0x02, 0x02, 0x03, 0x00, 0x00 };
44
45static const uchar
46 sc_GetCountryCode2[]= { 0x02, 0x0B, 0x00, 0x00, 0x00 },
47 sc_GetCamKey384CZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
48 0x18, 0xD7, 0x55, 0x14, 0xC0, 0x83, 0xF1, 0x38,
49 0x39, 0x6F, 0xF2, 0xEC, 0x4F, 0xE3, 0xF1, 0x85,
50 0x01, 0x46, 0x06, 0xCE, 0x7D, 0x08, 0x2C, 0x74,
51 0x46, 0x8F, 0x72, 0xC4, 0xEA, 0xD7, 0x9C, 0xE0,
52 0xE1, 0xFF, 0x58, 0xE7, 0x70, 0x0C, 0x92, 0x45,
53 0x26, 0x18, 0x4F, 0xA0, 0xE2, 0xF5, 0x9E, 0x46,
54 0x6F, 0xAE, 0x95, 0x35, 0xB0, 0x49, 0xB2, 0x0E,
55 0xA4, 0x1F, 0x8E, 0x47, 0xD0, 0x24, 0x11, 0xD0 },
56 sc_GetCamKey384DZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
57 0x27, 0xF2, 0xD6, 0xCD, 0xE6, 0x88, 0x62, 0x46,
58 0x81, 0xB0, 0xF5, 0x3E, 0x6F, 0x13, 0x4D, 0xCC,
59 0xFE, 0xD0, 0x67, 0xB1, 0x93, 0xDD, 0xF4, 0xDE,
60 0xEF, 0xF5, 0x3B, 0x04, 0x1D, 0xE5, 0xC3, 0xB2,
61 0x54, 0x38, 0x57, 0x7E, 0xC8, 0x39, 0x07, 0x2E,
62 0xD2, 0xF4, 0x05, 0xAA, 0x15, 0xB5, 0x55, 0x24,
63 0x90, 0xBB, 0x9B, 0x00, 0x96, 0xF0, 0xCB, 0xF1,
64 0x8A, 0x08, 0x7F, 0x0B, 0xB8, 0x79, 0xC3, 0x5D },
65 sc_GetCamKey384FZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
66 0x62, 0xFE, 0xD8, 0x4F, 0x44, 0x86, 0x2C, 0x21,
67 0x50, 0x9A, 0xBE, 0x27, 0x15, 0x9E, 0xC4, 0x48,
68 0xF3, 0x73, 0x5C, 0xBD, 0x08, 0x64, 0x6D, 0x13,
69 0x64, 0x90, 0x14, 0xDB, 0xFF, 0xC3, 0xFE, 0x03,
70 0x97, 0xFA, 0x75, 0x08, 0x12, 0xF9, 0x8F, 0x84,
71 0x83, 0x17, 0xAA, 0x6F, 0xEF, 0x2C, 0x10, 0x1B,
72 0xBF, 0x31, 0x41, 0xC3, 0x54, 0x2F, 0x65, 0x50,
73 0x95, 0xA9, 0x64, 0x22, 0x5E, 0xA4, 0xAF, 0xA9 };
74
75/* some variables for acs57 (Dahlia for ITA dvb-t) */
76#define ACS57EMM 0xD1
77#define ACS57ECM 0xD5
78#define ACS57GET 0xD2
79/* end define */
80
81typedef struct chid_base_date {
82 uint16_t caid;
83 uint16_t acs;
84 char c_code[4];
85 uint32_t base;
86} CHID_BASE_DATE;
87
88static void XRotateLeft8Byte(uchar *buf)
89{
90 int32_t k;
91 uchar t1=buf[7];
92 uchar t2=0;
93 for(k=0; k<=7; k++)
94 {
95 t2=t1;
96 t1=buf[k];
97 buf[k]=(buf[k]<<1)|(t2>>7);
98 }
99}
100
101static void ReverseSessionKeyCrypt(const uchar *camkey, uchar *key)
102{
103 uchar localkey[8], tmp1, tmp2;
104 int32_t idx1,idx2;
105
106 memcpy(localkey, camkey, 8) ;
107 for(idx1=0; idx1<8; idx1++)
108 {
109 for(idx2=0; idx2<8; idx2++)
110 {
111 tmp1 = CryptTable[key[7] ^ localkey[idx2] ^ idx1] ;
112 tmp2 = key[0] ;
113 key[0] = key[1] ;
114 key[1] = key[2] ;
115 key[2] = key[3] ;
116 key[3] = key[4] ;
117 key[4] = key[5] ;
118 key[5] = key[6] ^ tmp1 ;
119 key[6] = key[7] ;
120 key[7] = tmp1 ^ tmp2 ;
121 }
122 XRotateLeft8Byte(localkey);
123 }
124}
125
126static unsigned char XorSum(const unsigned char *mem, int len) {
127 unsigned char cs=0;
128 while(len>0) { cs ^= *mem++; len--; }
129 return cs;
130}
131
132static time_t chid_date(struct s_reader * reader, uint32_t date, char *buf, int32_t l)
133{
134
135 // Irdeto date starts 01.08.1997 which is
136 // 870393600 seconds in unix calendar time
137 //
138 // The above might not be true for all Irdeto card
139 // we need to find a way to identify cards to set the base date
140 // like we did for NDS
141 //
142 // this is the known default value.
143 uint32_t date_base=870393600L; // this is actually 01.08.1997, 00:00
144 // CAID, ACS, Country, base date D . M. Y, h : m
145 CHID_BASE_DATE table[] = { {0x0604, 0x1541, "GRC", 977817600L}, // 26.12.2000, 00:00
146 {0x0604, 0x1542, "GRC", 977817600L}, // 26.12.2000, 00:00
147 {0x0604, 0x1543, "GRC", 977817600L}, // 26.12.2000, 00:00
148 {0x0604, 0x1544, "GRC", 977817600L}, // 26.12.2000, 17:00
149 {0x0604, 0x0606, "NLD", 1066089600L}, // 14.10.2003, 00:00
150 {0x0628, 0x0606, "MCR", 1159574400L}, // 29.09.2006, 00:00
151 {0x0604, 0x0608, "EGY", 999993600L}, // 08.09.2001, 17:00
152 {0x0604, 0x0606, "EGY", 1003276800L}, // 16.10.2001, 17:00
153 {0x0627, 0x0608, "EGY", 946598400L}, // 30.12.1999, 16:00
154 {0x0662, 0x0608, "ITA", 944110500L}, // 01.12.1999, 23.55
155 {0x0616, 0x0608, "ITA", 944110500L}, // 01.12.1999, 23.55 //nitegate
156 {0x0664, 0x0608, "TUR", 946598400L}, // 31.12.1999, 00:00
157 {0x0624, 0x0006, "CZE", 946598400L}, // 30.12.1999, 16:00 //skyklink irdeto
158 {0x0624, 0x0006, "SVK", 946598400L}, // 30.12.1999, 16:00 //skyklink irdeto
159 {0x0666, 0x0006, "SVK", 946598400L}, // 30.12.1999, 16:00 //cslink irdeto
160 {0x0666, 0x0006, "CZE", 946598400L}, // 30.12.1999, 16:00 //cslink irdeto
161 {0x0648, 0x0608, "AUT", 946598400L}, // 31.12.1999, 00:00 //orf ice irdeto
162 {0x0648, 0x0005, "AUT", 946598400L}, // 31.12.1999, 00:00 //orf ice irdeto
163 {0x0604, 0x0605, "GRC", 1011052800L}, // 15.01.2002, 00:00 //nova irdeto
164 {0x0604, 0x0606, "GRC", 1011052800L}, // 15.01.2002, 00:00 //nova irdeto
165 {0x0604, 0x0607, "GRC", 1011052800L}, // 15.01.2002, 00:00 //nova irdeto
166 {0x0604, 0x0608, "GRC", 1011052800L}, // 15.01.2002, 00:00 //nova irdeto
167 {0x0604, 0x0005, "GRC", 1011052800L}, // 15.01.2002, 00:00 //mova irdeto
168 {0x0604, 0x0608, "NLD", 1066089600L}, // 14.10.2003, 00:00 //Ziggo irdeto caid: 0604, acs: 6.08
169 {0x0604, 0x0605, "NLD", 1066089600L}, // 14.10.2003, 00:00 //Ziggo irdeto caid: 0604, acs: 6.05
170 {0x0604, 0x0005, "NLD", 1066089600L}, // 14.10.2003, 00:00 //Ziggo irdeto caid: 0604, acs: 0.05
171 {0x0602, 0x0606, "NLD", 946598400L}, // 31.12.1999, 08:00 //Ziggo irdeto caid: 0602, acs: 6.06
172 {0x0602, 0x0505, "NLD", 946598400L}, // 31.12.1999, 00:00 //Ziggo irdeto caid: 0602, acs: 5.05
173 {0x0606, 0x0605, "NLD", 946598400L}, // 31.12.1999, 00:00 //Caiway irdeto card caid: 0606, acs: 6.05
174 {0x0606, 0x0606, "NLD", 946598400L}, // 31.12.1999, 00:00 //Caiway irdeto card caid: 0606, acs: 6.06
175 {0x0652, 0x0608, "MCR", 1206662400L}, // 28.03.2008, 00:00 //Raduga caid:0652, acs: 6.08
176 // {0x1702, 0x0384, "AUT", XXXXXXXXXL}, // -> we need the base date for this
177 // {0x1702, 0x0384, "GER", 888883200L}, // 02.03.1998, 16:00 -> this fixes some card but break others (S02).
178 {0x0, 0x0, "", 0L}
179 };
180
181 // now check for specific providers base date
182 int32_t i=0;
183 while(table[i].caid) {
184 if(reader->caid==table[i].caid && reader->acs==table[i].acs && !memcmp(reader->country_code,table[i].c_code,3) ) {
185 date_base = table[i].base;
186 break;
187 }
188 i++;
189 }
190
191 time_t ut=date_base+date*(24*3600);
192 if (buf) {
193 struct tm t;
194 cs_gmtime_r(&ut, &t);
195 snprintf(buf, l, "%04d/%02d/%02d", t.tm_year+1900, t.tm_mon+1, t.tm_mday);
196 }
197 return(ut);
198}
199
200static int32_t irdeto_do_cmd(struct s_reader * reader, uchar *buf, uint16_t good, uchar * cta_res, uint16_t * p_cta_lr)
201{
202 int32_t rc;
203 if( (rc = reader_cmd2icc(reader, buf, buf[4] + 5, cta_res, p_cta_lr)) )
204 return(rc); // result may be 0 (success) or negative
205 if (*p_cta_lr < 2)
206 return(0x7F7F); // this should never happen
207 return(good != b2i(2, cta_res+*p_cta_lr-2));
208}
209
210#define reader_chk_cmd(cmd, l) \
211{ \
212 if (reader_cmd2icc(reader, cmd, sizeof(cmd), cta_res, &cta_lr)) return ERROR; \
213 if (l && (cta_lr!=l)) return ERROR; }
214
215static int32_t irdeto_card_init_provider(struct s_reader * reader)
216{
217 def_resp;
218 int32_t i, p;
219 uchar buf[256] = {0};
220
221 uchar sc_GetProvider[] = { 0x02, 0x03, 0x03, 0x00, 0x00 };
222 uchar sc_Acs57Prov[] = { 0xD2, 0x06, 0x03, 0x00, 0x01, 0x3C };
223 uchar sc_Acs57_Cmd[] = { ACS57GET, 0xFE, 0x00, 0x00, 0x00 };
224 /*
225 * Provider
226 */
227 memset(reader->prid, 0xff, sizeof(reader->prid));
228 for (buf[0] = i = p = 0; i<reader->nprov; i++)
229 {
230 int32_t acspadd = 0;
231 if(reader->acs57==1){
232 acspadd=8;
233 sc_Acs57Prov[3]=i;
234 irdeto_do_cmd(reader, sc_Acs57Prov, 0x9021, cta_res, &cta_lr);
235 int32_t acslength = cta_res[cta_lr-1];
236 sc_Acs57_Cmd[4]=acslength;
237 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
238 sc_Acs57Prov[5]++;
239 sc_Acs57_Cmd[3]++;
240 } else {
241 sc_GetProvider[3] = i;
242 reader_chk_cmd(sc_GetProvider, 0);
243 }
244 //if ((cta_lr==26) && (cta_res[0]!=0xf))
245 if (((cta_lr == 26) && ((!(i&1)) || (cta_res[0] != 0xf))) || (reader->acs57==1))
246 {
247 reader->prid[i][4] = p++;
248
249 // maps the provider id for Betacrypt from FFFFFF to 000000,
250 // fixes problems with cascading CCcam and OSCam
251 if ((reader->caid >= 0x1700) && (reader->caid <= 0x1799))
252 memset(&reader->prid[i][0], 0, 4);
253 else
254 memcpy(&reader->prid[i][0], cta_res+acspadd, 4);
255
256 if (!memcmp(cta_res+acspadd+1, &reader->hexserial, 3))
257 reader->prid[i][3] = 0xFF;
258
259 snprintf((char *) buf+strlen((char *)buf), sizeof(buf)-strlen((char *)buf), ",%06x", b2i(3, &reader->prid[i][1]));
260 }
261 else
262 reader->prid[i][0] = 0xf;
263 }
264 if (p)
265 rdr_log(reader, "active providers: %d (%s)", p, buf + 1);
266
267 return OK;
268}
269
270
271
272static int32_t irdeto_card_init(struct s_reader * reader, ATR *newatr)
273{
274 def_resp;
275 get_atr;
276 int32_t camkey = 0;
277 uchar buf[256] = {0};
278 uchar sc_GetCamKey383C[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
279 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
280 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
281 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
282 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
283 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
284 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
285 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
286 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
287
288 uchar sc_GetASCIISerial[] = { 0x02, 0x00, 0x03, 0x00, 0x00 },
289 sc_GetHEXSerial[] = { 0x02, 0x01, 0x00, 0x00, 0x00 },
290 sc_GetSCDetails[] = { 0x02, 0x1E, 0x00, 0x00, 0x00 },
291 sc_GetCardFile[] = { 0x02, 0x0E, 0x02, 0x00, 0x00 };
292
293
294 uchar sc_Acs57CamKey[70] = { 0xD2, 0x12, 0x03, 0x00, 0x41},
295 sc_Acs57Country[] = { 0xD2, 0x04, 0x00, 0x00, 0x01, 0x3E },
296 sc_Acs57Ascii[] = { 0xD2, 0x00, 0x03, 0x00, 0x01, 0x3F },
297 sc_Acs57Hex[] = { 0xD2, 0x02, 0x03, 0x00, 0x01, 0x3E },
298 sc_Acs57CFile[] = { 0xD2, 0x1C, 0x02, 0x00, 0x01, 0x30 },
299 sc_Acs57_Cmd[] = { ACS57GET, 0xFE, 0x00, 0x00, 0x00 };
300
301 int32_t acspadd = 0;
302 if (!memcmp(atr+4, "IRDETO", 6))
303 reader->acs57=0;
304 else {
305 if ((!memcmp(atr+5, "IRDETO", 6)) || ((atr[6]==0xC4 && atr[9]==0x8F && atr[10]==0xF1) && reader->force_irdeto)) {
306 reader->acs57=1;
307 acspadd=8;
308 rdr_log(reader, "Hist. Bytes: %s",atr+5);
309 } else {
310 return ERROR;
311 }
312 }
313 rdr_log(reader, "detect irdeto card");
314 if(check_filled(reader->rsa_mod, 64) > 0 && (!reader->force_irdeto || reader->acs57)) // we use rsa from config as camkey
315 {
316 char tmp_dbg[65];
317 rdr_debug_mask(reader, D_READER, "using camkey data from config");
318 rdr_debug_mask(reader, D_READER, " camkey: %s", cs_hexdump(0, reader->boxkey, sizeof(reader->boxkey), tmp_dbg, sizeof(tmp_dbg)));
319 if (reader->acs57==1) {
320 memcpy(&sc_Acs57CamKey[5], reader->rsa_mod, 0x40);
321 rdr_debug_mask(reader, D_READER, "camkey-data: %s", cs_hexdump(0, &sc_Acs57CamKey[5], 32, tmp_dbg, sizeof(tmp_dbg)));
322 rdr_debug_mask(reader, D_READER, "camkey-data: %s", cs_hexdump(0, &sc_Acs57CamKey[37], 32, tmp_dbg, sizeof(tmp_dbg)));
323 } else {
324 memcpy(&sc_GetCamKey383C[5], reader->rsa_mod, 0x40);
325 rdr_debug_mask(reader, D_READER, "camkey-data: %s", cs_hexdump(0, &sc_GetCamKey383C[5], 32, tmp_dbg, sizeof(tmp_dbg)));
326 rdr_debug_mask(reader, D_READER, "camkey-data: %s", cs_hexdump(0, &sc_GetCamKey383C[37], 32, tmp_dbg, sizeof(tmp_dbg)));
327 }
328 } else {
329 if(reader->acs57==1) {
330 rdr_log(reader, "WARNING: ACS57 card can require the CamKey from config");
331 } else {
332 memcpy(reader->boxkey, "\x11\x22\x33\x44\x55\x66\x77\x88", 8);
333 }
334 }
335 /*
336 * Get Irdeto Smartcard Details - version - patch level etc
337 */
338 if(reader->acs57==0) {
339 if(!irdeto_do_cmd(reader,sc_GetSCDetails,0,cta_res, &cta_lr))
340 rdr_log(reader,"Irdeto SC %0x version %0x revision %0x, patch level %0x",cta_res[0+acspadd],
341 cta_res[1+acspadd],cta_res[2+acspadd],cta_res[5+acspadd]);
342 }
343 /*
344 * CountryCode
345 */
346 if(reader->acs57==1) {
347 irdeto_do_cmd(reader, sc_Acs57Country, 0x9019, cta_res, &cta_lr);
348 int32_t acslength=cta_res[cta_lr-1];
349 sc_Acs57_Cmd[4]=acslength;
350 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
351 } else {
352 reader_chk_cmd(sc_GetCountryCode, 18);
353 }
354 reader->acs = (cta_res[0+acspadd] << 8) | cta_res[1+acspadd];
355 reader->caid = (cta_res[5+acspadd] << 8) | cta_res[6+acspadd];
356 memcpy(reader->country_code,cta_res + 13 + acspadd, 3);
357 rdr_log(reader, "caid: %04X, acs: %x.%02x, country code: %c%c%c",
358 reader->caid, cta_res[0+acspadd], cta_res[1+acspadd], cta_res[13+acspadd], cta_res[14+acspadd], cta_res[15+acspadd]);
359
360 /*
361 * Ascii/Hex-Serial
362 */
363 if(reader->acs57==1) {
364 irdeto_do_cmd(reader, sc_Acs57Ascii, 0x901D, cta_res, &cta_lr);
365 int32_t acslength=cta_res[cta_lr-1];
366 sc_Acs57_Cmd[4]=acslength;
367 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
368 } else {
369 reader_chk_cmd(sc_GetASCIISerial, 22);
370 }
371 memcpy(buf, cta_res+acspadd, 10);
372 buf[10] = 0;
373 if(reader->acs57==1) {
374 irdeto_do_cmd(reader, sc_Acs57Hex, 0x903E, cta_res, &cta_lr);
375 int32_t acslength=cta_res[cta_lr-1];
376 sc_Acs57_Cmd[4]=acslength;
377 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
378 } else {
379 reader_chk_cmd(sc_GetHEXSerial, 18);
380 }
381 reader->nprov = cta_res[10+acspadd];
382 memcpy(reader->hexserial, cta_res+12+acspadd, 4);
383
384 rdr_log_sensitive(reader, "providers: %d, ascii serial: {%s}, hex serial: {%02X%02X%02X}, hex base: {%02X}",
385 reader->nprov, buf, reader->hexserial[0], reader->hexserial[1], reader->hexserial[2], reader->hexserial[3]);
386
387 /*
388 * CardFile
389 */
390 if(reader->acs57==1) {
391 irdeto_do_cmd(reader, sc_Acs57CFile, 0x9049, cta_res, &cta_lr);
392 int32_t acslength=cta_res[cta_lr-1];
393 sc_Acs57_Cmd[4]=acslength;
394 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
395 sc_Acs57CFile[2]=0x03;sc_Acs57CFile[5]++;
396 irdeto_do_cmd(reader, sc_Acs57CFile, 0x9049, cta_res, &cta_lr);
397 acslength=cta_res[cta_lr-1];
398 sc_Acs57_Cmd[4]=acslength;
399 sc_Acs57_Cmd[2]=0x03;
400 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
401 sc_Acs57_Cmd[2]=0x00;
402 } else {
403 for (sc_GetCardFile[2] = 2; sc_GetCardFile[2] < 4; sc_GetCardFile[2]++)
404 reader_chk_cmd(sc_GetCardFile, 0);
405 }
406
407 /*
408 * CamKey
409 */
410 if (((atr[14] == 0x03) && (atr[15] == 0x84) && (atr[16] == 0x55)) || (((atr[14]==0x53) && (atr[15]==0x20) && (atr[16]==0x56))))
411 {
412 switch (reader->caid)
413 {
414 case 0x1702: camkey = 1; break;
415 case 0x1722: camkey = 2; break;
416 case 0x1762: camkey = 3; break;
417// case 0x0624: camkey = 4; break; //ice 0D96/0624 has short ATR
418 default : camkey = 5; break;
419 }
420 }
421
422 if ((reader->caid == 0x0648) || (reader->caid == 0x0666) || (reader->caid == 0x0624)) { // acs 6.08 and ice 0D96/0624
423 camkey = 4;
424 sc_Acs57CamKey[2] = 0;
425 }
426
427 rdr_debug_mask(reader, D_READER, "set camkey for type=%d", camkey);
428
429 switch (camkey)
430 {
431 case 1:
432 reader_chk_cmd(sc_GetCamKey384CZ, 10);
433 break;
434 case 2:
435 reader_chk_cmd(sc_GetCamKey384DZ, 10);
436 break;
437 case 3:
438 reader_chk_cmd(sc_GetCamKey384FZ, 10);
439 break;
440 case 4:
441 {
442 int32_t i,crc=61;
443 crc^=0x01, crc^=0x02, crc^=0x09;
444 crc^=sc_Acs57CamKey[2], crc^=sc_Acs57CamKey[3], crc^=(sc_Acs57CamKey[4]+1);
445 for(i=5;i<(int)sizeof(sc_Acs57CamKey)-1;i++)
446 crc^=sc_Acs57CamKey[i];
447 sc_Acs57CamKey[69]=crc;
448 if ((reader->caid == 0x0648) || (reader->caid == 0x0666) || (reader->caid == 0x0624)) {
449 sc_Acs57CamKey[69] = XorSum(sc_Acs57CamKey, 69) ^ 0x3f ^ (sc_Acs57CamKey[0]&0xf0) ^ 0x1b;
450 if (irdeto_do_cmd(reader, sc_Acs57CamKey, 0x9011, cta_res, &cta_lr)) {
451 rdr_log(reader, "You have a bad Cam Key set");
452 return ERROR;
453 }
454 } else
455 irdeto_do_cmd(reader, sc_Acs57CamKey, 0x9012, cta_res, &cta_lr);
456 int32_t acslength=cta_res[cta_lr-1];
457 sc_Acs57_Cmd[4]=acslength;
458 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
459 }
460 break;
461 default:
462 if(reader->acs57==1) {
463 int32_t i, crc=0x76;
464 for(i=6;i<(int)sizeof(sc_Acs57CamKey)-1;i++)
465 crc^=sc_Acs57CamKey[i];
466 sc_Acs57CamKey[69]=crc;
467 irdeto_do_cmd(reader, sc_Acs57CamKey, 0x9012, cta_res, &cta_lr);
468 int32_t acslength=cta_res[cta_lr-1];
469 sc_Acs57_Cmd[4]=acslength;
470 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
471 } else {
472 reader_chk_cmd(sc_GetCamKey383C, 0);
473 }
474 break;
475 }
476 if (reader->cardmhz != 600)
477 rdr_log(reader, "WARNING: For Irdeto cards you will have to set 'cardmhz = 600' in oscam.server");
478
479 return irdeto_card_init_provider(reader);
480}
481
482int32_t irdeto_do_ecm(struct s_reader * reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
483{
484 def_resp; cta_lr = 0; //suppress compiler error
485 static const uchar sc_EcmCmd[] = { 0x05, 0x00, 0x00, 0x02, 0x00 };
486 uchar sc_Acs57Ecm[] = {0xD5, 0x00, 0x00, 0x02, 0x00};
487 uchar sc_Acs57_Cmd[]={ ACS57ECM, 0xFE, 0x00, 0x00, 0x00 };
488 uchar cta_cmd[272];
489
490 int32_t i=0, acspadd=0;
491 if(reader->acs57==1) {
492 int32_t crc=63;
493 sc_Acs57Ecm[4]=er->ecm[2]-2;
494 if ((reader->caid == 0x0648) || (reader->caid == 0x0666) || (reader->caid == 0x0624)) { //crc for orf, cslink, skylink
495 sc_Acs57Ecm[2]=0;
496 crc^=0x01;crc^=0x05;crc^=sc_Acs57Ecm[2];crc^=sc_Acs57Ecm[3];crc^=(sc_Acs57Ecm[4]-1);
497 for(i=6;i<er->ecm[2]+4;i++)
498 crc^=er->ecm[i];
499 } else {
500 sc_Acs57Ecm[2]=er->ecm[6];
501 crc^=0x01;crc^=0x05;crc^=sc_Acs57Ecm[2];crc^=sc_Acs57Ecm[3];crc^=(sc_Acs57Ecm[4]-1);
502 for(i=6;i<er->ecm[3]-5;i++)
503 crc^=er->ecm[i];
504 }
505 memcpy(cta_cmd,sc_Acs57Ecm,sizeof(sc_Acs57Ecm));
506 memcpy(cta_cmd+5,er->ecm+6,er->ecm[2]-1);
507 cta_cmd[er->ecm[2]+2]=crc;
508
509 irdeto_do_cmd(reader, cta_cmd, 0, cta_res, &cta_lr);
510 int32_t acslength=cta_res[cta_lr-1];
511 // If acslength != 0x1F you don't have the entitlements or you camkey is bad
512 if(acslength!=0x1F){
513 switch(acslength){
514 case 0x09:
515 rdr_log(reader, "Maybe you don't have the entitlements for this channel");
516 break;
517 default:
518 rdr_log(reader, "Maybe you have a bad Cam Key set it from config file");
519 break;
520 }
521 return ERROR;
522 }
523 sc_Acs57_Cmd[4]=acslength;
524 cta_lr=0;
525 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
526 acspadd=8;
527 }else{
528 memcpy(cta_cmd, sc_EcmCmd, sizeof(sc_EcmCmd));
529 cta_cmd[4] = (er->ecm[2]) - 3;
530 memcpy(cta_cmd + sizeof(sc_EcmCmd), &er->ecm[6], cta_cmd[4]);
531
532 int32_t try = 1;
533 int32_t ret;
534 do {
535 if (try >1)
536 snprintf( ea->msglog, MSGLOGSIZE, "%s irdeto_do_cmd try nr %i", reader->label, try);
537 ret = (irdeto_do_cmd(reader, cta_cmd, 0x9D00, cta_res, &cta_lr));
538 ret = ret || (cta_lr < 24);
539 if (ret)
540 snprintf( ea->msglog, MSGLOGSIZE, "%s irdeto_do_cmd [%d] %02x %02x", reader->label, cta_lr, cta_res[cta_lr - 2], cta_res[cta_lr - 1] );
541 try++;
542 } while ((try < 3) && (ret));
543 if (ret)
544 return ERROR;
545 }
546 ReverseSessionKeyCrypt(reader->boxkey, cta_res+6+acspadd);
547 ReverseSessionKeyCrypt(reader->boxkey, cta_res+14+acspadd);
548 memcpy(ea->cw, cta_res + 6 + acspadd, 16);
549 return OK;
550}
551
552static int32_t irdeto_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr) {
553
554 int32_t i, l = (ep->emm[3]&0x07);
555 int32_t base = (ep->emm[3]>>3);
556 char dumprdrserial[l*3], dumpemmserial[l*3];
557
558 rdr_debug_mask(rdr, D_EMM, "Entered irdeto_get_emm_type ep->emm[3]=%02x",ep->emm[3]);
559
560 switch (l) {
561
562 case 0:
563 // global emm, 0 bytes addressed
564 ep->type = GLOBAL;
565 rdr_debug_mask(rdr, D_EMM, "GLOBAL base = %02x", base);
566 return 1;
567
568 case 2:
569 // shared emm, 2 bytes addressed
570 ep->type = SHARED;
571 memset(ep->hexserial, 0, 8);
572 memcpy(ep->hexserial, ep->emm + 4, l);
573 cs_hexdump(1, rdr->hexserial, l, dumprdrserial, sizeof(dumprdrserial));
574 cs_hexdump(1, ep->hexserial, l, dumpemmserial, sizeof(dumpemmserial));
575 rdr_debug_mask_sensitive(rdr, D_EMM, "SHARED l = %d ep = {%s} rdr = {%s} base = %02x", l,
576 dumpemmserial, dumprdrserial, base);
577
578 if (base & 0x10) {
579 // hex addressed
580 return (base == rdr->hexserial[3] && !memcmp(ep->emm + 4, rdr->hexserial, l));
581 }
582 else {
583 if (!memcmp(ep->emm + 4, rdr->hexserial, l))
584 return 1;
585
586 // provider addressed
587 for(i = 0; i < rdr->nprov; i++)
588 if (base == rdr->prid[i][0] && !memcmp(ep->emm + 4, &rdr->prid[i][1], l))
589 return 1;
590 }
591 rdr_debug_mask(rdr, D_EMM, "neither hex nor provider addressed or unknown provider id");
592 return 0;
593
594 case 3:
595 // unique emm, 3 bytes addressed
596 ep->type = UNIQUE;
597 memset(ep->hexserial, 0, 8);
598 memcpy(ep->hexserial, ep->emm + 4, l);
599 cs_hexdump(1, rdr->hexserial, l, dumprdrserial, sizeof(dumprdrserial));
600 cs_hexdump(1, ep->hexserial, l, dumpemmserial, sizeof(dumpemmserial));
601 rdr_debug_mask(rdr, D_EMM, "UNIQUE l = %d ep = {%s} rdr = {%s} base = %02x", l,
602 dumpemmserial, dumprdrserial, base);
603
604 if (base & 0x10)
605 // unique hex addressed
606 return (base == rdr->hexserial[3] && !memcmp(ep->emm + 4, rdr->hexserial, l));
607 else {
608 if (!memcmp(ep->emm + 4, rdr->hexserial, l))
609 return 1;
610
611 // unique provider addressed
612 for(i = 0; i < rdr->nprov; i++)
613 if (base == rdr->prid[i][0] && !memcmp(ep->emm + 4, &rdr->prid[i][1], l))
614 return 1;
615 }
616 rdr_debug_mask(rdr, D_EMM, "neither hex nor provider addressed or unknown provider id");
617 return 0;
618
619 default:
620 ep->type = UNKNOWN;
621 rdr_debug_mask(rdr, D_EMM, "UNKNOWN");
622 return 1;
623 }
624
625}
626
627static void irdeto_get_emm_filter(struct s_reader * rdr, uchar *filter)
628{
629 int32_t idx = 2;
630
631 filter[0]=0xFF;
632 filter[1]=0; //filter count
633
634 //int32_t base = rdr->hexserial[3];
635 //int32_t emm_g = base * 8;
636 //int32_t emm_s = emm_g + 2;
637 //int32_t emm_u = emm_g + 3;
638
639
640 filter[idx++]=EMM_GLOBAL;
641 filter[idx++]=0;
642 filter[idx+0] = 0x82;
643 filter[idx+0+16] = 0xFF;
644 filter[idx+1] = 0x00;
645 filter[idx+1+16] = 0x03;
646 filter[1]++;
647 idx += 32;
648
649/*
650 filter[idx++]=EMM_GLOBAL;
651 filter[idx++]=0;
652 filter[idx+0] = 0x82;
653 filter[idx+16] = 0xFF;
654 filter[idx+1] = 0x81;
655 filter[idx+1+16] = 0xFF;
656 memcpy(filter+idx+2, rdr->hexserial, 1);
657 memset(filter+idx+2+16, 0xFF, 1);
658 filter[1]++;
659 idx += 32;
660*/
661
662 filter[idx++]=EMM_UNIQUE;
663 filter[idx++]=0;
664 filter[idx+0] = 0x82;
665 filter[idx+0+16] = 0xFF;
666 filter[idx+1] = 0x03;
667 filter[idx+1+16] = 0x03;
668 memcpy(filter+idx+2, rdr->hexserial, 3);
669 memset(filter+idx+2+16, 0xFF, 3);
670 filter[1]++;
671 idx += 32;
672
673/* filter[idx++]=EMM_SHARED;
674 filter[idx++]=0;
675 filter[idx+0] = 0x82;
676 filter[idx+0+16] = 0xFF;
677 filter[idx+1] = 0x02;
678 filter[idx+1+16] = 0x03;
679 memcpy(filter+idx+2, rdr->hexserial, 2);
680 memset(filter+idx+2+16, 0xFF, 2);
681 filter[1]++;
682 idx += 32; */
683
684 int32_t i;
685 for(i = 0; i < rdr->nprov; i++) {
686 if (rdr->prid[i][1]==0xFF)
687 continue;
688
689 filter[idx++]=EMM_UNIQUE;
690 filter[idx++]=0;
691 filter[idx+0] = 0x82;
692 filter[idx+0+16] = 0xFF;
693 filter[idx+1] = 0x03;
694 filter[idx+1+16] = 0x03;
695 memcpy(filter+idx+2, &rdr->prid[i][1], 3);
696 memset(filter+idx+2+16, 0xFF, 3);
697 filter[1]++;
698 idx += 32;
699
700 filter[idx++]=EMM_SHARED;
701 filter[idx++]=0;
702 filter[idx+0] = 0x82;
703 filter[idx+0+16] = 0xFF;
704 filter[idx+1] = 0x02;
705 filter[idx+1+16] = 0x03;
706 memcpy(filter+idx+2, &rdr->prid[i][1], 2);
707 memset(filter+idx+2+16, 0xFF, 2);
708 filter[1]++;
709 idx += 32;
710
711 if (filter[1]>=10) {
712 rdr_log(rdr, "irdeto_get_emm_filter: could not start all emm filter");
713 break;
714 }
715 }
716
717 return;
718}
719
720#define ADDRLEN 4 // Address length in EMM commands
721
722static int32_t irdeto_do_emm(struct s_reader * reader, EMM_PACKET *ep)
723{
724 def_resp;
725 static const uchar sc_EmmCmd[] = { 0x01,0x00,0x00,0x00,0x00 };
726 static uchar sc_Acs57Emm[] = { 0xD1,0x00,0x00,0x00,0x00 };
727 uchar sc_Acs57_Cmd[]={ ACS57EMM, 0xFE, 0x00, 0x00, 0x00 };
728
729 uchar cta_cmd[272];
730 if (ep->emm[0] != 0x82) {
731 rdr_debug_mask(reader, D_EMM, "Invalid EMM: Has to start with 0x82, but starts with %02x!", ep->emm[0]);
732 return ERROR;
733 }
734
735 int32_t i, l = (ep->emm[3] & 0x07), ok = 0;
736 int32_t mode = (ep->emm[3] >> 3);
737 uchar *emm = ep->emm;
738
739 if (mode & 0x10) {
740 // hex addressed
741 ok = (mode == reader->hexserial[3] && (!l || !memcmp(&emm[4], reader->hexserial, l)));
742 }
743 else {
744 ok = !memcmp(&emm[4], reader->hexserial, l);
745
746 // provider addressed
747 for(i = 0; i < reader->nprov && !ok; i++) {
748 ok = (mode == reader->prid[i][0] && (!l || !memcmp(&emm[4], &reader->prid[i][1], l)));
749 }
750 }
751
752 if (ok) {
753 l++;
754 if (l <= ADDRLEN) {
755 if(reader->acs57==1) {
756 int32_t dataLen=0;
757 if(ep->type==UNIQUE){
758 dataLen=ep->emm[2]-1;
759 }else{
760 dataLen=ep->emm[2];
761 }
762 if(dataLen < 7 || dataLen > (int32_t)sizeof(ep->emm) - 6 || dataLen > (int32_t)sizeof(cta_cmd) - 9) {
763 rdr_debug_mask(reader, D_EMM, "dataLen %d seems wrong, faulty EMM?", dataLen);
764 return ERROR;
765 }
766 if (ep->type==GLOBAL && (reader->caid==0x0624 || reader->caid==0x0648 || reader->caid == 0x0666)) dataLen+=2;
767 int32_t crc=63;
768 sc_Acs57Emm[4]=dataLen;
769 memcpy(&cta_cmd, sc_Acs57Emm, sizeof(sc_Acs57Emm));
770 crc^=0x01;crc^=0x01;crc^=0x00;crc^=0x00;crc^=0x00;crc^=(dataLen-1);
771 memcpy(&cta_cmd[5],&ep->emm[3],10);
772 if (ep->type==UNIQUE) {
773 memcpy(&cta_cmd[9],&ep->emm[9],dataLen-4);
774 } else {
775 if (ep->type==GLOBAL && (reader->caid==0x0624 || reader->caid==0x0648 || reader->caid == 0x0666)) {
776 memcpy(&cta_cmd[9],&ep->emm[6],1);
777 memcpy(&cta_cmd[10],&ep->emm[7],dataLen-6);
778// cta_cmd[9]=0x00;
779 } else if (reader->caid==0x0624 || reader->caid==0x0648 || reader->caid == 0x0666) { //only orf, cslink, skylink
780 memcpy(&cta_cmd[9],&ep->emm[8],dataLen-4);
781 } else {
782 memcpy(&cta_cmd[10],&ep->emm[9],dataLen-6);
783 }
784 }
785 for(i=5;i<dataLen+4;i++)
786 crc^=cta_cmd[i];
787 cta_cmd[dataLen-1+5]=crc;
788 irdeto_do_cmd(reader, cta_cmd, 0, cta_res, &cta_lr);
789 int32_t acslength=cta_res[cta_lr-1];
790 sc_Acs57_Cmd[4]=acslength;
791 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
792 if (cta_res[2] != 0)
793 rdr_log(reader, "EMM write error %02X", cta_res[2]);
794 return OK;
795 } else {
796 const int32_t dataLen = SCT_LEN(emm) - 5 - l; // sizeof of emm bytes (nanos)
797 if(dataLen < 1 || dataLen > (int32_t)sizeof(ep->emm) - 5 - l || dataLen > (int32_t)sizeof(cta_cmd) - (int32_t)sizeof(sc_EmmCmd) - ADDRLEN) {
798 rdr_debug_mask(reader, D_EMM, "dataLen %d seems wrong, faulty EMM?", dataLen);
799 return ERROR;
800 }
801 uchar *ptr = cta_cmd;
802 memcpy(ptr, sc_EmmCmd, sizeof(sc_EmmCmd)); // copy card command
803 ptr[4] = dataLen + ADDRLEN; // set card command emm size
804 ptr += sizeof(sc_EmmCmd); emm += 3;
805 memset(ptr, 0, ADDRLEN); // clear addr range
806 memcpy(ptr, emm, l); // copy addr bytes
807 ptr += ADDRLEN; emm += l;
808 memcpy(ptr, &emm[2], dataLen); // copy emm bytes
809 return(irdeto_do_cmd(reader, cta_cmd, 0, cta_res, &cta_lr) ? 0 : 1); // TODO: this always returns success cause return code cant be 0
810 }
811 } else
812 rdr_debug_mask(reader, D_EMM, "addrlen %d > %d", l, ADDRLEN);
813 }
814 return ERROR;
815}
816
817static int32_t irdeto_card_info(struct s_reader * reader)
818{
819 def_resp;
820 int32_t i, p;
821
822 cs_clear_entitlement(reader); // reset the entitlements
823
824 uchar sc_GetChanelIds[] = { 0x02, 0x04, 0x00, 0x00, 0x01, 0x00 };
825 uchar sc_Acs57Code[] = { 0xD2, 0x16, 0x00, 0x00, 0x01 ,0x37},
826 sc_Acs57Prid[] = { 0xD2, 0x08, 0x00, 0x00, 0x02, 0x00,0x00 },
827 sc_Acs57_Cmd[] = { ACS57GET, 0xFE, 0x00, 0x00, 0x00 };
828
829 /*
830 * ContryCode2
831 */
832 int32_t acspadd=0;
833 if(reader->acs57==1){
834 acspadd=8;
835 reader_chk_cmd(sc_Acs57Code,0);
836 int32_t acslength=cta_res[cta_lr-1];
837 sc_Acs57_Cmd[4]=acslength;
838 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
839 } else {
840 reader_chk_cmd(sc_GetCountryCode2, 0);
841 }
842
843 if (((cta_lr>9) && !(cta_res[cta_lr-2]|cta_res[cta_lr-1])) || (reader->acs57==1))
844 {
845 rdr_debug_mask(reader, D_READER, "max chids: %d, %d, %d, %d", cta_res[6+acspadd], cta_res[7+acspadd], cta_res[8+acspadd], cta_res[9+acspadd]);
846
847 /*
848 * Provider 2
849 */
850 for (i=p=0; i<reader->nprov; i++)
851 {
852 int32_t j, k, chid, first=1;
853 char t[32];
854 if (reader->prid[i][4]!=0xff)
855 {
856 p++;
857 sc_Acs57Prid[3]=i;
858 sc_GetChanelIds[3]=i; // provider at index i
859 j=0;
860 // for (j=0; j<10; j++) => why 10 .. do we know for sure the there are only 10 chids !!!
861 // shouldn't it me the max chid value we read above ?!
862 while(1) // will exit if cta_lr < 61 .. which is the correct break condition.
863 {
864 if(reader->acs57==1) {
865 int32_t crc=63;
866 sc_Acs57Prid[5]=j;
867 crc^=0x01;crc^=0x02;crc^=0x04;
868 crc^=sc_Acs57Prid[2];crc^=sc_Acs57Prid[3];crc^=(sc_Acs57Prid[4]-1);crc^=sc_Acs57Prid[5];
869 sc_Acs57Prid[6]=crc;
870 irdeto_do_cmd(reader, sc_Acs57Prid, 0x903C, cta_res, &cta_lr);
871 int32_t acslength=cta_res[cta_lr-1];
872 if (acslength==0x09) break;
873 sc_Acs57_Cmd[4]=acslength;
874 reader_chk_cmd(sc_Acs57_Cmd, acslength+2);
875 if(cta_res[10]==0xFF) break;
876 cta_res[cta_lr-3]=0xff;
877 cta_res[cta_lr-2]=0xff;
878 cta_res[cta_lr-1]=0xff;
879 acspadd=8;
880 } else {
881 sc_GetChanelIds[5]=j; // chid at index j for provider at index i
882 reader_chk_cmd(sc_GetChanelIds, 0);
883 }
884 // if (cta_lr<61) break; // why 61 (0 to 60 in steps of 6 .. is it 10*6 from the 10 in the for loop ?
885 // what happen if the card only send back.. 9 chids (or less)... we don't see them
886 // so we should check whether or not we have at least 6 bytes (1 chid).
887 if (cta_lr<6) break;
888
889 for(k=0+acspadd; k<cta_lr; k+=6)
890 {
891 chid=b2i(2, cta_res+k);
892 if (chid && chid!=0xFFFF)
893 {
894 time_t date, start_t, end_t;
895
896 start_t = chid_date(reader, date = b2i(2, cta_res + k + 2), t, 16);
897 end_t = chid_date(reader, date + cta_res[k + 4], t + 16, 16);
898
899 // todo: add entitlements to list but produces a warning related to date variable
900 cs_add_entitlement(reader, reader->caid, b2i(3, &reader->prid[i][1]), chid, 0, start_t, end_t, 3);
901
902 if (first)
903 {
904 rdr_log(reader, "entitlements for provider: %d, id: %06X", p, b2i(3, &reader->prid[i][1]));
905 first=0;
906 }
907 rdr_log(reader, "chid: %04X, date: %s - %s", chid, t, t+16);
908 }
909 }
910 j++;
911 }
912 }
913 }
914 }
915 rdr_log(reader, "ready for requests");
916 return OK;
917}
918
919void reader_irdeto(struct s_cardsystem *ph)
920{
921 ph->do_emm=irdeto_do_emm;
922 ph->do_ecm=irdeto_do_ecm;
923 ph->card_info=irdeto_card_info;
924 ph->card_init=irdeto_card_init;
925 ph->get_emm_type=irdeto_get_emm_type;
926 ph->get_emm_filter=irdeto_get_emm_filter;
927 ph->caids[0]=0x06;
928 ph->caids[1]=0x17;
929 ph->desc="irdeto";
930}
931#endif
Note: See TracBrowser for help on using the repository browser.