source: trunk/reader-irdeto.c@ 1200

Last change on this file since 1200 was 1200, checked in by nightmann, 12 years ago

For irdeto cards you can now use boxkey in oscam.server as irdeto 'camkey' and rsakey in oscam.server as irdeto camkey-data. (not fully tested yet)
For further information and discussion see: http://streamboard.gmc.to/wbb2/thread.php?postid=317175#post317175 or http://streamboard.gmc.to:8001/ticket/333

File size: 13.9 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3
4extern uchar cta_cmd[], cta_res[];
5extern ushort cta_lr;
6static int nagra;
7
8static const uchar CryptTable[256] =
9{
10 0xDA, 0x26, 0xE8, 0x72, 0x11, 0x52, 0x3E, 0x46,
11 0x32, 0xFF, 0x8C, 0x1E, 0xA7, 0xBE, 0x2C, 0x29,
12 0x5F, 0x86, 0x7E, 0x75, 0x0A, 0x08, 0xA5, 0x21,
13 0x61, 0xFB, 0x7A, 0x58, 0x60, 0xF7, 0x81, 0x4F,
14 0xE4, 0xFC, 0xDF, 0xB1, 0xBB, 0x6A, 0x02, 0xB3,
15 0x0B, 0x6E, 0x5D, 0x5C, 0xD5, 0xCF, 0xCA, 0x2A,
16 0x14, 0xB7, 0x90, 0xF3, 0xD9, 0x37, 0x3A, 0x59,
17 0x44, 0x69, 0xC9, 0x78, 0x30, 0x16, 0x39, 0x9A,
18 0x0D, 0x05, 0x1F, 0x8B, 0x5E, 0xEE, 0x1B, 0xC4,
19 0x76, 0x43, 0xBD, 0xEB, 0x42, 0xEF, 0xF9, 0xD0,
20 0x4D, 0xE3, 0xF4, 0x57, 0x56, 0xA3, 0x0F, 0xA6,
21 0x50, 0xFD, 0xDE, 0xD2, 0x80, 0x4C, 0xD3, 0xCB,
22 0xF8, 0x49, 0x8F, 0x22, 0x71, 0x84, 0x33, 0xE0,
23 0x47, 0xC2, 0x93, 0xBC, 0x7C, 0x3B, 0x9C, 0x7D,
24 0xEC, 0xC3, 0xF1, 0x89, 0xCE, 0x98, 0xA2, 0xE1,
25 0xC1, 0xF2, 0x27, 0x12, 0x01, 0xEA, 0xE5, 0x9B,
26 0x25, 0x87, 0x96, 0x7B, 0x34, 0x45, 0xAD, 0xD1,
27 0xB5, 0xDB, 0x83, 0x55, 0xB0, 0x9E, 0x19, 0xD7,
28 0x17, 0xC6, 0x35, 0xD8, 0xF0, 0xAE, 0xD4, 0x2B,
29 0x1D, 0xA0, 0x99, 0x8A, 0x15, 0x00, 0xAF, 0x2D,
30 0x09, 0xA8, 0xF5, 0x6C, 0xA1, 0x63, 0x67, 0x51,
31 0x3C, 0xB2, 0xC0, 0xED, 0x94, 0x03, 0x6F, 0xBA,
32 0x3F, 0x4E, 0x62, 0x92, 0x85, 0xDD, 0xAB, 0xFE,
33 0x10, 0x2E, 0x68, 0x65, 0xE7, 0x04, 0xF6, 0x0C,
34 0x20, 0x1C, 0xA9, 0x53, 0x40, 0x77, 0x2F, 0xA4,
35 0xFA, 0x6D, 0x73, 0x28, 0xE2, 0xCD, 0x79, 0xC8,
36 0x97, 0x66, 0x8E, 0x82, 0x74, 0x06, 0xC7, 0x88,
37 0x1A, 0x4A, 0x6B, 0xCC, 0x41, 0xE9, 0x9D, 0xB8,
38 0x23, 0x9F, 0x3D, 0xBF, 0x8D, 0x95, 0xC5, 0x13,
39 0xB9, 0x24, 0x5A, 0xDC, 0x64, 0x18, 0x38, 0x91,
40 0x7F, 0x5B, 0x70, 0x54, 0x07, 0xB6, 0x4B, 0x0E,
41 0x36, 0xAC, 0x31, 0xE6, 0xD6, 0x48, 0xAA, 0xB4
42};
43
44static uchar
45 sc_CamKey[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 },
46 sc_GetCountryCode[] = { 0x02, 0x02, 0x03, 0x00, 0x00 },
47 sc_GetASCIISerial[] = { 0x02, 0x00, 0x03, 0x00, 0x00 },
48 sc_GetHEXSerial[] = { 0x02, 0x01, 0x00, 0x00, 0x00 },
49 sc_GetProvider[] = { 0x02, 0x03, 0x03, 0x00, 0x00 },
50 sc_GetCardFile[] = { 0x02, 0x0E, 0x02, 0x00, 0x00 },
51 sc_GetCountryCode2[]= { 0x02, 0x0B, 0x00, 0x00, 0x00 },
52 sc_GetChanelIds[] = { 0x02, 0x04, 0x00, 0x00, 0x01, 0x00 },
53 sc_GetCamKey384CZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
54 0x18, 0xD7, 0x55, 0x14, 0xC0, 0x83, 0xF1, 0x38,
55 0x39, 0x6F, 0xF2, 0xEC, 0x4F, 0xE3, 0xF1, 0x85,
56 0x01, 0x46, 0x06, 0xCE, 0x7D, 0x08, 0x2C, 0x74,
57 0x46, 0x8F, 0x72, 0xC4, 0xEA, 0xD7, 0x9C, 0xE0,
58 0xE1, 0xFF, 0x58, 0xE7, 0x70, 0x0C, 0x92, 0x45,
59 0x26, 0x18, 0x4F, 0xA0, 0xE2, 0xF5, 0x9E, 0x46,
60 0x6F, 0xAE, 0x95, 0x35, 0xB0, 0x49, 0xB2, 0x0E,
61 0xA4, 0x1F, 0x8E, 0x47, 0xD0, 0x24, 0x11, 0xD0 },
62 sc_GetCamKey384DZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
63 0x27, 0xF2, 0xD6, 0xCD, 0xE6, 0x88, 0x62, 0x46,
64 0x81, 0xB0, 0xF5, 0x3E, 0x6F, 0x13, 0x4D, 0xCC,
65 0xFE, 0xD0, 0x67, 0xB1, 0x93, 0xDD, 0xF4, 0xDE,
66 0xEF, 0xF5, 0x3B, 0x04, 0x1D, 0xE5, 0xC3, 0xB2,
67 0x54, 0x38, 0x57, 0x7E, 0xC8, 0x39, 0x07, 0x2E,
68 0xD2, 0xF4, 0x05, 0xAA, 0x15, 0xB5, 0x55, 0x24,
69 0x90, 0xBB, 0x9B, 0x00, 0x96, 0xF0, 0xCB, 0xF1,
70 0x8A, 0x08, 0x7F, 0x0B, 0xB8, 0x79, 0xC3, 0x5D },
71 sc_GetCamKey384FZ[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
72 0x62, 0xFE, 0xD8, 0x4F, 0x44, 0x86, 0x2C, 0x21,
73 0x50, 0x9A, 0xBE, 0x27, 0x15, 0x9E, 0xC4, 0x48,
74 0xF3, 0x73, 0x5C, 0xBD, 0x08, 0x64, 0x6D, 0x13,
75 0x64, 0x90, 0x14, 0xDB, 0xFF, 0xC3, 0xFE, 0x03,
76 0x97, 0xFA, 0x75, 0x08, 0x12, 0xF9, 0x8F, 0x84,
77 0x83, 0x17, 0xAA, 0x6F, 0xEF, 0x2C, 0x10, 0x1B,
78 0xBF, 0x31, 0x41, 0xC3, 0x54, 0x2F, 0x65, 0x50,
79 0x95, 0xA9, 0x64, 0x22, 0x5E, 0xA4, 0xAF, 0xA9 },
80 sc_GetCamKey383C[] = { 0x02, 0x09, 0x03, 0x00, 0x40,
81 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
82 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
83 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
84 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
85 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
86 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
87 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
88 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
89
90static void XRotateLeft8Byte(uchar *buf)
91{
92 int k;
93 uchar t1=buf[7];
94 uchar t2=0;
95 for(k=0; k<=7; k++)
96 {
97 t2=t1;
98 t1=buf[k];
99 buf[k]=(buf[k]<<1)|(t2>>7);
100 }
101}
102
103static void ReverseSessionKeyCrypt(const uchar *camkey, uchar *key)
104{
105 uchar localkey[8], tmp1, tmp2;
106 int idx1,idx2;
107
108 memcpy(localkey, camkey, 8) ;
109 for(idx1=0; idx1<8; idx1++)
110 {
111 for(idx2=0; idx2<8; idx2++)
112 {
113 tmp1 = CryptTable[key[7] ^ localkey[idx2] ^ idx1] ;
114 tmp2 = key[0] ;
115 key[0] = key[1] ;
116 key[1] = key[2] ;
117 key[2] = key[3] ;
118 key[3] = key[4] ;
119 key[4] = key[5] ;
120 key[5] = key[6] ^ tmp1 ;
121 key[6] = key[7] ;
122 key[7] = tmp1 ^ tmp2 ;
123 }
124 XRotateLeft8Byte(localkey);
125 }
126}
127
128static time_t chid_date(ulong date, char *buf, int l)
129{
130 // Irdeto date starts 01.08.1997 which is
131 // 870393600 seconds in unix calendar time
132 time_t ut=870393600L+date*(24*3600);
133 if (buf)
134 {
135 struct tm *t;
136 t=gmtime(&ut);
137 snprintf(buf, l, "%04d/%02d/%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday);
138 }
139 return(ut);
140}
141
142static int irdeto_do_cmd(uchar *buf, ushort good)
143{
144 int rc;
145 if( (rc=reader_cmd2icc(buf, buf[4]+5)) )
146 return(rc); // result may be 0 (success) or negative
147 if (cta_lr<2)
148 return(0x7F7F); // this should never happen
149 return(good!=b2i(2, cta_res+cta_lr-2));
150}
151
152#define reader_chk_cmd(cmd, l) \
153{ \
154 if (reader_cmd2icc(cmd, sizeof(cmd))) return(0); \
155 if (l && (cta_lr!=l)) return(0); }
156
157int irdeto_card_init(uchar *atr)
158{
159 int i, camkey=0, cs_ptyp_orig=cs_ptyp;
160 uchar buf[256]={0};
161 //uchar sc_GetROM[] = { 0xA0, 0xCA, 0x00, 0x00, 3, 0x10, 0, 0x11};
162
163 if (memcmp(atr+4, "IRDETO", 6))
164 return(0);
165 nagra=0;
166
167 if(reader[ridx].has_rsa) // we use rsa from config as camkey
168 {
169 cs_debug("[irdeto-reader] using camkey data from config");
170 memcpy(&sc_GetCamKey383C[5], reader[ridx].rsa_mod, 0x40);
171 memcpy(sc_CamKey, reader[ridx].nagra_boxkey, 8);
172 cs_debug("[irdeto-reader] camkey: %s", cs_hexdump (0, sc_CamKey, 8));
173 cs_debug("[irdeto-reader] camkey-data: %s", cs_hexdump (0, &sc_GetCamKey383C[5], 32));
174 cs_debug("[irdeto-reader] camkey-data: %s", cs_hexdump (0, &sc_GetCamKey383C[37], 32));
175 }
176
177 /*
178 * ContryCode
179 */
180 reader_chk_cmd(sc_GetCountryCode, 18);
181 reader[ridx].acs=(cta_res[0]<<8)|cta_res[1];
182 reader[ridx].caid[0]=(cta_res[5]<<8)|cta_res[6];
183 cs_ri_log("type: %s, caid: %04X, acs: %x.%02x%s",
184 (nagra) ? "aladin" : "irdeto",
185 reader[ridx].caid[0], cta_res[0], cta_res[1], buf);
186
187 /*
188 * Ascii/Hex-Serial
189 */
190 reader_chk_cmd(sc_GetASCIISerial, 22);
191 memcpy(buf, cta_res, 10);
192 buf[10]=0;
193 reader_chk_cmd(sc_GetHEXSerial, 18);
194 memcpy(reader[ridx].hexserial, cta_res+12, 8);
195 reader[ridx].nprov=cta_res[10];
196 cs_ri_log("ascii serial: %s, hex serial: %02X%02X%02X, hex base: %02X",
197 buf, cta_res[12], cta_res[13], cta_res[14], cta_res[15]);
198
199 /*
200 * CardFile
201 */
202 for (sc_GetCardFile[2]=2;sc_GetCardFile[2]<4;sc_GetCardFile[2]++)
203 reader_chk_cmd(sc_GetCardFile, 0);
204
205 /*
206 * CamKey
207 */
208 if ((atr[14]==0x03) && (atr[15]==0x84) && (atr[16]==0x55))
209 {
210 switch (reader[ridx].caid[0])
211 {
212 case 0x1702: camkey=1; break;
213 case 0x1722: camkey=2; break;
214 case 0x1762: camkey=3; break;
215 default : camkey=4; break;
216 }
217 }
218
219 if ((reader[ridx].caid[0] >= 0x1700) && (reader[ridx].caid[0] <= 0x1799)) // Betacrypt
220 {
221 memset(reader[ridx].prid, 0xff, sizeof(reader[ridx].prid));
222 for (i=0; i<reader[ridx].nprov; i++)
223 {
224 //values are needed for AU to work for Nagravision/Aladin/Betacrypt
225 reader[ridx].prid[i][0]=0;
226 reader[ridx].prid[i][1]=0;
227 reader[ridx].prid[i][2]=0;
228 reader[ridx].prid[i][3]=i;
229 //reader[ridx].prid[i][4]=0; //not sure what to do with this one
230
231 //since shared address is not filled, we fill it here
232 reader[ridx].sa[i][0]=0x00;
233 reader[ridx].sa[i][1]=0xFF;
234 reader[ridx].sa[i][2]=0xFF;
235 reader[ridx].sa[i][3]=0xFF;
236 }
237 }
238
239 cs_ptyp=D_DEVICE;
240 cs_debug("[irdeto-reader] set camkey for type=%d", camkey);
241 cs_ptyp=cs_ptyp_orig;
242
243 switch (camkey)
244 {
245 case 1:
246 reader_chk_cmd(sc_GetCamKey384CZ, 10);
247 break;
248 case 2:
249 reader_chk_cmd(sc_GetCamKey384DZ, 10);
250 break;
251 case 3:
252 reader_chk_cmd(sc_GetCamKey384FZ, 10);
253 break;
254 default:
255 reader_chk_cmd(sc_GetCamKey383C, 0);
256 break;
257 }
258
259 cs_log("ready for requests");
260 return(1);
261}
262
263int irdeto_do_ecm(ECM_REQUEST *er)
264{
265 static const uchar sc_EcmCmd[] = { 0x05, 0x00, 0x00, 0x02, 0x00 };
266
267 memcpy(cta_cmd, sc_EcmCmd, sizeof(sc_EcmCmd));
268 cta_cmd[4]=(er->ecm[2])-3;
269 memcpy(cta_cmd+sizeof(sc_EcmCmd), &er->ecm[6], cta_cmd[4]);
270 if (irdeto_do_cmd(cta_cmd, 0x9D00)) return(0);
271 if (cta_lr<24) return(0);
272 ReverseSessionKeyCrypt(sc_CamKey, cta_res+6);
273 ReverseSessionKeyCrypt(sc_CamKey, cta_res+14);
274 memcpy(er->cw, cta_res+6, 16);
275 return(1);
276}
277
278int irdeto_do_emm(EMM_PACKET *ep)
279{
280 static const uchar sc_EmmCmd[] = { 0x01,0x00,0x00,0x00,0x00 };
281
282 int i, l=(ep->emm[3]&0x07), ok=0;
283 int mode=(ep->emm[3]>>3);
284
285 uchar *emm=ep->emm;
286 ep->type=emm[3];
287 if (mode&0x10) // Hex addressed
288 {
289 ok=(mode==reader[ridx].hexserial[3] &&
290 (!l || !memcmp(&emm[4], reader[ridx].hexserial, l)));
291 }
292 else // Provider addressed
293 {
294 for(i=0; i<reader[ridx].nprov; i++)
295 {
296 ok=(mode==reader[ridx].prid[i][0] &&
297 (!l || !memcmp(&emm[4], &reader[ridx].prid[i][1], l)));
298 if (ok) break;
299 }
300 }
301
302 if (ok)
303 {
304 l++;
305 if (l<=ADDRLEN)
306 {
307 const int dataLen=SCT_LEN(emm)-5-l; // sizeof of emm bytes (nanos)
308 uchar *ptr=cta_cmd;
309 memcpy(ptr, sc_EmmCmd, sizeof(sc_EmmCmd)); // copy card command
310 ptr[4]=dataLen+ADDRLEN; // set card command emm size
311 ptr+=sizeof(sc_EmmCmd); emm+=3;
312 memset(ptr, 0, ADDRLEN); // clear addr range
313 memcpy(ptr, emm, l); // copy addr bytes
314 ptr+=ADDRLEN; emm+=l;
315 memcpy(ptr, &emm[2], dataLen); // copy emm bytes
316 return(irdeto_do_cmd(cta_cmd, 0) ? 0 : 1);
317 }
318 else
319 cs_log("addrlen %d > %d", l, ADDRLEN);
320 }
321 return(0);
322}
323
324int irdeto_card_info(void)
325{
326 int i, p;
327 uchar buf[256]={0};
328 uchar sc_GetChid[] = { 0xA0, 0xCA, 0x00, 0x00, 4, 0x22, 1, 5, 0x20};
329 cs_log("card detected");
330 cs_log("type: irdeto");
331
332 if (nagra)
333 {
334 for (sc_GetChid[7]=5;;sc_GetChid[7]|=0x80)
335 {
336 ushort chid;
337 char ds[16], de[16];
338 reader_chk_cmd(sc_GetChid, 0);
339 if ((cta_lr>33) && (chid=b2i(2, cta_res+11)))
340 {
341 chid_date(b2i(2, cta_res+20)-0x7f7, ds, 15);
342 chid_date(b2i(2, cta_res+13)-0x7f7, de, 15);
343 cs_ri_log("chid: %04X, date: %s - %s", chid, ds, de);
344 }
345 else
346 break;
347 }
348 }
349 else
350 {
351 /*
352 * Provider
353 */
354 memset(reader[ridx].prid, 0xff, sizeof(reader[ridx].prid));
355 for (buf[0]=i=p=0; i<reader[ridx].nprov; i++)
356 {
357 sc_GetProvider[3]=i;
358 reader_chk_cmd(sc_GetProvider, 0);
359// if ((cta_lr==26) && (cta_res[0]!=0xf))
360 if ((cta_lr==26) && ((!(i&1)) || (cta_res[0]!=0xf)))
361 {
362 reader[ridx].prid[i][4]=p++;
363 memcpy(&reader[ridx].prid[i][0], cta_res, 4);
364 sprintf((char *) buf+strlen((char *)buf), ",%06lx", b2i(3, &reader[ridx].prid[i][1]));
365 }
366 else
367 reader[ridx].prid[i][0]=0xf;
368 }
369 if (p)
370 cs_ri_log("providers: %d (%s)", p, buf+1);
371
372 /*
373 * ContryCode2
374 */
375 reader_chk_cmd(sc_GetCountryCode2, 0);
376 if ((cta_lr>9) && !(cta_res[cta_lr-2]|cta_res[cta_lr-1]))
377 {
378 cs_debug("max chids: %d, %d, %d, %d", cta_res[6], cta_res[7], cta_res[8], cta_res[9]);
379
380 /*
381 * Provider 2
382 */
383 for (i=p=0; i<reader[ridx].nprov; i++)
384 {
385 int j, k, chid, first=1;
386 char t[32];
387 if (reader[ridx].prid[i][4]!=0xff)
388 {
389 p++;
390 sc_GetChanelIds[3]=i;
391 for (j=0; j<10; j++)
392 {
393 sc_GetChanelIds[5]=j;
394 reader_chk_cmd(sc_GetChanelIds, 0);
395 if (cta_lr<61) break;
396 for(k=0; k<cta_lr; k+=6)
397 {
398 chid=b2i(2, cta_res+k);
399 if (chid && chid!=0xFFFF)
400 {
401 time_t date;
402 chid_date(date=b2i(2, cta_res+k+2), t, 16);
403 chid_date(date+cta_res[k+4], t+16, 16);
404 if (first)
405 {
406 cs_ri_log("provider: %d, id: %06X", p, b2i(3, &reader[ridx].prid[i][1]));
407 first=0;
408 }
409 cs_ri_log("chid: %04X, date: %s - %s", chid, t, t+16);
410 }
411 }
412 }
413 }
414 }
415 }
416 }
417
418// maps the provider id for Betacrypt from FFFFFF to 000000,
419// fixes problems with cascading CCcam and OSCam
420
421 if ((reader[ridx].caid[0] >= 0x1700) && (reader[ridx].caid[0] <= 0x1799))
422 {
423 memset(reader[ridx].prid, 0xff, sizeof(reader[ridx].prid));
424 for (i=0; i<reader[ridx].nprov; i++)
425 {
426 reader[ridx].prid[i][0]=0;
427 reader[ridx].prid[i][1]=0;
428 reader[ridx].prid[i][2]=0;
429 reader[ridx].prid[i][3]=i;
430 reader[ridx].sa[i][0]=0x00;
431 reader[ridx].sa[i][1]=0xFF;
432 reader[ridx].sa[i][2]=0xFF;
433 reader[ridx].sa[i][3]=0xFF;
434 }
435 }
436 return(1);
437}
Note: See TracBrowser for help on using the repository browser.