source: trunk/reader-dre.c @ 4994

Last change on this file since 4994 was 4994, checked in by Admin, 9 years ago

I noticed that monitor encryption is not working on 64bit plattforms due to other sizes of long on this plattform. This patch converts all numeric types like long to portable types like uint32_t. This is not complete yet (only base folder up to r4987, changes thereafter might be incompletely converted). If you encounter problems through this patch please report in forum.

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