source: trunk/reader-dre.c @ 4686

Last change on this file since 4686 was 4686, checked in by landlord, 9 years ago

Added patch for DRE2 (Platforma HD + Tricolor) SCs.

  • Property svn:eol-style set to native
File size: 16.5 KB
Line 
1#include <openssl/des.h>
2
3#include "globals.h"
4#include "reader-common.h"
5
6#define OK_RESPONSE 0x61
7#define CMD_BYTE 0x59
8
9void DES_Decrypt(DES_cblock *data, const_DES_cblock *key)
10{
11  DES_cblock out;
12  DES_key_schedule schedule;
13
14  DES_set_key_unchecked(key, &schedule);
15  DES_ecb_encrypt(data, &out, &schedule, 0);
16
17  memcpy(data, &out, 8);
18}
19
20static uchar xor (const uchar * cmd, int cmdlen)
21{
22  int i;
23  uchar checksum = 0x00;
24  for (i = 0; i < cmdlen; i++)
25    checksum ^= cmd[i];
26  return checksum;
27}
28
29static int dre_command (struct s_reader * reader, const uchar * cmd, int cmdlen, unsigned char * cta_res, unsigned short * p_cta_lr)    //attention: inputcommand will be changed!!!! answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
30{
31  uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 };  //any command starts with this,
32  //last byte is nr of bytes of the command that will be sent
33  //after the startcmd
34//response on startcmd+cmd:     = { 0x61, 0x05 }  //0x61 = "OK", last byte is nr. of bytes card will send
35  uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 };    //after command answer has to be requested,
36  //last byte must be nr. of bytes that card has reported to send
37  uchar command[256];
38  int headerlen = sizeof (startcmd);
39  startcmd[4] = cmdlen + 3; //commandlength + type + len + checksum bytes
40  memcpy (command, startcmd, headerlen);
41  command[headerlen++] = CMD_BYTE;  //type
42  command[headerlen++] = cmdlen + 1;    //len = command + 1 checksum byte
43  memcpy (command + headerlen, cmd, cmdlen);
44
45  uchar checksum = ~xor (cmd, cmdlen);
46  //cs_debug_mask(D_READER, "[dre-reader] Checksum: %02x", checksum);
47  cmdlen += headerlen;
48  command[cmdlen++] = checksum;
49
50  reader_cmd2icc (reader, command, cmdlen, cta_res, p_cta_lr);
51
52  if ((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE)) {
53    cs_log ("[dre-reader] unexpected answer from card: %s", cs_hexdump (0, cta_res, *p_cta_lr));
54    return ERROR;           //error
55  }
56
57  reqans[4] = cta_res[1];   //adapt length byte
58  reader_cmd2icc (reader, reqans, 5, cta_res, p_cta_lr);
59
60  if (cta_res[0] != CMD_BYTE) {
61    cs_log ("[dre-reader] unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
62    return ERROR;
63  }
64  if ((cta_res[1] == 0x03) && (cta_res[2] == 0xe2)) {
65    switch (cta_res[3]) {
66    case 0xe1:
67      cs_log ("[dre-reader] checksum error: %s.", cs_hexdump (0, cta_res, *p_cta_lr));
68      break;
69    case 0xe2:
70      cs_log ("[dre-reader] wrong provider: %s.", cs_hexdump (0, cta_res, *p_cta_lr));
71      break;
72    case 0xe3:
73      cs_log ("[dre-reader] illegal command: %s.", cs_hexdump (0, cta_res, *p_cta_lr)); 
74      break;
75    case 0xec:
76      cs_log ("[dre-reader] wrong signature: %s.", cs_hexdump (0, cta_res, *p_cta_lr));
77      break;
78    default:
79      cs_debug_mask(D_READER, "[dre-reader] unknown error: %s.", cs_hexdump (0, cta_res, *p_cta_lr));
80      break;
81    }
82    return ERROR;           //error
83  }
84  int length_excl_leader = *p_cta_lr;
85  if ((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
86    length_excl_leader -= 2;
87
88  checksum = ~xor (cta_res + 2, length_excl_leader - 3);
89
90  if (cta_res[length_excl_leader - 1] != checksum) {
91    cs_log ("[dre-reader] checksum does not match, expected %02x received %02x:%s", checksum,
92        cta_res[length_excl_leader - 1], cs_hexdump (0, cta_res, *p_cta_lr));
93    return ERROR;           //error
94  }
95  return OK;
96}
97
98#define dre_cmd(cmd) \
99{ \
100    dre_command(reader, cmd, sizeof(cmd),cta_res,&cta_lr); \
101}
102
103static int dre_set_provider_info (struct s_reader * reader)
104{
105  def_resp;
106  int i;
107  uchar cmd59[] = { 0x59, 0x14 };   // subscriptions
108  uchar cmd5b[] = { 0x5b, 0x00, 0x14 }; //validity dates
109
110  cmd59[1] = reader->provider;
111  if ((dre_cmd (cmd59))) {  //ask subscription packages, returns error on 0x11 card
112    uchar pbm[32];
113    memcpy (pbm, cta_res + 3, cta_lr - 6);
114    cs_debug_mask(D_READER, "[dre-reader] pbm: %s", cs_hexdump (0, pbm, 32));
115
116    if (pbm[0] == 0xff)
117      cs_ri_log (reader, "[dre-reader] no active packages");
118    else
119      for (i = 0; i < 32; i++)
120    if (pbm[i] != 0xff) {
121      cmd5b[1] = i;
122      cmd5b[2] = reader->provider;
123      dre_cmd (cmd5b);  //ask for validity dates
124
125      time_t start;
126      time_t end;
127      start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
128      end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];
129
130      struct tm temp;
131
132      localtime_r (&start, &temp);
133      int startyear = temp.tm_year + 1900;
134      int startmonth = temp.tm_mon + 1;
135      int startday = temp.tm_mday;
136      localtime_r (&end, &temp);
137      int endyear = temp.tm_year + 1900;
138      int endmonth = temp.tm_mon + 1;
139      int endday = temp.tm_mday;
140      cs_ri_log (reader, "[dre-reader] active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i, startyear, startmonth, startday,
141          endyear, endmonth, endday);
142    }
143  }
144  return OK;
145}
146
147static int dre_card_init (struct s_reader * reader, ATR newatr)
148{
149    get_atr;
150  def_resp;
151  uchar ua[] = { 0x43, 0x15 };  // get serial number (UA)
152  uchar providers[] = { 0x49, 0x15 };   // get providers
153  int i;
154    char *card;
155
156  if ((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12 || atr[4] != 0xca || atr[5] != 0x07))
157    return ERROR;
158
159  reader->provider = atr[6];
160  uchar checksum = xor (atr + 1, 6);
161
162  if (checksum != atr[7])
163    cs_log ("[dre-reader] warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]);
164
165  switch (atr[6]) {
166  case 0x11:
167    card = "Tricolor Centr";
168    reader->caid = 0x4ae1;
169    break;          //59 type card = MSP (74 type = ATMEL)
170  case 0x12:
171    card = "Cable TV";
172    reader->caid = 0x4ae1;  //TODO not sure about this one
173    break;
174  case 0x14:
175    card = "Tricolor Syberia / Platforma HD new";
176    reader->caid = 0x4ae1;
177    break;          //59 type card
178  case 0x15:
179    card = "Platforma HD / DW old";
180    reader->caid = 0x4ae1;
181    break;          //59 type card
182  default:
183    card = "Unknown";
184    reader->caid = 0x4ae1;
185    break;
186  }
187
188  memset (reader->prid, 0x00, 8);
189
190  static const uchar cmd30[] =
191    { 0x30, 0x81, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05, 0x06, 0x87, 0x08, 0x09, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05,
192    0x00
193  };
194  dre_cmd (cmd30);      //unknown command, generates error on card 0x11 and 0x14
195/*
196response:
19759 03 E2 E3
198FE 48 */
199
200  uchar cmd54[] = { 0x54, 0x14 };   // geocode
201  cmd54[1] = reader->provider;
202  uchar geocode = 0;
203  if ((dre_cmd (cmd54)))    //error would not be fatal, like on 0x11 cards
204    geocode = cta_res[3];
205
206  providers[1] = reader->provider;
207  if (!(dre_cmd (providers)))
208    return ERROR;           //fatal error
209  if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
210    return ERROR;
211  uchar provname[128];
212  for (i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++) {
213    provname[i] = cta_res[6 + i];
214    if (provname[i] == 0x00)
215      break;
216  }
217  int major_version = cta_res[3];
218  int minor_version = cta_res[4];
219
220  ua[1] = reader->provider;
221  dre_cmd (ua);         //error would not be fatal
222
223  int hexlength = cta_res[1] - 2;   //discard first and last byte, last byte is always checksum, first is answer code
224
225  reader->hexserial[0] = 0;
226  reader->hexserial[1] = 0;
227  memcpy (reader->hexserial + 2, cta_res + 3, hexlength);
228
229  int low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
230  int dre_chksum = 0;
231  uchar buf[32];
232  sprintf ((char *)buf, "%i%i%08i", reader->provider - 16, major_version + 1, low_dre_id);
233  for (i = 0; i < 32; i++) {
234    if (buf[i] == 0x00)
235      break;
236    dre_chksum += buf[i] - 48;
237  }
238
239  //cs_ri_log("[dre-reader] type: DRE Crypt, caid: %04X, serial: %llu, card: v%x",
240  cs_ri_log (reader, "[dre-reader] type: DRE Crypt, caid: %04X, serial: %s, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
241      reader->caid, cs_hexdump (0, reader->hexserial + 2, 4), dre_chksum, reader->provider - 16,
242      major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
243  cs_ri_log (reader, "[dre-reader] Provider name:%s.", provname);
244
245
246  memset (reader->sa, 0, sizeof (reader->sa));
247  memcpy (reader->sa[0], reader->hexserial + 2, 1); //copy first byte of unique address also in shared address, because we dont know what it is...
248
249  cs_ri_log (reader, "[dre-reader] SA = %02X%02X%02X%02X, UA = %s", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
250      reader->sa[0][3], cs_hexdump (0, reader->hexserial + 2, 4));
251
252  reader->nprov = 1;
253
254  if (!dre_set_provider_info (reader))
255    return ERROR;           //fatal error
256
257  cs_log ("[dre-reader] ready for requests");
258  return OK;
259}
260
261static unsigned char DESkeys[16*8]=
262{
263  0x4A,0x11,0x23,0xB1,0x45,0x99,0xCF,0x10, // 00
264  0x21,0x1B,0x18,0xCD,0x02,0xD4,0xA1,0x1F, // 01
265  0x07,0x56,0xAB,0xB4,0x45,0x31,0xAA,0x23, // 02
266  0xCD,0xF2,0x55,0xA1,0x13,0x4C,0xF1,0x76, // 03
267  0x57,0xD9,0x31,0x75,0x13,0x98,0x89,0xC8, // 04
268  0xA3,0x36,0x5B,0x18,0xC2,0x83,0x45,0xE2, // 05
269  0x19,0xF7,0x35,0x08,0xC3,0xDA,0xE1,0x28, // 06
270  0xE7,0x19,0xB5,0xD8,0x8D,0xE3,0x23,0xA4, // 07
271  0xA7,0xEC,0xD2,0x15,0x8B,0x42,0x59,0xC5, // 08
272  0x13,0x49,0x83,0x2E,0xFB,0xAD,0x7C,0xD3, // 09
273  0x37,0x25,0x78,0xE3,0x72,0x19,0x53,0xD9, // 0A
274  0x7A,0x15,0xA4,0xC7,0x15,0x49,0x32,0xE8, // 0B
275  0x63,0xD5,0x96,0xA7,0x27,0xD8,0xB2,0x68, // 0C
276  0x42,0x5E,0x1A,0x8C,0x41,0x69,0x8E,0xE8, // 0D
277  0xC2,0xAB,0x37,0x29,0xD3,0xCF,0x93,0xA7, // 0E
278  0x49,0xD3,0x33,0xC2,0xEB,0x71,0xD3,0x14  // 0F
279};
280
281void DREover(unsigned char *ECMdata, unsigned char *DW)
282{
283  unsigned char i, data[8], key[8];
284  if(ECMdata[2] >= (43+4) && ECMdata[40] == 0x3A && ECMdata[41] == 0x4B)
285  {
286    for(i = 0; i < 8; i++) key[i] = DESkeys[(ECMdata[42] & 0x0F) * 8 + i];
287
288    for(i = 0; i < 8; i++) data[i] = DW[i];
289    DES_Decrypt(&data, &key);                             // even DW post-process
290    for(i = 0; i < 8; i++) DW[i] = data[i];
291
292    for(i = 0; i < 8; i++) data[i] = DW[8+i];
293    DES_Decrypt(&data, &key);                             // odd DW post-process
294    for(i = 0; i < 8; i++) DW[8+i] = data[i];
295  };
296};
297
298static int dre_do_ecm (struct s_reader * reader, ECM_REQUEST * er)
299{
300  def_resp;
301  if (reader->caid == 0x4ae0) {
302    uchar ecmcmd41[] = { 0x41,
303      0x58, 0x1f, 0x00,     //fixed part, dont change
304      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   //0x01 - 0x08: next key
305      0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,   //0x11 - 0x18: current key
306      0x3b, 0x59, 0x11      //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
307    };
308    ecmcmd41[22] = reader->provider;
309    memcpy (ecmcmd41 + 4, er->ecm + 8, 16);
310    ecmcmd41[20] = er->ecm[6];  //keynumber
311    ecmcmd41[21] = 0x58 + er->ecm[25];  //package number
312    cs_debug_mask(D_READER, "[dre-reader] unused ECM info front:%s", cs_hexdump (0, er->ecm, 8));
313    cs_debug_mask(D_READER, "[dre-reader] unused ECM info back:%s", cs_hexdump (0, er->ecm + 24, er->ecm[2] + 2 - 24));
314    if ((dre_cmd (ecmcmd41))) { //ecm request
315      if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
316                return ERROR;       //exit if response is not 90 00
317      memcpy (er->cw, cta_res + 11, 8);
318      memcpy (er->cw + 8, cta_res + 3, 8);
319
320      return OK;
321    }
322  }
323  else {
324
325    uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3,  //fixed header?
326      0x9C, 0xDA,       //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
327      0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E,   //next key?
328      0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD,   //current key?
329      0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11,   //key or signature?
330      0x14          //provider
331    };
332    memcpy (ecmcmd51 + 1, er->ecm + 5, 0x21);
333    cs_debug_mask(D_READER, "[dre-reader] unused ECM info front:%s", cs_hexdump (0, er->ecm, 5));
334    cs_debug_mask(D_READER, "[dre-reader] unused ECM info back:%s", cs_hexdump (0, er->ecm + 37, 4));
335    ecmcmd51[33] = reader->provider;    //no part of sig
336    if ((dre_cmd (ecmcmd51))) { //ecm request
337      if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
338                return ERROR;       //exit if response is not 90 00
339      DREover(er->ecm, cta_res + 3);
340      memcpy (er->cw, cta_res + 11, 8);
341      memcpy (er->cw + 8, cta_res + 3, 8);
342      return OK;
343    }
344  }
345  return ERROR;
346}
347
348static int dre_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr)
349{
350  switch (ep->emm[0]) {
351        case 0x87:
352            ep->type = UNIQUE;
353            return TRUE; //FIXME: no filling of ep->hexserial
354
355        case 0x89:
356            ep->type = SHARED;
357            // FIXME: Seems to be that SA is only used with caid 0x4ae1
358            if (rdr->caid == 0x4ae1) {
359                memset(ep->hexserial, 0, 8);
360                memcpy(ep->hexserial, ep->emm + 3, 4);
361                return (!memcmp(&rdr->sa[0][0], ep->emm + 3, 4));
362            }
363            else
364                return TRUE;
365        default:
366            ep->type = UNKNOWN;
367            return TRUE;
368    }
369}
370
371void dre_get_emm_filter(struct s_reader * rdr, uchar *filter)
372{
373    filter[0]=0xFF;
374    filter[1]=3;
375
376    filter[2]=GLOBAL;
377    filter[3]=1; //not active
378
379    //FIXME: Dont now how to filter GLOBAL EMM's
380    filter[4+0]    = 0xFF; //dummy
381    filter[4+0+16] = 0xFF;
382
383
384    filter[36]=SHARED;
385    filter[37]=0;
386
387    filter[38+0]    = 0x89;
388    filter[38+0+16] = 0xFF;
389    // FIXME: Seems to be that SA is only used with caid 0x4ae1
390    if (rdr->caid == 0x4ae1) {
391        memcpy(filter+38+1, &rdr->sa[0][0], 4);
392        memset(filter+38+1+16, 0xFF, 4);
393    }
394
395
396    //FIXME: No filter for hexserial
397    filter[70]=UNIQUE;
398    filter[71]=0;
399
400    filter[72+0]    = 0x87;
401       filter[72+0+16] = 0xFF;
402   
403    return;
404}
405
406static int dre_do_emm (struct s_reader * reader, EMM_PACKET * ep)
407{
408  def_resp;
409
410  cs_ddump_mask(D_READER, ep->emm, ((ep->emm[1] & 0x0f) << 8) + ep->emm[2] + 3, "EMM:");
411
412  if (reader->caid == 0x4ae1) {
413    if(ep->type == UNIQUE && ep->emm[39] == 0x3d)
414    { /* For new package activation. */
415        uchar emmcmd58[26];
416        emmcmd58[0] = 0x58;
417        memcpy(&emmcmd58[1], &ep->emm[40], 24);
418        emmcmd58[25] = 0x15;
419        if ((dre_cmd (emmcmd58)))
420            if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
421                return ERROR;
422    }
423    else
424    {
425        uchar emmcmd52[0x3a];
426        emmcmd52[0] = 0x52;
427        int i;
428        for (i = 0; i < 2; i++) {
429            memcpy (emmcmd52 + 1, ep->emm + 5 + 32 + i * 56, 56);
430            // check for shared address
431            if(ep->emm[3]!=reader->sa[0][0]) 
432                return OK; // ignore, wrong address
433            emmcmd52[0x39] = reader->provider;
434            if ((dre_cmd (emmcmd52)))
435                if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
436                    return ERROR; //exit if response is not 90 00
437        }
438    }
439  }
440  else {
441    uchar emmcmd42[] =
442      { 0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
443      0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
444      0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
445      0x91,
446      0x56, 0x58, 0x11
447    };
448        int i;
449        switch (ep->type) {
450            case UNIQUE: 
451            for (i = 0; i < 2; i++) {
452                    memcpy (emmcmd42 + 1, ep->emm + 42 + i*49, 48);
453                    emmcmd42[49] = ep->emm[i*49 + 41]; //keynr
454                    emmcmd42[50] = 0x58 + ep->emm[40]; //package nr
455                emmcmd42[51] = reader->provider;
456                if ((dre_cmd (emmcmd42))) {
457                  if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
458                            return ERROR;       //exit if response is not 90 00
459                    }
460                }
461                break;
462            case SHARED:
463            default:
464            memcpy (emmcmd42 + 1, ep->emm + 6, 48);
465            emmcmd42[51] = reader->provider;
466            //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
467            emmcmd42[50] = 0x58;
468            emmcmd42[49] = ep->emm[5];  //keynr
469            /* response:
470               59 05 A2 02 05 01 5B
471               90 00 */
472            if ((dre_cmd (emmcmd42))) { //first emm request
473              if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
474                        return ERROR;       //exit if response is not 90 00
475       
476              memcpy (emmcmd42 + 1, ep->emm + 55, 7);   //TODO OR next two lines?
477              /*memcpy (emmcmd42 + 1, ep->emm + 55, 7);  //FIXME either I cant count or my EMM log contains errors
478                 memcpy (emmcmd42 + 8, ep->emm + 67, 41); */
479              emmcmd42[51] = reader->provider;
480              //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
481              emmcmd42[50] = 0x58;
482              emmcmd42[49] = ep->emm[54];   //keynr
483              if ((dre_cmd (emmcmd42))) {   //second emm request
484                        if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
485                            return ERROR;       //exit if response is not 90 00
486              }
487            }
488        }
489  }
490  return OK;            //success
491}
492
493static int dre_card_info (void)
494{
495  return OK;
496}
497
498void reader_dre(struct s_cardsystem *ph) 
499{
500    ph->do_emm=dre_do_emm;
501    ph->do_ecm=dre_do_ecm;
502    ph->card_info=dre_card_info;
503    ph->card_init=dre_card_init;
504    ph->get_emm_type=dre_get_emm_type;
505    ph->get_emm_filter=dre_get_emm_filter;
506    ph->caids[0]=0x4A;
507    ph->desc="dre";
508}
Note: See TracBrowser for help on using the repository browser.