source: trunk/reader-cryptoworks.c@ 8377

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

cryptoworks/viaccess: Run EMM reassembly before writing EMM in the card.

Before this patch EMM reassembly was only run by the dvbapi client.

This means that any other client (via newcamd, cs378x, cccam) was
expected to perform its own EMM reassembly otherwise the card
was unable to write the EMMs that needed preprocessing (reassemblation).

This commit moves EMM reassembly where it belongs - just before the
EMM is written in the card. That simplifies client logic (no more
knowledge of EMM structure and types) and allows cards to be updated
via any network protocol as long as the client is not trying to be
smart and just sends us all EMM packets.

The changes were tested with SRG Swiss Viacess card and Digiturk
Cryptoworks card. In the both cards shared EMMs were written OK
while receiving them via cs378x protocol and tsdecrypt as client.

If a client sends already reassembled EMMs it also works.

  • Property svn:eol-style set to LF
File size: 22.8 KB
Line 
1#include "globals.h"
2#ifdef READER_CRYPTOWORKS
3#include "oscam-config.h"
4#include "oscam-emm.h"
5#include "reader-common.h"
6
7#define CMD_LEN 5
8
9static const char *cs_cert = "oscam.cert";
10
11static int search_boxkey(uint16_t caid, char *key)
12{
13 int i, rc = 0;
14 FILE *fp;
15 char c_caid[512];
16
17 fp = fopen(get_config_filename(c_caid, sizeof(c_caid), cs_cert), "r");
18 if (fp) {
19 for (; (!rc) && fgets(c_caid, sizeof(c_caid), fp);) {
20 char *c_provid, *c_key;
21
22 c_provid = strchr(c_caid, '#');
23 if (c_provid)
24 *c_provid = '\0';
25 if (!(c_provid = strchr(c_caid, ':')))
26 continue;
27 *c_provid++ ='\0';
28 if (!(c_key = strchr(c_provid, ':')))
29 continue;
30 *c_key++ ='\0';
31 if (word_atob(trim(c_caid))!=caid)
32 continue;
33 if ((i=(strlen(trim(c_key))>>1)) > 256)
34 continue;
35 if (cs_atob((uchar *)key, c_key, i) < 0) {
36 cs_log("wrong key in \"%s\"", cs_cert);
37 continue;
38 }
39 rc = 1;
40 }
41 fclose(fp);
42 }
43 return rc;
44}
45
46static void RotateBytes1(unsigned char *out, unsigned char *in, int32_t n)
47{
48 // loop is executed atleast once, so it's not a good idea to
49 // call with n=0 !!
50 out+=n;
51 do { *(--out)=*(in++); } while(--n);
52}
53
54static void RotateBytes2(unsigned char *in, int32_t n)
55{
56 // loop is executed atleast once, so it's not a good idea to
57 // call with n=0 !!
58 unsigned char *e=in+n-1;
59 do
60 {
61 unsigned char temp=*in;
62 *in++=*e;
63 *e-- =temp;
64 } while(in<e);
65}
66
67static int32_t Input(BIGNUM *d, unsigned char *in, int32_t n, int32_t LE)
68{
69 if (LE)
70 {
71 unsigned char tmp[n];
72 RotateBytes1(tmp,in,n);
73 return(BN_bin2bn(tmp,n,d)!=0);
74 }
75 else
76 return(BN_bin2bn(in,n,d)!=0);
77}
78
79static int32_t Output(struct s_reader * reader, unsigned char *out, int32_t n, BIGNUM *r, int32_t LE)
80{
81 int32_t s=BN_num_bytes(r);
82 if (s>n)
83 {
84 unsigned char buff[s];
85 rdr_debug_mask(reader, D_READER, "rsa: RSA len %d > %d, truncating", s, n);
86 BN_bn2bin(r,buff);
87 memcpy(out,buff+s-n,n);
88 }
89 else if (s<n)
90 {
91 int32_t l=n-s;
92 rdr_debug_mask(reader, D_READER, "rsa: RSA len %d < %d, padding", s, n);
93 memset(out,0,l);
94 BN_bn2bin(r,out+l);
95 }
96 else
97 BN_bn2bin(r,out);
98 if (LE)
99 RotateBytes2(out,n);
100 return(s);
101}
102
103static int32_t cw_RSA(struct s_reader * reader, unsigned char *out, unsigned char *in, int32_t n, BIGNUM *exp, BIGNUM *mod, int32_t LE)
104{
105 int32_t rc=0;
106 BN_CTX *ctx;
107 BIGNUM *r, *d;
108 ctx=BN_CTX_new();
109 r=BN_new();
110 d=BN_new();
111 if (Input(d,in,n,LE))
112 {
113 if(BN_mod_exp(r,d,exp,mod,ctx))
114 rc=Output(reader, out,n,r,LE);
115 else
116 rdr_log(reader, "rsa: mod-exp failed");
117 }
118 BN_CTX_free(ctx);
119 BN_free(d);
120 BN_free(r);
121 return(rc);
122}
123
124static time_t chid_date(uchar *ptr, char *buf, int32_t l)
125{
126 time_t rc = 0;
127 struct tm timeinfo;
128 memset(&timeinfo, 0, sizeof(struct tm));
129 if (buf) {
130 timeinfo.tm_year = 90 + (ptr[0]>>1);
131 timeinfo.tm_mon = (((ptr[0]&1)<<3)|(ptr[1]>>5)) - 1;
132 timeinfo.tm_mday = ptr[1]&0x1f;
133 rc = mktime(&timeinfo);
134 strftime(buf, l, "%Y/%m/%d", &timeinfo);
135 }
136 return(rc);
137}
138
139
140static int32_t select_file(struct s_reader * reader, uchar f1, uchar f2, uchar * cta_res, uint16_t * p_cta_lr)
141{
142 uint16_t cta_lr;
143 uchar insA4[] = {0xA4, 0xA4, 0x00, 0x00, 0x02, 0x00, 0x00};
144 insA4[5]=f1;
145 insA4[6]=f2;
146 write_cmd(insA4, insA4+5); // select file
147 *p_cta_lr = cta_lr;
148 return((cta_res[0]==0x9f)&&(cta_res[1]==0x11));
149}
150
151static int32_t read_record(struct s_reader * reader, uchar rec, uchar * cta_res)
152{
153 uint16_t cta_lr;
154 uchar insA2[] = {0xA4, 0xA2, 0x00, 0x00, 0x01, 0x00};
155 uchar insB2[] = {0xA4, 0xB2, 0x00, 0x00, 0x00};
156
157 insA2[5]=rec;
158 write_cmd(insA2, insA2+5); // select record
159 if (cta_res[0]!=0x9f)
160 return(-1);
161 insB2[4]=cta_res[1]; // get len
162 write_cmd(insB2, NULL); // read record
163 if ((cta_res[cta_lr-2]!=0x90) || (cta_res[cta_lr-1]))
164 return(-1);
165 return(cta_lr-2);
166}
167
168/*
169int32_t cryptoworks_send_pin(struct s_reader * reader)
170{
171 unsigned char insPIN[] = { 0xA4, 0x20, 0x00, 0x00, 0x04, 0x00,0x00,0x00,0x00 }; //Verify PIN
172
173 if(reader->pincode[0] && (reader->pincode[0]&0xF0)==0x30)
174 {
175 memcpy(insPIN+5,reader->pincode,4);
176
177 write_cmd(insPIN, insPIN+5);
178 rdr_debug_mask(reader, D_READER, "Sent pincode to card.");
179 if((cta_res[0]==0x98)&&(cta_res[1]==0x04)) rdr_log(reader, "bad pincode");
180
181 return OK;
182 }
183
184 return(0);
185}
186*/
187
188static int32_t cryptoworks_disable_pin(struct s_reader * reader)
189{
190 def_resp;
191 unsigned char insPIN[] = { 0xA4, 0x26, 0x00, 0x00, 0x04, 0x00,0x00,0x00,0x00 }; //disable PIN
192
193 if(reader->pincode[0] && (reader->pincode[0]&0xF0)==0x30)
194 {
195 memcpy(insPIN+5,reader->pincode,4);
196
197 write_cmd(insPIN, insPIN+5);
198 rdr_log (reader, "disable pincode to card");
199 if((cta_res[0]==0x98)&&(cta_res[1]==0x04)) rdr_log (reader, "bad pincode");
200 return ERROR;
201 }
202 return OK;
203}
204
205static int32_t cryptoworks_card_init(struct s_reader * reader, ATR *newatr)
206{
207 get_atr;
208 def_resp;
209 int32_t i;
210 uint32_t mfid=0x3F20;
211 static const uchar cwexp[] = { 1, 0 , 1};
212 uchar insA4C[]= {0xA4, 0xC0, 0x00, 0x00, 0x11};
213 uchar insB8[] = {0xA4, 0xB8, 0x00, 0x00, 0x0c};
214 uchar issuerid=0;
215 char issuer[20]={0}, tmp[11];
216 char *unknown="unknown", *pin=unknown, ptxt[CS_MAXPROV<<2]={0};
217
218 if ((atr[6]!=0xC4) || (atr[9]!=0x8F) || (atr[10]!=0xF1)) return ERROR;
219
220 rdr_log(reader, "card detected");
221 rdr_log(reader, "type: CryptoWorks");
222
223 reader->caid=0xD00;
224 reader->nprov=0;
225 reader->ucpk_valid = 0;
226 memset(reader->prid, 0, sizeof(reader->prid));
227
228 write_cmd(insA4C, NULL); // read masterfile-ID
229 if ((cta_res[0]==0xDF) && (cta_res[1]>=6))
230 mfid=(cta_res[6]<<8)|cta_res[7];
231
232 select_file(reader, 0x3f, 0x20, cta_res, &cta_lr);
233 insB8[2]=insB8[3]=0; // first
234 for(cta_res[0]=0xdf; cta_res[0]==0xdf;)
235 {
236 write_cmd(insB8, NULL); // read provider id's
237 if (cta_res[0]!=0xdf) break;
238 if (((cta_res[4]&0x1f)==0x1f) && (reader->nprov<CS_MAXPROV))
239 {
240 snprintf(ptxt+strlen(ptxt), sizeof(ptxt)-strlen(ptxt), ",%02X", cta_res[5]);
241 reader->prid[reader->nprov++][3]=cta_res[5];
242 }
243 insB8[2]=insB8[3]=0xff; // next
244 }
245 for (i=reader->nprov; i<CS_MAXPROV; i++)
246 memset(&reader->prid[i][0], 0xff, 4);
247
248 select_file(reader, 0x2f, 0x01, cta_res, &cta_lr); // read caid
249 if (read_record(reader, 0xD1, cta_res)>=4)
250 reader->caid=(cta_res[2]<<8)|cta_res[3];
251
252 if (read_record(reader, 0x80, cta_res)>=7) // read serial
253 memcpy(reader->hexserial, cta_res+2, 5);
254 rdr_log_sensitive(reader, "type: CryptoWorks, caid: %04X, ascii serial: {%llu}, hex serial: {%s}",
255 reader->caid, (unsigned long long) b2ll(5, reader->hexserial),cs_hexdump(0, reader->hexserial, 5, tmp, sizeof(tmp)));
256
257 if (read_record(reader, 0x9E, cta_res)>=66) // read ISK
258 {
259 uchar keybuf[256];
260 BIGNUM *ipk;
261 if (search_boxkey(reader->caid, (char *)keybuf))
262 {
263 ipk=BN_new();
264 BN_bin2bn(cwexp, sizeof(cwexp), &reader->exp);
265 BN_bin2bn(keybuf, 64, ipk);
266 cw_RSA(reader, cta_res+2, cta_res+2, 0x40, &reader->exp, ipk, 0);
267 BN_free(ipk);
268 reader->ucpk_valid =(cta_res[2]==((mfid & 0xFF)>>1));
269 if (reader->ucpk_valid)
270 {
271 cta_res[2]|=0x80;
272 BN_bin2bn(cta_res+2, 0x40, &reader->ucpk);
273 rdr_ddump_mask(reader, D_READER, cta_res+2, 0x40, "IPK available -> session-key:");
274 }
275 else
276 {
277 reader->ucpk_valid =(keybuf[0]==(((mfid & 0xFF)>>1)|0x80));
278 if (reader->ucpk_valid)
279 {
280 BN_bin2bn(keybuf, 0x40, &reader->ucpk);
281 rdr_ddump_mask(reader, D_READER, keybuf, 0x40, "session-key found:");
282 }
283 else
284 rdr_log(reader, "invalid IPK or session-key for CAID %04X !", reader->caid);
285 }
286 }
287 }
288 if (read_record(reader, 0x9F, cta_res)>=3)
289 issuerid=cta_res[2];
290 if (read_record(reader, 0xC0, cta_res)>=16)
291 {
292 cs_strncpy(issuer, (const char *)cta_res+2, sizeof(issuer));
293 trim(issuer);
294 }
295 else
296 cs_strncpy(issuer, unknown, sizeof(issuer));
297
298 select_file(reader, 0x3f, 0x20, cta_res, &cta_lr);
299 select_file(reader, 0x2f, 0x11, cta_res, &cta_lr); // read pin
300 if (read_record(reader, atr[8], cta_res)>=7)
301 {
302 cta_res[6]=0;
303 pin=(char *)cta_res+2;
304 }
305 rdr_log (reader, "issuer: %s, id: %02X, bios: v%d, pin: %s, mfid: %04X", issuer, issuerid, atr[7], pin, mfid);
306 rdr_log (reader, "providers: %d (%s)", reader->nprov, ptxt+1);
307
308 cryptoworks_disable_pin(reader);
309
310 return OK;
311}
312
313static int32_t cryptoworks_do_ecm(struct s_reader * reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
314{
315 def_resp;
316 int32_t r=0;
317 unsigned char ins4C[] = { 0xA4,0x4C,0x00,0x00,0x00 };
318 unsigned char insC0[] = { 0xA4,0xC0,0x00,0x00,0x1C };
319 unsigned char nanoD4[10];
320 int32_t secLen=check_sct_len(er->ecm,-5+(reader->ucpk_valid ? sizeof(nanoD4):0));
321
322 if(secLen>5)
323 {
324 int32_t i;
325 const uchar *ecm=er->ecm;
326 uchar buff[MAX_LEN];
327
328 if(reader->ucpk_valid)
329 {
330 memcpy(buff,er->ecm,secLen);
331 nanoD4[0]=0xD4;
332 nanoD4[1]=0x08;
333 for (i=2; i<(int)sizeof(nanoD4); i++)
334 nanoD4[i]=rand();
335 memcpy(&buff[secLen], nanoD4, sizeof(nanoD4));
336 ecm=buff;
337 secLen+=sizeof(nanoD4);
338 }
339
340 ins4C[3]=reader->ucpk_valid ? 2 : 0;
341 ins4C[4]=secLen-5;
342 write_cmd(ins4C, ecm+5);
343 if (cta_res[cta_lr-2]==0x9f)
344 {
345 insC0[4]=cta_res[cta_lr-1];
346 write_cmd(insC0, NULL);
347 for(i=0; i<secLen && r<2; )
348 {
349 int32_t n=cta_res[i+1];
350 switch(cta_res[i])
351 {
352 case 0x80:
353 rdr_debug_mask(reader, D_READER, "nano 80 (serial)");
354 break;
355 case 0xD4:
356 rdr_debug_mask(reader, D_READER, "nano D4 (rand)");
357 if(n<8 || memcmp(&cta_res[i],nanoD4,sizeof(nanoD4))){
358 rdr_debug_mask(reader, D_READER, "random data check failed after decrypt");
359 }
360 break;
361 case 0xDB: // CW
362 rdr_debug_mask(reader, D_READER, "nano DB (cw)");
363 if(n==0x10)
364 {
365 memcpy(ea->cw, &cta_res[i+2], 16);
366 r|=1;
367 }
368 break;
369 case 0xDF: // signature
370 rdr_debug_mask(reader, D_READER, "nano DF %02x (sig)", n);
371 if (n==0x08)
372 {
373 if((cta_res[i+2]&0x50)==0x50 && !(cta_res[i+3]&0x01) && (cta_res[i+5]&0x80))
374 r|=2;
375 }
376 else if (n==0x40) // camcrypt
377 {
378 if(reader->ucpk_valid)
379 {
380 cw_RSA(reader, &cta_res[i+2],&cta_res[i+2], n, &reader->exp, &reader->ucpk, 0);
381 rdr_debug_mask(reader, D_READER, "after camcrypt");
382 r=0; secLen=n-4; n=4;
383 }
384 else
385 {
386 rdr_log(reader, "valid UCPK needed for camcrypt!");
387 return ERROR;
388 }
389 }
390 break;
391 default:
392 rdr_debug_mask(reader, D_READER, "nano %02x (unhandled)", cta_res[i]);
393 break;
394 }
395 i+=n+2;
396 }
397 }
398
399/*
400#ifdef LALL
401 if ((cta_res[cta_lr-2]==0x9f)&&(cta_res[cta_lr-1]==0x1c))
402 {
403 write_cmd(insC0, NULL);
404 if ((cta_lr>26)&&(cta_res[cta_lr-2]==0x90)&&(cta_res[cta_lr-1]==0))
405 {
406 if (rc=(((cta_res[20]&0x50)==0x50) &&
407 (!(cta_res[21]&0x01)) &&
408 (cta_res[23]&0x80)))
409 memcpy(ea->cw, cta_res+2, 16);
410 }
411 }
412#endif
413*/
414 }
415 //return(rc ? 1 : 0);
416 return((r==3) ? 1 : 0);
417}
418
419static uint32_t cryptoworks_get_emm_provid(unsigned char *buffer, int32_t len);
420
421static int32_t cryptoworks_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr)
422{
423 char dumprdrserial[16], dumpemmserial[16];
424
425 rdr_debug_mask(rdr, D_EMM, "Entered cryptoworks_get_emm_type ep->emm[0]=%02x",ep->emm[0]);
426 switch (ep->emm[0]) {
427 case 0x82:
428 if(ep->emm[3]==0xA9 && ep->emm[4]==0xFF && ep->emm[13]==0x80 && ep->emm[14]==0x05) {
429 ep->type = UNIQUE;
430 memset(ep->hexserial, 0, 8);
431 memcpy(ep->hexserial, ep->emm + 5, 5);
432 cs_hexdump(1, rdr->hexserial, 5, dumprdrserial, sizeof(dumprdrserial));
433 cs_hexdump(1, ep->hexserial, 5, dumpemmserial, sizeof(dumpemmserial));
434 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+12, ep->emmlen-12), ep->provid);
435 rdr_debug_mask_sensitive(rdr, D_EMM, "UNIQUE, ep = {%s} rdr = {%s}", dumpemmserial, dumprdrserial);
436 return (!memcmp(ep->emm + 5, rdr->hexserial, 5)); // check for serial
437 }
438 break;
439 case 0x84:
440 if(ep->emm[3]==0xA9 && ep->emm[4]==0xFF && ep->emm[12]==0x80 && ep->emm[13]==0x04) {
441 ep->type = SHARED;
442 memset(ep->hexserial, 0, 8);
443 memcpy(ep->hexserial, ep->emm + 5, 4);
444 cs_hexdump(1, rdr->hexserial, 4, dumprdrserial, sizeof(dumprdrserial));
445 cs_hexdump(1, ep->hexserial, 4, dumpemmserial, sizeof(dumpemmserial));
446 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+12, ep->emmlen-12), ep->provid);
447 rdr_debug_mask_sensitive(rdr, D_EMM, "SHARED, ep = {%s} rdr = {%s}", dumpemmserial, dumprdrserial);
448 return (!memcmp(ep->emm + 5, rdr->hexserial, 4)); // check for SA
449 }
450 break;
451 case 0x86:
452 if(ep->emm[3]==0xA9 && ep->emm[4]==0xFF && ep->emm[5]==0x83
453 && ep->emm[6]==0x01 && ep->emm[8]==0x85) {
454 rdr_debug_mask(rdr, D_EMM, "SHARED (Header)");
455 ep->type = SHARED;
456 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+8, ep->emmlen-8), ep->provid);
457 // We need those packets to pass otherwise we would never
458 // be able to complete EMM reassembly
459 return 1;
460 }
461 break;
462 case 0x88:
463 case 0x89:
464 if(ep->emm[3]==0xA9 && ep->emm[4]==0xFF && ep->emm[8]==0x83 && ep->emm[9]==0x01) {
465 rdr_debug_mask(rdr, D_EMM, "GLOBAL");
466 ep->type = GLOBAL;
467 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+8, ep->emmlen-8), ep->provid);
468 return 1;
469 }
470 break;
471 case 0x8F:
472 ep->type = UNKNOWN;
473 rdr_debug_mask(rdr, D_EMM, "0x8F via camd3");
474
475 switch(ep->emm[4]) {
476 case 0x44:
477 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+8, ep->emmlen-8), ep->provid);
478 ep->type = GLOBAL; break;
479 case 0x48:
480 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+12, ep->emmlen-12), ep->provid);
481 ep->type = SHARED; break;
482 case 0x42:
483 i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+12, ep->emmlen-12), ep->provid);
484 ep->type = UNIQUE; break;
485 }
486 return 1;
487
488 /* FIXME: Seems to be that all other EMM types are rejected by the card */
489 default:
490 ep->type = UNKNOWN;
491 rdr_debug_mask(rdr, D_EMM, "UNKNOWN");
492 return 0; // skip emm
493 }
494
495 rdr_debug_mask(rdr, D_EMM, "invaild");
496 return 0;
497}
498
499static void cryptoworks_get_emm_filter(struct s_reader * rdr, uchar *filter)
500{
501 int32_t idx = 2;
502
503 filter[0]=0xFF;
504 filter[1]=0;
505
506 filter[idx++]=EMM_GLOBAL;
507 filter[idx++]=0;
508 filter[idx+0] = 0x88;
509 filter[idx+0+16] = 0xFE;
510 filter[idx+1] = 0xA9;
511 filter[idx+1+16] = 0xFF;
512 filter[idx+2] = 0xFF;
513 filter[idx+2+16] = 0xFF;
514 filter[1]++;
515 idx += 32;
516
517 filter[idx++]=EMM_SHARED;
518 filter[idx++]=0;
519 filter[idx+0] = 0x86;
520 filter[idx+16] = 0xFF;
521 filter[idx+1] = 0xA9;
522 filter[idx+1+16] = 0xFF;
523 filter[idx+2] = 0xFF;
524 filter[idx+2+16] = 0xFF;
525 filter[1]++;
526 idx += 32;
527
528 filter[idx++]=EMM_SHARED;
529 filter[idx++]=0;
530 filter[idx+0] = 0x84;
531 filter[idx+0+16] = 0xFF;
532 filter[idx+1] = 0xA9;
533 filter[idx+1+16] = 0xFF;
534 filter[idx+2] = 0xFF;
535 filter[idx+2+16] = 0xFF;
536 memcpy(filter+idx+3, rdr->hexserial, 4);
537 memset(filter+idx+3+16, 0xFF, 4);
538 filter[1]++;
539 idx += 32;
540
541 filter[idx++]=EMM_UNIQUE;
542 filter[idx++]=0;
543 filter[idx+0] = 0x82;
544 filter[idx+0+16] = 0xFF;
545 filter[idx+1] = 0xA9;
546 filter[idx+1+16] = 0xFF;
547 filter[idx+2] = 0xFF;
548 filter[idx+2+16] = 0xFF;
549 memcpy(filter+idx+3, rdr->hexserial, 5);
550 memset(filter+idx+3+16, 0xFF, 5);
551 filter[1]++;
552
553 return;
554}
555
556static int32_t cryptoworks_do_emm(struct s_reader * reader, EMM_PACKET *ep)
557{
558 def_resp;
559 uchar insEMM_GA[] = {0xA4, 0x44, 0x00, 0x00, 0x00};
560 uchar insEMM_SA[] = {0xA4, 0x48, 0x00, 0x00, 0x00};
561 uchar insEMM_UA[] = {0xA4, 0x42, 0x00, 0x00, 0x00};
562 int32_t rc=0;
563 uchar *emm=ep->emm;
564
565 if(emm[0]==0x8f && emm[3]==0xA4) {
566 //camd3 emm
567 write_cmd(emm+3, emm+3+CMD_LEN);
568 rc=((cta_res[0]==0x90)&&(cta_res[1]==0x00));
569 return(rc);
570 }
571
572
573 switch(ep->type)
574 {
575 //GA
576 case GLOBAL:
577 insEMM_GA[4]=ep->emm[2]-2;
578 if(emm[7]==insEMM_GA[4]-3)
579 {
580 write_cmd(insEMM_GA, emm+5);
581 rc=((cta_res[0]==0x90)&&(cta_res[1]==0x00));
582 }
583 break;
584
585 //SA
586 case SHARED:
587 insEMM_SA[4]=ep->emm[2]-6;
588 //if(emm[11]==insEMM_SA[4]-3)
589 //{
590 write_cmd(insEMM_SA, emm+9);
591 rc=((cta_res[0]==0x90)&&(cta_res[1]==0x00));
592 //}
593 break;
594
595 //UA
596 case UNIQUE:
597 insEMM_UA[4]=ep->emm[2]-7;
598 if(emm[12]==insEMM_UA[4]-3)
599 {
600 //cryptoworks_send_pin(); //?? may be
601 write_cmd(insEMM_UA, emm+10);
602 rc=((cta_res[0]==0x90)&&(cta_res[1]==0x00));
603 }
604 break;
605 }
606
607 if (!rc)
608 rdr_debug_mask(reader, D_EMM, "%s(): type %d - %02X %02X", __func__, ep->type, cta_res[0], cta_res[1]);
609
610 return(rc);
611}
612
613static int32_t cryptoworks_card_info(struct s_reader * reader)
614{
615 def_resp;
616 int32_t i;
617 uchar insA21[]= {0xA4, 0xA2, 0x01, 0x00, 0x05, 0x8C, 0x00, 0x00, 0x00, 0x00};
618 uchar insB2[] = {0xA4, 0xB2, 0x00, 0x00, 0x00};
619 char l_name[20+8]=", name: ";
620
621 cs_clear_entitlement(reader); // reset the entitlements
622
623 for (i=0; i<reader->nprov; i++)
624 {
625 l_name[8]=0;
626 select_file(reader, 0x1f, reader->prid[i][3], cta_res, &cta_lr); // select provider
627 select_file(reader, 0x0e, 0x11, cta_res, &cta_lr); // read provider name
628 if (read_record(reader, 0xD6, cta_res)>=16)
629 {
630 cs_strncpy(l_name+8, (const char *)cta_res+2, sizeof(l_name)-9);
631 l_name[sizeof(l_name)-1]=0;
632 trim(l_name+8);
633 }
634 l_name[0]=(l_name[8]) ? ',' : 0;
635 rdr_log (reader, "provider: %d, id: %02X%s", i+1, reader->prid[i][3], l_name);
636 select_file(reader, 0x0f, 0x20, cta_res, &cta_lr); // select provider class
637 write_cmd(insA21, insA21+5);
638 if (cta_res[0]==0x9f)
639 {
640 insB2[4]=cta_res[1];
641 for(insB2[3]=0; (cta_res[0]!=0x94)||(cta_res[1]!=0x2); insB2[3]=1)
642 {
643 write_cmd(insB2, NULL); // read chid
644 if (cta_res[0]!=0x94)
645 {
646 char ds[16], de[16];
647
648 // todo: add entitlements to list but produces a warning related to date variable
649 cs_add_entitlement(reader, reader->caid, reader->prid[i][3], b2i(2, cta_res + 7), 0,
650 chid_date(cta_res+28, ds, sizeof(ds)-1),
651 chid_date(cta_res+30, de, sizeof(de)-1), 3);
652
653 rdr_log (reader, "chid: %02X%02X, date: %s - %s, name: %s",
654 cta_res[6], cta_res[7], ds, de, trim((char *) cta_res+10));
655 }
656 }
657 }
658
659 select_file(reader, 0x0f, 0x00, cta_res, &cta_lr); // select provider channel
660 write_cmd(insA21, insA21+5);
661 if (cta_res[0]==0x9f)
662 {
663 insB2[4]=cta_res[1];
664 for(insB2[3]=0; (cta_res[0]!=0x94)||(cta_res[1]!=0x2); insB2[3]=1)
665 {
666 write_cmd(insB2, NULL); // read chid
667 if (cta_res[0]!=0x94)
668 {
669 char ds[16], de[16];
670
671 // todo: add entitlements to list but produces a warning related to date variable
672 cs_add_entitlement(reader, reader->caid, reader->prid[i][3], b2i(2, cta_res + 6), 0,
673 chid_date(cta_res+28, ds, sizeof(ds)-1),
674 chid_date(cta_res+30, de, sizeof(de)-1), 3);
675
676 cta_res[27]=0;
677 rdr_log (reader, "chid: %02X%02X, date: %s - %s, name: %s",
678 cta_res[6], cta_res[7], ds, de, trim((char *)cta_res+10));
679 }
680 }
681 }
682 }
683 rdr_log(reader, "ready for requests");
684 return OK;
685}
686
687static uint32_t cryptoworks_get_emm_provid(unsigned char *buffer, int32_t len)
688{
689 uint32_t provid=0;
690 int32_t i=0;
691
692 for(i=0; i<len;) {
693 switch (buffer[i]) {
694 case 0x83:
695 provid=buffer[i+2] & 0xfc;
696 return provid;
697 break;
698 default:
699 i+=buffer[i+1]+2;
700 break;
701 }
702
703 }
704 return provid;
705}
706
707static bool cryptoworks_reassemble_emm(struct s_reader *reader, EMM_PACKET *ep)
708{
709 uchar *buffer = ep->emm;
710 int16_t *len = &ep->emmlen;
711 int16_t emm_len = 0;
712
713 // Cryptoworks
714 // Cryptoworks EMM-S have to be assembled by the client from an EMM-SH with table
715 // id 0x84 and a corresponding EMM-SB (body) with table id 0x86. A pseudo EMM-S
716 // with table id 0x84 has to be build containing all nano commands from both the
717 // original EMM-SH and EMM-SB in ascending order.
718 //
719 if (*len>500) return 0;
720 char dumpbuf[255];
721
722 switch (buffer[0]) {
723 case 0x82 : // emm-u
724 cs_debug_mask(D_DVBAPI, "[cryptoworks] unique emm (EMM-U): %s" , cs_hexdump(0, buffer, *len, dumpbuf, sizeof(dumpbuf)));
725 break;
726
727 case 0x84: // emm-sh
728 cs_debug_mask(D_DVBAPI, "[cryptoworks] shared emm (EMM-SH): %s" , cs_hexdump(0, buffer, *len, dumpbuf, sizeof(dumpbuf)));
729 if (!memcmp(reader->reassemble_emm, buffer, *len)) return 0;
730 memcpy(reader->reassemble_emm, buffer, *len);
731 reader->reassemble_emm_len=*len;
732 // If we return 0 (skip packet) and someone send us already
733 // reassembled packet we would miss it. Thats why we return 1 (ok)
734 // and "suffer" couple of wrongly written packets in the card.
735 return 1;
736
737 case 0x86: // emm-sb
738 cs_debug_mask(D_DVBAPI, "[cryptoworks] shared emm (EMM-SB): %s" , cs_hexdump(0, buffer, *len, dumpbuf, sizeof(dumpbuf)));
739 if (!reader->reassemble_emm_len) return 0;
740
741 // we keep the first 12 bytes of the 0x84 emm (EMM-SH)
742 // now we need to append the payload of the 0x86 emm (EMM-SB)
743 // starting after the header (&buffer[5])
744 // then the rest of the payload from EMM-SH
745 // so we should have :
746 // EMM-SH[0:12] + EMM-SB[5:len_EMM-SB] + EMM-SH[12:EMM-SH_len]
747 // then sort the nano in ascending order
748 // update the emm len (emmBuf[1:2])
749 //
750
751 emm_len=*len-5 + reader->reassemble_emm_len-12;
752 unsigned char *tmp, *assembled;
753 if (!cs_malloc(&tmp, emm_len))
754 return 0;
755 if (!cs_malloc(&assembled, emm_len + 12)) {
756 free(tmp);
757 return 0;
758 }
759 unsigned char *assembled_EMM;
760 if (!cs_malloc(&assembled_EMM, emm_len + 12)) {
761 free(assembled);
762 free(tmp);
763 return 0;
764 }
765 memcpy(tmp,&buffer[5], *len-5);
766 memcpy(tmp+*len-5,&reader->reassemble_emm[12],reader->reassemble_emm_len-12);
767 memcpy(assembled_EMM,reader->reassemble_emm,12);
768 emm_sort_nanos(assembled_EMM+12,tmp,emm_len);
769
770 assembled_EMM[1]=((emm_len+9)>>8) | 0x70;
771 assembled_EMM[2]=(emm_len+9) & 0xFF;
772 //copy back the assembled emm in the working buffer
773 memcpy(buffer, assembled_EMM, emm_len+12);
774 *len=emm_len+12;
775
776 free(tmp);
777 free(assembled);
778 free(assembled_EMM);
779
780 reader->reassemble_emm_len = 0;
781
782 cs_debug_mask(D_DVBAPI, "[cryptoworks] shared emm (assembled): %s", cs_hexdump(0, buffer, emm_len+12, dumpbuf, sizeof(dumpbuf)));
783 if(assembled_EMM[11]!=emm_len) { // sanity check
784 // error in emm assembly
785 cs_debug_mask(D_DVBAPI, "[cryptoworks] Error assembling Cryptoworks EMM-S");
786 return 0;
787 }
788 break;
789
790 case 0x88: // emm-g
791 case 0x89: // emm-g
792 cs_debug_mask(D_DVBAPI, "[cryptoworks] global emm (EMM-G): %s", cs_hexdump(0, buffer, *len, dumpbuf, sizeof(dumpbuf)));
793 break;
794 }
795 return 1;
796}
797
798void reader_cryptoworks(struct s_cardsystem *ph)
799{
800 ph->do_emm_reassembly=cryptoworks_reassemble_emm;
801 ph->do_emm=cryptoworks_do_emm;
802 ph->do_ecm=cryptoworks_do_ecm;
803 ph->card_info=cryptoworks_card_info;
804 ph->card_init=cryptoworks_card_init;
805 ph->get_emm_type=cryptoworks_get_emm_type;
806 ph->get_emm_filter=cryptoworks_get_emm_filter;
807 ph->caids[0]=0x0D;
808 ph->desc="cryptoworks";
809}
810#endif
Note: See TracBrowser for help on using the repository browser.