source: trunk/reader-cryptoworks.c @ 5375

Last change on this file since 5375 was 5359, checked in by Admin, 8 years ago

Fix #1894: Don't add messages about sending the pin to the card to the entitlements info.

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