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