source: trunk/reader-viaccess.c@ 8441

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

cryptoworks/viaccess: Allow EMMs that are reassembled by the client to work.

ACamd, mgcamd and possibly other clients reassemble and filter EMMs
before sending them to OSCam. When EMM reassembly was moved on the
local reader side in r8377, EMMs were stopped from reaching the card
until they were reassembled.

But if the EMM is already reassembled then no EMM-SH packets are
comming so the reassembly never succeeded.

With this change all EMMs reach the card even if they are not
reassembled. This allows already reassembled EMMs to work and EMM
reassembly to work.

The downside is that there would be some EMM writing errors because
the reader would try to write not assembled EMMs instead of waiting
for reassembly.

  • Property svn:eol-style set to LF
File size: 31.4 KB
Line 
1#include "globals.h"
2#ifdef READER_VIACCESS
3#include "oscam-aes.h"
4#include "oscam-time.h"
5#include "oscam-emm.h"
6#include "reader-common.h"
7
8struct via_date {
9 uint16_t day_s : 5;
10 uint16_t month_s : 4;
11 uint16_t year_s : 7;
12
13 uint16_t day_e : 5;
14 uint16_t month_e : 4;
15 uint16_t year_e : 7;
16};
17
18static void parse_via_date(const uchar *buf, struct via_date *vd, int32_t fend)
19{
20 uint16_t date;
21
22 date = (buf[0]<<8) | buf[1];
23 vd->day_s = date & 0x1f;
24 vd->month_s = (date>>5) & 0x0f;
25 vd->year_s = (date>>9) & 0x7f;
26
27 if( fend )
28 {
29 date = (buf[2]<<8) | buf[3];
30 vd->day_e = date & 0x1f;
31 vd->month_e = (date>>5) & 0x0f;
32 vd->year_e = (date>>9) & 0x7f;
33 }
34}
35
36//static void get_via_data(const uchar *b, int32_t l, time_t *start_t, time_t *end_t, uchar *cls)
37//{
38// int32_t i, j;
39// struct via_date vd;
40// struct tm tm;
41// memset(&vd, 0, sizeof(struct via_date));
42//
43// // b -> via date (4 bytes)
44// b+=4;
45// l-=4;
46//
47// j=l-1;
48// for (; j>=0; j--)
49// for (i=0; i<8; i++)
50// if (b[j] & (1 << (i&7)))
51// {
52// parse_via_date(b-4, &vd, 1);
53// *cls=(l-(j+1))*8+i;
54// }
55//
56// memset(&tm, 0, sizeof(struct tm));
57// tm.tm_year = vd.year_s + 80; //via year starts in 1980, tm_year starts in 1900
58// tm.tm_mon = vd.month_s - 1; // january is 0 in tm_mon
59// tm.tm_mday = vd.day_s;
60// *start_t = mktime(&tm);
61//
62// tm.tm_year = vd.year_e + 80;
63// tm.tm_mon = vd.month_e - 1;
64// tm.tm_mday = vd.day_e;
65// *end_t = mktime(&tm);
66//
67//}
68
69static void show_class(struct s_reader *reader, const char *p, uint32_t provid, const uchar *b, int32_t l)
70{
71 int32_t i, j;
72
73 // b -> via date (4 bytes)
74 b+=4;
75 l-=4;
76
77 j=l-1;
78 for (; j>=0; j--)
79 for (i=0; i<8; i++)
80 if (b[j] & (1 << (i&7)))
81 {
82 uchar cls;
83 struct via_date vd;
84 parse_via_date(b-4, &vd, 1);
85 cls=(l-(j+1))*8+i;
86 if (p)
87 rdr_log(reader, "%sclass: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", p, cls,
88 vd.year_s+1980, vd.month_s, vd.day_s,
89 vd.year_e+1980, vd.month_e, vd.day_e);
90 else {
91 rdr_log(reader, "class: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", cls,
92 vd.year_s+1980, vd.month_s, vd.day_s,
93 vd.year_e+1980, vd.month_e, vd.day_e);
94
95 time_t start_t, end_t;
96 struct tm tm;
97 //convert time:
98 memset(&tm, 0, sizeof(tm));
99 tm.tm_year = vd.year_s+80; //via year starts in 1980, tm_year starts in 1900
100 tm.tm_mon = vd.month_s-1; // january is 0 in tm_mon
101 tm.tm_mday = vd.day_s;
102 start_t = cs_timegm(&tm);
103
104 tm.tm_year = vd.year_e+80; //via year starts in 1980, tm_year starts in 1900
105 tm.tm_mon = vd.month_e-1; // january is 0 in tm_mon
106 tm.tm_mday = vd.day_e;
107 end_t = cs_timegm(&tm);
108
109 cs_add_entitlement(reader, reader->caid, provid, cls, cls, start_t, end_t, 5);
110 }
111 }
112}
113
114static void show_subs(struct s_reader * reader, const uchar *emm)
115{
116 // emm -> A9, A6, B6
117
118 switch( emm[0] )
119 {
120 case 0xA9:
121 show_class(reader, "nano A9: ", 0, emm+2, emm[1]);
122 break;
123 /*
124 {
125 int32_t i, j, byts;
126 const uchar *oemm;
127
128 oemm = emm;
129 byts = emm[1]-4;
130 emm+=6;
131
132 j=byts-1;
133 for( ; j>=0; j-- )
134 for( i=0; i<8; i++ )
135 if( emm[j] & (1 << (i&7)) )
136 {
137 uchar cls;
138 struct via_date vd;
139 parse_via_date(emm-4, &vd, 1);
140 cls=(byts-(j+1))*8+i;
141 rdr_log(reader, "%sclass %02X: expiry date: %02d/%02d/%04d - %02d/%02d/%04d",
142 fnano?"nano A9: ":"", cls,
143 vd.day_s, vd.month_s, vd.year_s+1980,
144 vd.day_e, vd.month_e, vd.year_e+1980);
145 }
146 break;
147 }
148 */
149 case 0xA6:
150 {
151 char szGeo[256];
152
153 memset(szGeo, 0, 256);
154 strncpy(szGeo, (char *)emm+2, emm[1]);
155 rdr_log(reader, "nano A6: geo %s", szGeo);
156 break;
157 }
158 case 0xB6:
159 {
160 uchar m; // modexp
161 struct via_date vd;
162
163 m=emm[emm[1]+1];
164 parse_via_date(emm+2, &vd, 0);
165 rdr_log(reader, "nano B6: modexp %d%d%d%d%d%d: %02d/%02d/%04d", (m&0x20)?1:0,
166 (m&0x10)?1:0,(m&0x08)?1:0,(m&0x04)?1:0,(m&0x02)?1:0,(m&0x01)?1:0,
167 vd.day_s, vd.month_s, vd.year_s+1980);
168 break;
169 }
170 }
171}
172
173static int32_t chk_prov(struct s_reader * reader, uchar *id, uchar keynr)
174{
175 int32_t i, j, rc;
176 for (rc=i=0; (!rc) && (i<reader->nprov); i++)
177 if(!memcmp(&reader->prid[i][1], id, 3))
178 for (j=0; (!rc) && (j<16); j++)
179 if (reader->availkeys[i][j]==keynr)
180 rc=1;
181 return(rc);
182}
183
184static int32_t unlock_parental(struct s_reader * reader)
185{
186 /* disabling parental lock. assuming pin "0000" if no pin code is provided in the config */
187
188 static const uchar inDPL[] = {0xca, 0x24, 0x02, 0x00, 0x09};
189 uchar cmDPL[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F};
190 def_resp;
191
192 if (strcmp(reader->pincode, "none")) {
193 rdr_log(reader, "Using PIN %s",reader->pincode);
194 // the pin need to be coded in bcd, so we need to convert from ascii to bcd, so '1234' -> 0x12 0x34
195 cmDPL[6]=((reader->pincode[0]-0x30)<<4) | ((reader->pincode[1]-0x30) & 0x0f);
196 cmDPL[7]=((reader->pincode[2]-0x30)<<4) | ((reader->pincode[3]-0x30) & 0x0f);
197 }
198 else {
199 rdr_log(reader, "Using PIN 0000!");
200 }
201 write_cmd(inDPL,cmDPL);
202 if( !(cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0) ) {
203 if (strcmp(reader->pincode, "none")) {
204 rdr_log(reader, "Can't disable parental lock. Wrong PIN? OSCam used %s!",reader->pincode);
205 }
206 else {
207 rdr_log(reader, "Can't disable parental lock. Wrong PIN? OSCam used 0000!");
208 }
209 }
210 else
211 rdr_log(reader, "Parental lock disabled");
212
213 return 0;
214}
215
216static int32_t viaccess_card_init(struct s_reader * reader, ATR *newatr)
217{
218 get_atr;
219 def_resp;
220 int32_t i;
221 uchar buf[256];
222 uchar insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
223 uchar insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
224 uchar insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
225 uchar insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
226 static const uchar insFAC[] = { 0x87, 0x02, 0x00, 0x00, 0x03 }; // init FAC
227 static const uchar FacDat[] = { 0x00, 0x00, 0x28 };
228 static unsigned char ins8702_data[] = { 0x00, 0x00, 0x11};
229 static unsigned char ins8704[] = { 0x87, 0x04, 0x00, 0x00, 0x07 };
230 static unsigned char ins8706[] = { 0x87, 0x06, 0x00, 0x00, 0x04 };
231
232
233 if ((atr[1]!=0x77) || ((atr[2]!=0x18) && (atr[2]!=0x11) && (atr[2]!=0x19)) || ((atr[9]!=0x68) && (atr[9]!=0x6C)))
234 return ERROR;
235
236 write_cmd(insFAC, FacDat);
237 if( !(cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0) )
238 return ERROR;
239
240 memset(&reader->last_geo, 0, sizeof(reader->last_geo));
241 write_cmd(insFAC, ins8702_data);
242 if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) {
243 write_cmd(ins8704, NULL);
244 if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) {
245 write_cmd(ins8706, NULL);
246 if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) {
247 reader->last_geo.number_ecm =(cta_res[2]<<8) | (cta_res[3]);
248 rdr_log(reader, "using ecm #%x for long viaccess ecm",reader->last_geo.number_ecm);
249 }
250 }
251 }
252
253
254 // switch((atr[atrsize-4]<<8)|atr[atrsize-3])
255 // {
256 // case 0x6268: ver="2.3"; break;
257 // case 0x6668: ver="2.4(?)"; break;
258 // case 0xa268:
259 // default: ver="unknown"; break;
260 // }
261
262 reader->caid=0x500;
263 memset(reader->prid, 0xff, sizeof(reader->prid));
264 insac[2]=0xa4; write_cmd(insac, NULL); // request unique id
265 insb8[4]=0x07; write_cmd(insb8, NULL); // read unique id
266 memcpy(reader->hexserial, cta_res+2, 5);
267 // rdr_log(reader, "[viaccess-reader] type: Viaccess, ver: %s serial: %llu", ver, b2ll(5, cta_res+2));
268 rdr_log_sensitive(reader, "type: Viaccess (%sstandard atr), caid: %04X, serial: {%llu}",
269 atr[9]==0x68?"":"non-",reader->caid, (unsigned long long) b2ll(5, cta_res+2));
270
271 i=0;
272 insa4[2]=0x00; write_cmd(insa4, NULL); // select issuer 0
273 buf[0]=0;
274 while((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0))
275 {
276 insc0[4]=0x1a; write_cmd(insc0, NULL); // show provider properties
277 cta_res[2]&=0xF0;
278 reader->prid[i][0]=0;
279 memcpy(&reader->prid[i][1], cta_res, 3);
280 memcpy(&reader->availkeys[i][0], cta_res+10, 16);
281 snprintf((char *)buf+strlen((char *)buf), sizeof(buf)-strlen((char *)buf), ",%06X", b2i(3, &reader->prid[i][1]));
282 //rdr_log(reader, "[viaccess-reader] buf: %s", buf);
283
284 insac[2]=0xa5; write_cmd(insac, NULL); // request sa
285 insb8[4]=0x06; write_cmd(insb8, NULL); // read sa
286 memcpy(&reader->sa[i][0], cta_res+2, 4);
287
288 /*
289 insac[2]=0xa7; write_cmd(insac, NULL); // request name
290 insb8[4]=0x02; write_cmd(insb8, NULL); // read name nano + len
291 l=cta_res[1];
292 insb8[4]=l; write_cmd(insb8, NULL); // read name
293 cta_res[l]=0;
294 rdr_log(reader, "[viaccess-reader] name: %s", cta_res);
295 */
296
297 insa4[2]=0x02;
298 write_cmd(insa4, NULL); // select next issuer
299 i++;
300 }
301 reader->nprov=i;
302 rdr_log(reader, "providers: %d (%s)", reader->nprov, buf+1);
303
304 if (cfg.ulparent)
305 unlock_parental(reader);
306
307 rdr_log(reader, "ready for requests");
308 return OK;
309}
310
311bool dcw_crc(uchar *dw){
312 int8_t i;
313 for(i=0;i<16;i+=4) if(dw[i+3]!=((dw[i]+dw[i+1]+dw[i+2])& 0xFF))return 0;
314 return 1;
315}
316
317static int32_t viaccess_do_ecm(struct s_reader * reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
318{
319 def_resp;
320 static const unsigned char insa4[] = { 0xca,0xa4,0x04,0x00,0x03 }; // set provider id
321 unsigned char ins88[] = { 0xca,0x88,0x00,0x00,0x00 }; // set ecm
322 unsigned char insf8[] = { 0xca,0xf8,0x00,0x00,0x00 }; // set geographic info
323 static const unsigned char insc0[] = { 0xca,0xc0,0x00,0x00,0x12 }; // read dcw
324
325 // //XXX what is the 4th byte for ??
326 int32_t ecm88Len = MIN(MAX_ECM_SIZE-4, SCT_LEN(er->ecm)-4);
327 if(ecm88Len < 1){
328 rdr_log(reader, "ECM: Size of ECM couldn't be correctly calculated.");
329 return ERROR;
330 }
331 uchar ecmData[ecm88Len];
332 memset(ecmData, 0, ecm88Len);
333 memcpy(ecmData, er->ecm+4, ecm88Len);
334 uchar *ecm88Data = &ecmData[0];
335 uint32_t provid=0;
336 int32_t rc=0;
337 int32_t hasD2 = 0;
338 int32_t curEcm88len=0;
339 int32_t nanoLen=0;
340 uchar *nextEcm;
341 uchar DE04[256];
342 int32_t D2KeyID=0;
343 int32_t curnumber_ecm=0;
344 //nanoD2 d2 02 0d 02 -> D2 nano, len 2
345 // 0d -> post AES decrypt CW
346 // 0b -> pre AES decrypt CW
347 int32_t nanoD2 = 0; // 0x0b = 1 0x0d = 2
348
349 memset(DE04, 0, sizeof(DE04)); //fix dorcel de04 bug
350
351 nextEcm=ecm88Data;
352
353
354
355 while (ecm88Len>0 && !rc) {
356
357 if(ecm88Data[0] ==0x00 && ecm88Data[1] == 0x00) {
358 // nano 0x00 and len 0x00 aren't valid ... something is obviously wrong with this ecm.
359 rdr_log(reader, "ECM: Invalid ECM structure. Rejecting");
360 return ERROR;
361 }
362
363 // 80 33 nano 80 (ecm) + len (33)
364 if(ecm88Data[0]==0x80) { // nano 80, give ecm len
365 curEcm88len=ecm88Data[1];
366 nextEcm=ecm88Data+curEcm88len+2;
367 ecm88Data += 2;
368 ecm88Len -= 2;
369 }
370
371 if(!curEcm88len) { //there was no nano 80 -> simple ecm
372 curEcm88len=ecm88Len;
373 }
374
375 // d2 02 0d 02 -> D2 nano, len 2, select the AES key to be used
376 if(ecm88Data[0]==0xd2) {
377 // test if need post or pre AES decrypt
378 if(ecm88Data[2]==0x0b)
379 {
380 nanoD2 = 1;
381 rdr_debug_mask(reader, D_READER, "ECM: nano D2 0x0b");
382 }
383 if(ecm88Data[2]==0x0d)
384 {
385 nanoD2 = 2;
386 rdr_debug_mask(reader, D_READER, "ECM: nano D2 0x0d");
387 }
388 // use the d2 arguments to get the key # to be used
389 int32_t len = ecm88Data[1] + 2;
390 D2KeyID=ecm88Data[3];
391 ecm88Data += len;
392 ecm88Len -= len;
393 curEcm88len -=len;
394 hasD2 = 1;
395 }
396 else
397 hasD2 = 0;
398
399
400 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here
401 // 09 -> use key #9
402 // 05 67 00
403 if ((ecm88Data[0]==0x90 || ecm88Data[0]==0x40) && (ecm88Data[1]==0x03 || ecm88Data[1]==0x07 ) )
404 {
405 uchar ident[3], keynr;
406 uchar *ecmf8Data=0;
407 int32_t ecmf8Len=0;
408
409 nanoLen=ecm88Data[1] + 2;
410 keynr=ecm88Data[4]&0x0F;
411
412 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here
413 // 09 -> use key #9
414 if(nanoLen>5) {
415 curnumber_ecm =(ecm88Data[6]<<8) | (ecm88Data[7]);
416 rdr_debug_mask(reader, D_READER, "checking if the ecm number (%x) match the card one (%x)",curnumber_ecm,reader->last_geo.number_ecm);
417 // if we have an ecm number we check it.
418 // we can't assume that if the nano len is 5 or more we have an ecm number
419 // as some card don't support this
420 if( reader->last_geo.number_ecm > 0 ) {
421 if (reader->last_geo.number_ecm == curnumber_ecm && !( ecm88Data[nanoLen-1] == 0x01 && (ecm88Data[2] == 0x03 && ecm88Data[3] == 0x0B && ecm88Data[4] == 0x00 ) )) {
422 keynr=ecm88Data[5];
423 rdr_debug_mask(reader, D_READER, "keyToUse = %02x, ECM ending with %02x",ecm88Data[5], ecm88Data[nanoLen-1]);
424 } else {
425 if( ecm88Data[nanoLen-1] == 0x01 && (ecm88Data[2] == 0x03 && ecm88Data[3] == 0x0B && ecm88Data[4] == 0x00 ) )
426 {
427 rdr_debug_mask(reader, D_READER, "Skip ECM ending with = %02x for ecm number (%x) for provider %02x%02x%02x",ecm88Data[nanoLen-1], curnumber_ecm, ecm88Data[2], ecm88Data[3], ecm88Data[4]);
428 }
429 rdr_debug_mask(reader, D_READER, "Skip ECM ending with = %02x for ecm number (%x)",ecm88Data[nanoLen-1], curnumber_ecm);
430 ecm88Data=nextEcm;
431 ecm88Len-=curEcm88len;
432 continue; //loop to next ecm
433 }
434 }
435 else { // long ecm but we don't have an ecm number so we have to try them all.
436 keynr=ecm88Data[5];
437 rdr_debug_mask(reader, D_READER, "keyToUse = %02x",ecm88Data[5]);
438 }
439 }
440
441 memcpy (ident, &ecm88Data[2], sizeof(ident));
442 provid = b2i(3, ident);
443 ident[2]&=0xF0;
444
445 if(hasD2 && reader->aes_list) {
446 // check that we have the AES key to decode the CW
447 // if not there is no need to send the ecm to the card
448 if(!aes_present(reader->aes_list, 0x500, (uint32_t) (provid & 0xFFFFF0) , D2KeyID))
449 return ERROR;
450 }
451
452
453 if (!chk_prov(reader, ident, keynr))
454 {
455 rdr_debug_mask(reader, D_READER, "ECM: provider or key not found on card");
456 snprintf( ea->msglog, MSGLOGSIZE, "provider(%02x%02x%02x) or key(%d) not found on card", ident[0],ident[1],ident[2], keynr );
457 return ERROR;
458 }
459
460 ecm88Data+=nanoLen;
461 ecm88Len-=nanoLen;
462 curEcm88len-=nanoLen;
463
464 // DE04
465 if (ecm88Data[0]==0xDE && ecm88Data[1]==0x04)
466 {
467 memcpy (DE04, &ecm88Data[0], 6);
468 ecm88Data+=6;
469 }
470 //
471
472 if( reader->last_geo.provid != provid )
473 {
474 reader->last_geo.provid = provid;
475 reader->last_geo.geo_len = 0;
476 reader->last_geo.geo[0] = 0;
477 write_cmd(insa4, ident); // set provider
478 }
479
480 //Nano D2 0x0b Pre AES decrypt CW
481 if ( hasD2 && nanoD2 == 1)
482 {
483 uchar *ecm88DataCW = ecm88Data;
484 int32_t cwStart = 0;
485 //int32_t cwStartRes = 0;
486 int32_t must_exit = 0;
487 // find CW start
488 while(cwStart < curEcm88len -1 && !must_exit)
489 {
490 if(ecm88Data[cwStart] == 0xEA && ecm88Data[cwStart+1] == 0x10)
491 {
492 ecm88DataCW = ecm88DataCW + cwStart + 2;
493 must_exit = 1;
494 }
495 cwStart++;
496 }
497 // use AES from list to decrypt CW
498 rdr_debug_mask(reader, D_READER, "Decoding CW : using AES key id %d for provider %06x",D2KeyID, (provid & 0xFFFFF0));
499 if (aes_decrypt_from_list(reader->aes_list,0x500, (uint32_t) (provid & 0xFFFFF0), D2KeyID, &ecm88DataCW[0], 16) == 0)
500 snprintf( ea->msglog, MSGLOGSIZE, "AES Decrypt : key id %d not found for CAID %04X , provider %06x", D2KeyID, 0x500, (provid & 0xFFFFF0) );
501 }
502
503 while(ecm88Len>1 && ecm88Data[0]<0xA0)
504 {
505 nanoLen=ecm88Data[1]+2;
506 if (!ecmf8Data)
507 ecmf8Data=(uchar *)ecm88Data;
508 ecmf8Len+=nanoLen;
509 ecm88Len-=nanoLen;
510 curEcm88len-=nanoLen;
511 ecm88Data+=nanoLen;
512 }
513 if(ecmf8Len)
514 {
515 if( reader->last_geo.geo_len!=ecmf8Len ||
516 memcmp(reader->last_geo.geo, ecmf8Data, reader->last_geo.geo_len))
517 {
518 memcpy(reader->last_geo.geo, ecmf8Data, ecmf8Len);
519 reader->last_geo.geo_len= ecmf8Len;
520 insf8[3]=keynr;
521 insf8[4]=ecmf8Len;
522 write_cmd(insf8, ecmf8Data);
523 }
524 }
525 ins88[2]=ecmf8Len?1:0;
526 ins88[3]=keynr;
527 ins88[4]= curEcm88len;
528 //
529 // we should check the nano to make sure the ecm is valid
530 // we should look for at least 1 E3 nano, 1 EA nano and the F0 signature nano
531 //
532 // DE04
533 if (DE04[0]==0xDE)
534 {
535 uint32_t l = curEcm88len-6;
536 if (l > 256 || curEcm88len <= 6) { //don't known if this is ok...
537 rdr_log(reader, "ecm invalid/too long! len=%d", curEcm88len);
538 return ERROR;
539 }
540 memcpy(DE04+6, (uchar *)ecm88Data, l);
541 write_cmd(ins88, DE04); // request dcw
542 }
543 else
544 {
545 write_cmd(ins88, (uchar *)ecm88Data); // request dcw
546 }
547 //
548 write_cmd(insc0, NULL); // read dcw
549 switch(cta_res[0])
550 {
551 case 0xe8: // even
552 if(cta_res[1]==8) { memcpy(ea->cw,cta_res+2,8); rc=1; }
553 break;
554 case 0xe9: // odd
555 if(cta_res[1]==8) { memcpy(ea->cw+8,cta_res+2,8); rc=1; }
556 break;
557 case 0xea: // complete
558 if(cta_res[1]==16) { memcpy(ea->cw,cta_res+2,16); rc=1; }
559 break;
560 default :
561 ecm88Data=nextEcm;
562 ecm88Len-=curEcm88len;
563 rdr_debug_mask(reader, D_READER, "ECM: key to use is not the current one, trying next ECM");
564 snprintf( ea->msglog, MSGLOGSIZE, "key to use is not the current one, trying next ECM" );
565 }
566 }
567 else {
568 //ecm88Data=nextEcm;
569 //ecm88Len-=curEcm88len;
570 rdr_debug_mask(reader, D_READER, "ECM: Unknown ECM type");
571 snprintf( ea->msglog, MSGLOGSIZE, "Unknown ECM type" );
572 return ERROR; /*Lets interupt the loop and exit, because we don't know this ECM type.*/
573 }
574 }
575
576 if ( hasD2 && !dcw_crc(ea->cw) && nanoD2 == 2) {
577 rdr_debug_mask(reader, D_READER, "Decoding CW : using AES key id %d for provider %06x",D2KeyID, (provid & 0xFFFFF0));
578 rc=aes_decrypt_from_list(reader->aes_list,0x500, (uint32_t) (provid & 0xFFFFF0), D2KeyID,ea->cw, 16);
579 if( rc == 0 )
580 snprintf( ea->msglog, MSGLOGSIZE, "AES Decrypt : key id %d not found for CAID %04X , provider %06x", D2KeyID, 0x500, (provid & 0xFFFFF0) );
581 }
582
583 return(rc?OK:ERROR);
584}
585
586static int32_t viaccess_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr)
587{
588 uint32_t provid=0;
589 rdr_debug_mask(rdr, D_EMM, "Entered viaccess_get_emm_type ep->emm[0]=%02x",ep->emm[0]);
590
591 if (ep->emm[3] == 0x90 && ep->emm[4] == 0x03) {
592 provid = ep->emm[5] << 16 | ep->emm[6] << 8 | (ep->emm[7] & 0xFE);
593 i2b_buf(4, provid, ep->provid);
594 }
595
596 switch (ep->emm[0]) {
597case 0x88:
598 ep->type=UNIQUE;
599 memset(ep->hexserial, 0, 8);
600 memcpy(ep->hexserial, ep->emm + 4, 4);
601 rdr_debug_mask(rdr, D_EMM, "UNIQUE");
602 return(!memcmp(rdr->hexserial + 1, ep->hexserial, 4));
603
604case 0x8A:
605case 0x8B:
606 ep->type=GLOBAL;
607 rdr_debug_mask(rdr, D_EMM, "GLOBAL");
608 return 1;
609
610case 0x8C:
611case 0x8D:
612 ep->type=SHARED;
613 rdr_debug_mask(rdr, D_EMM, "SHARED (part)");
614 // We need those packets to pass otherwise we would never
615 // be able to complete EMM reassembly
616 return 1;
617
618case 0x8E:
619 ep->type=SHARED;
620 memset(ep->hexserial, 0, 8);
621 memcpy(ep->hexserial, ep->emm + 3, 3);
622 rdr_debug_mask(rdr, D_EMM, "SHARED");
623
624 //check for provider as serial (cccam only?)
625 int8_t i;
626 for (i=0;i<rdr->nprov;i++) {
627 if (!memcmp(&rdr->prid[i][1], ep->hexserial, 3))
628 return 1;
629 }
630 return(!memcmp(&rdr->sa[0][0], ep->hexserial, 3));
631
632default:
633 ep->type = UNKNOWN;
634 rdr_debug_mask(rdr, D_EMM, "UNKNOWN");
635 return 1;
636 }
637}
638
639static void viaccess_get_emm_filter(struct s_reader * rdr, uchar *filter)
640{
641 int32_t idx = 2;
642
643 filter[0]=0xFF;
644 filter[1]=0;
645
646 filter[idx++]=EMM_SHARED;
647 filter[idx++]=0;
648 filter[idx+0] = 0x8C;
649 filter[idx+0+16] = 0xFF;
650 filter[1]++;
651 idx += 32;
652
653 filter[idx++]=EMM_SHARED;
654 filter[idx++]=0;
655 filter[idx+0] = 0x8D;
656 filter[idx+0+16] = 0xFF;
657 filter[1]++;
658 idx += 32;
659
660 filter[idx++]=EMM_SHARED;
661 filter[idx++]=0;
662 filter[idx+0] = 0x8E;
663 filter[idx+0+16] = 0xFF;
664 memcpy(filter+idx+1, &rdr->sa[0][0], 3);
665 memset(filter+idx+1+16, 0xFF, 3);
666 filter[1]++;
667 idx += 32;
668
669 filter[idx++]=EMM_UNIQUE;
670 filter[idx++]=0;
671 filter[idx+0] = 0x88;
672 filter[idx+0+16] = 0xFF;
673 memcpy(filter+idx+1, rdr->hexserial + 1, 4);
674 memset(filter+idx+1+16, 0xFF, 4);
675 filter[1]++;
676
677 return;
678}
679
680static int32_t viaccess_do_emm(struct s_reader * reader, EMM_PACKET *ep)
681{
682 def_resp;
683 static const unsigned char insa4[] = { 0xca,0xa4,0x04,0x00,0x03 }; // set provider id
684 unsigned char insf0[] = { 0xca,0xf0,0x00,0x01,0x22 }; // set adf
685 unsigned char insf4[] = { 0xca,0xf4,0x00,0x01,0x00 }; // set adf, encrypted
686 unsigned char ins18[] = { 0xca,0x18,0x01,0x01,0x00 }; // set subscription
687 unsigned char ins1c[] = { 0xca,0x1c,0x01,0x01,0x00 }; // set subscription, encrypted
688 //static const unsigned char insc8[] = { 0xca,0xc8,0x00,0x00,0x02 }; // read extended status
689 // static const unsigned char insc8Data[] = { 0x00,0x00 }; // data for read extended status
690
691 int32_t emmdatastart=7;
692
693
694 if (ep->type == UNIQUE) emmdatastart++;
695 int32_t emmLen=SCT_LEN(ep->emm)-emmdatastart;
696 int32_t rc=0;
697
698 ///cs_dump(ep->emm, emmLen+emmdatastart, "RECEIVED EMM VIACCESS");
699
700 int32_t emmUpToEnd;
701 uchar *emmParsed = ep->emm+emmdatastart;
702 int32_t provider_ok = 0;
703 uint32_t emm_provid;
704 uchar keynr = 0;
705 int32_t ins18Len = 0;
706 uchar ins18Data[512];
707 uchar insData[512];
708 uchar *nano81Data = 0;
709 uchar *nano91Data = 0;
710 uchar *nano92Data = 0;
711 uchar *nano9EData = 0;
712 uchar *nanoF0Data = 0;
713
714 for (emmUpToEnd=emmLen; (emmParsed[1] != 0) && (emmUpToEnd > 0); emmUpToEnd -= (2 + emmParsed[1]), emmParsed += (2 + emmParsed[1])) {
715 ///cs_dump (emmParsed, emmParsed[1] + 2, "NANO");
716
717 if (emmParsed[0]==0x90 && emmParsed[1]==0x03) {
718 /* identification of the service operator */
719
720 uchar soid[3], ident[3], i;
721
722 for (i=0; i<3; i++) {
723 soid[i]=ident[i]=emmParsed[2+i];
724 }
725 ident[2]&=0xF0;
726 emm_provid=b2i(3, ident);
727 keynr=soid[2]&0x0F;
728 if (chk_prov(reader, ident, keynr)) {
729 provider_ok = 1;
730 } else {
731 rdr_log(reader, "EMM: provider or key not found on card (%x, %x)", emm_provid, keynr);
732 return ERROR;
733 }
734
735 // check if the provider changes. If yes, set the new one. If not, don't .. card will return an error if we do.
736 if( reader->last_geo.provid != emm_provid ) {
737 write_cmd(insa4, ident);
738 if( cta_res[cta_lr-2]!=0x90 || cta_res[cta_lr-1]!=0x00 ) {
739 cs_dump(insa4, 5, "set provider cmd:");
740 cs_dump(soid, 3, "set provider data:");
741 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]);
742 return ERROR;
743 }
744 }
745 // as we are maybe changing the used provider, clear the cache, so the next ecm will re-select the correct one
746 reader->last_geo.provid = 0;
747 reader->last_geo.geo_len = 0;
748 reader->last_geo.geo[0] = 0;
749
750 }
751 else if (emmParsed[0]==0x9e && emmParsed[1]==0x20) {
752 /* adf */
753
754 if (!nano91Data) {
755 /* adf is not crypted, so test it */
756
757 uchar custwp;
758 uchar *afd;
759
760 custwp=reader->sa[0][3];
761 afd=(uchar*)emmParsed+2;
762
763 if( afd[31-custwp/8] & (1 << (custwp & 7)) )
764 rdr_debug_mask(reader, D_READER, "emm for our card %08X", b2i(4, &reader->sa[0][0]));
765 else
766 return SKIPPED;
767 }
768
769 // memorize
770 nano9EData = emmParsed;
771
772 } else if (emmParsed[0]==0x81) {
773 nano81Data = emmParsed;
774 } else if (emmParsed[0]==0x91 && emmParsed[1]==0x08) {
775 nano91Data = emmParsed;
776 } else if (emmParsed[0]==0x92 && emmParsed[1]==0x08) {
777 nano92Data = emmParsed;
778 } else if (emmParsed[0]==0xF0 && emmParsed[1]==0x08) {
779 nanoF0Data = emmParsed;
780 } else {
781 /* other nanos */
782 show_subs(reader, emmParsed);
783
784 memcpy(ins18Data+ins18Len, emmParsed, emmParsed[1] + 2);
785 ins18Len += emmParsed [1] + 2;
786 }
787 }
788
789 if (!provider_ok) {
790 rdr_debug_mask(reader, D_READER, "provider not found in emm, continue anyway");
791 // force key to 1...
792 keynr = 1;
793 ///return ERROR;
794 }
795
796 if (!nanoF0Data) {
797 cs_dump(ep->emm, ep->emmlen, "can't find 0xf0 in emm...");
798 return ERROR; // error
799 }
800
801 if (nano9EData) {
802 if (!nano91Data) {
803 // set adf
804 insf0[3] = keynr; // key
805 insf0[4] = nano9EData[1] + 2;
806 write_cmd(insf0, nano9EData);
807 if( cta_res[cta_lr-2]!=0x90 || cta_res[cta_lr-1]!=0x00 ) {
808 cs_dump(insf0, 5, "set adf cmd:");
809 cs_dump(nano9EData, insf0[4] , "set adf data:");
810 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]);
811 return ERROR;
812 }
813 } else {
814 // set adf crypte
815 insf4[3] = keynr; // key
816 insf4[4] = nano91Data[1] + 2 + nano9EData[1] + 2;
817 memcpy (insData, nano91Data, nano91Data[1] + 2);
818 memcpy (insData + nano91Data[1] + 2, nano9EData, nano9EData[1] + 2);
819 write_cmd(insf4, insData);
820 if(( cta_res[cta_lr-2]!=0x90 && cta_res[cta_lr-2]!=0x91) || cta_res[cta_lr-1]!=0x00 ) {
821 cs_dump(insf4, 5, "set adf encrypted cmd:");
822 cs_dump(insData, insf4[4], "set adf encrypted data:");
823 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]);
824 return ERROR;
825 }
826 }
827 }
828
829 if (!nano92Data) {
830 // send subscription
831 ins18[2] = nano9EData ? 0x01: 0x00; // found 9E nano ?
832 ins18[3] = keynr; // key
833 ins18[4] = ins18Len + nanoF0Data[1] + 2;
834 memcpy (insData, ins18Data, ins18Len);
835 memcpy (insData + ins18Len, nanoF0Data, nanoF0Data[1] + 2);
836 write_cmd(ins18, insData);
837 if( (cta_res[cta_lr-2]==0x90 || cta_res[cta_lr-2]==0x91) && cta_res[cta_lr-1]==0x00 ) {
838 rdr_debug_mask(reader, D_READER, "update successfully written");
839 rc=1; // written
840 } else {
841 cs_dump(ins18, 5, "set subscription cmd:");
842 cs_dump(insData, ins18[4], "set subscription data:");
843 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]);
844 }
845
846 } else {
847 // send subscription encrypted
848
849 if (!nano81Data) {
850 cs_dump(ep->emm, ep->emmlen, "0x92 found, but can't find 0x81 in emm...");
851 return ERROR; // error
852 }
853
854 ins1c[2] = nano9EData ? 0x01: 0x00; // found 9E nano ?
855 if (ep->type == UNIQUE) ins1c[2] = 0x02;
856 ins1c[3] = keynr; // key
857 ins1c[4] = nano92Data[1] + 2 + nano81Data[1] + 2 + nanoF0Data[1] + 2;
858 memcpy (insData, nano92Data, nano92Data[1] + 2);
859 memcpy (insData + nano92Data[1] + 2, nano81Data, nano81Data[1] + 2);
860 memcpy (insData + nano92Data[1] + 2 + nano81Data[1] + 2, nanoF0Data, nanoF0Data[1] + 2);
861 write_cmd(ins1c, insData);
862
863 if( (cta_res[cta_lr-2]==0x90 || cta_res[cta_lr-2]==0x91) &&
864 (cta_res[cta_lr-1]==0x00 || cta_res[cta_lr-1]==0x08) ) {
865 rdr_log(reader, "update successfully written");
866 rc=1; // written
867 }
868 rc=1;
869 /* don't return ERROR at this place
870 else {
871 if( cta_res[cta_lr-2]&0x1 )
872 rdr_log(reader, "update not written. Data already exists or unknown address");
873
874 //if( cta_res[cta_lr-2]&0x8 ) {
875 write_cmd(insc8, NULL);
876 if( (cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0x00) ) {
877 rdr_log(reader, "extended status %02X %02X", cta_res[0], cta_res[1]);
878 }
879 //}
880 return ERROR;
881 } */
882
883 }
884
885 /*
886 Sub Main()
887 Sc.Write("CA A4 04 00 03")
888 RX
889 Sc.Write("02 07 11")
890 RX
891 Sc.Write("CA F0 00 01 22")
892 RX
893 Sc.Write("9E 20")
894 Sc.Write("10 10 08 8A 80 00 04 00 10 10 26 E8 54 80 1E 80")
895 Sc.Write("00 01 00 00 00 00 00 50 00 00 80 02 22 00 08 50")
896 RX
897 Sc.Write("CA 18 01 01 11")
898 RX
899 Sc.Write("A9 05 34 DE 34 FF 80")
900 Sc.Write("F0 08 1A 3E AF B5 2B EE E3 3B")
901 RX
902
903 End Sub
904 */
905 return rc;
906}
907
908static int32_t viaccess_card_info(struct s_reader * reader)
909{
910 def_resp;
911 int32_t i, l;
912 uchar insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
913 uchar insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
914 uchar insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
915 uchar insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
916 static const uchar ins24[] = { 0xca, 0x24, 0x00, 0x00, 0x09 }; // set pin
917
918 static const uchar cls[] = { 0x00, 0x21, 0xff, 0x9f};
919 static const uchar pin[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
920
921 reader->last_geo.provid = 0;
922 reader->last_geo.geo_len = 0;
923 reader->last_geo.geo[0] = 0;
924
925 rdr_log(reader, "card detected");
926
927 cs_clear_entitlement(reader); //reset the entitlements
928
929 // set pin
930 write_cmd(ins24, pin);
931
932 insac[2]=0xa4; write_cmd(insac, NULL); // request unique id
933 insb8[4]=0x07; write_cmd(insb8, NULL); // read unique id
934 rdr_log_sensitive(reader, "serial: {%llu}", (unsigned long long) b2ll(5, cta_res+2));
935
936 insa4[2]=0x00; write_cmd(insa4, NULL); // select issuer 0
937 for (i=1; (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0); i++)
938 {
939 uint32_t l_provid, l_sa;
940 uchar l_name[64];
941 insc0[4]=0x1a; write_cmd(insc0, NULL); // show provider properties
942 cta_res[2]&=0xF0;
943 l_provid=b2i(3, cta_res);
944
945 insac[2]=0xa5; write_cmd(insac, NULL); // request sa
946 insb8[4]=0x06; write_cmd(insb8, NULL); // read sa
947 l_sa=b2i(4, cta_res+2);
948
949 insac[2]=0xa7; write_cmd(insac, NULL); // request name
950 insb8[4]=0x02; write_cmd(insb8, NULL); // read name nano + len
951 l=cta_res[1];
952 insb8[4]=l; write_cmd(insb8, NULL); // read name
953 cta_res[l]=0;
954 trim((char *)cta_res);
955 if (cta_res[0])
956 snprintf((char *)l_name, sizeof(l_name), ", name: %s", cta_res);
957 else
958 l_name[0]=0;
959
960 // read GEO
961 insac[2]=0xa6; write_cmd(insac, NULL); // request GEO
962 insb8[4]=0x02; write_cmd(insb8, NULL); // read GEO nano + len
963 l=cta_res[1];
964 char tmp[l*3+1];
965 insb8[4]=l; write_cmd(insb8, NULL); // read geo
966 rdr_log_sensitive(reader, "provider: %d, id: {%06X%s}, sa: {%08X}, geo: %s",
967 i, l_provid, l_name, l_sa, (l<4) ? "empty" : cs_hexdump(1, cta_res, l, tmp, sizeof(tmp)));
968
969 // read classes subscription
970 insac[2]=0xa9; insac[4]=4;
971 write_cmd(insac, cls); // request class subs
972 while( (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0) )
973 {
974 insb8[4]=0x02; write_cmd(insb8, NULL); // read class subs nano + len
975 if( (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0) )
976 {
977 l=cta_res[1];
978 insb8[4]=l; write_cmd(insb8, NULL); // read class subs
979 if( (cta_res[cta_lr-2]==0x90) &&
980 (cta_res[cta_lr-1]==0x00 || cta_res[cta_lr-1]==0x08) )
981 {
982 show_class(reader, NULL, l_provid, cta_res, cta_lr-2);
983 }
984 }
985 }
986
987 insac[4]=0;
988 insa4[2]=0x02;
989 write_cmd(insa4, NULL); // select next provider
990 }
991 //return ERROR;
992 return OK;
993}
994
995static bool viaccess_reassemble_emm(struct s_reader *reader, EMM_PACKET *ep)
996{
997 uint8_t *buffer = ep->emm;
998 int16_t *len = &ep->emmlen;
999 int32_t pos=0, i;
1000 int16_t k;
1001
1002 // Viaccess
1003 if (*len>500) return 0;
1004
1005 switch(buffer[0]) {
1006 case 0x8c:
1007 case 0x8d:
1008 // emm-s part 1
1009 if (!memcmp(reader->reassemble_emm, buffer, *len))
1010 return 0;
1011
1012 // copy first part of the emm-s
1013 memcpy(reader->reassemble_emm, buffer, *len);
1014 reader->reassemble_emm_len=*len;
1015 //cs_ddump_mask(D_READER, buffer, len, "viaccess global emm:");
1016 break;
1017
1018 case 0x8e:
1019 // emm-s part 2
1020 if (!reader->reassemble_emm_len) return 1;
1021
1022 //extract nanos from emm-gh and emm-s
1023 uchar emmbuf[512];
1024
1025 cs_debug_mask(D_DVBAPI, "[viaccess] %s: start extracting nanos", __func__);
1026 //extract from emm-gh
1027 for (i=3; i<reader->reassemble_emm_len; i+=reader->reassemble_emm[i+1]+2) {
1028 //copy nano (length determined by i+1)
1029 memcpy(emmbuf+pos, reader->reassemble_emm+i, reader->reassemble_emm[i+1]+2);
1030 pos+=reader->reassemble_emm[i+1]+2;
1031 }
1032
1033 if (buffer[2]==0x2c) {
1034 //add 9E 20 nano + first 32 bytes of emm content
1035 memcpy(emmbuf+pos, "\x9E\x20", 2);
1036 memcpy(emmbuf+pos+2, buffer+7, 32);
1037 pos+=34;
1038
1039 //add F0 08 nano + 8 subsequent bytes of emm content
1040 memcpy(emmbuf+pos, "\xF0\x08", 2);
1041 memcpy(emmbuf+pos+2, buffer+39, 8);
1042 pos+=10;
1043 } else {
1044 //extract from variable emm-s
1045 for (k=7; k<(*len); k+=buffer[k+1]+2) {
1046 //copy nano (length determined by k+1)
1047 memcpy(emmbuf+pos, buffer+k, buffer[k+1]+2);
1048 pos+=buffer[k+1]+2;
1049 }
1050 }
1051
1052 cs_ddump_mask(D_DVBAPI, buffer, *len, "[viaccess] %s: %s emm-s", __func__, (buffer[2]==0x2c) ? "fixed" : "variable");
1053
1054 emm_sort_nanos(buffer+7, emmbuf, pos);
1055 pos+=7;
1056
1057 //calculate emm length and set it on position 2
1058 buffer[2]=pos-3;
1059
1060 cs_ddump_mask(D_DVBAPI, reader->reassemble_emm, reader->reassemble_emm_len, "[viaccess] %s: emm-gh", __func__);
1061 cs_ddump_mask(D_DVBAPI, buffer, pos, "[viaccess] %s: assembled emm", __func__);
1062
1063 *len=pos;
1064 break;
1065 }
1066 return 1;
1067}
1068
1069void reader_viaccess(struct s_cardsystem *ph)
1070{
1071 ph->do_emm_reassembly=viaccess_reassemble_emm;
1072 ph->do_emm=viaccess_do_emm;
1073 ph->do_ecm=viaccess_do_ecm;
1074 ph->card_info=viaccess_card_info;
1075 ph->card_init=viaccess_card_init;
1076 ph->get_emm_type=viaccess_get_emm_type;
1077 ph->get_emm_filter=viaccess_get_emm_filter;
1078 ph->caids[0]=0x05;
1079 ph->desc="viaccess";
1080}
1081#endif
Note: See TracBrowser for help on using the repository browser.