source: trunk/reader-dre.c @ 497

Last change on this file since 497 was 497, checked in by dingo35, 10 years ago

Fix small bug in debugging configs

  • Property svn:eol-style set to native
File size: 20.8 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3//#include <stdlib.h>
4
5extern uchar cta_cmd[], cta_res[];
6extern ushort cta_lr;
7unsigned long long serial;
8char *card;
9static uchar provider;
10static short int mode;
11
12#define OK_RESPONSE 0x61
13#define CMD_BYTE 0x59
14
15#define dre_cmd(cmd) \
16{ \
17    dre_command(cmd, sizeof(cmd)); \
18}
19
20int dre_set_provider_info (void)
21{
22  int i;
23  static uchar cmd59[] = { 0x59, 0x14 };    // subscriptions
24  static uchar cmd5b[] = { 0x5b, 0x00, 0x14 };  //validity dates
25
26  cmd59[1] = provider;
27  if ((dre_cmd (cmd59))) {  //ask subscription packages, returns error on 0x11 card
28    uchar pbm[32];
29    memcpy (pbm, cta_res + 3, cta_lr - 6);
30    cs_debug ("DRECRYPT pbm: %s", cs_hexdump (0, pbm, 32));
31
32    if (pbm[0] == 0xff)
33      cs_log ("No active packages!");
34    else
35      for (i = 0; i < 32; i++)
36    if (pbm[i] != 0xff) {
37      cmd5b[1] = i;
38      cmd5b[2] = provider;
39      dre_cmd (cmd5b);  //ask for validity dates
40
41      time_t start;
42      time_t end;
43      start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
44      end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];
45
46      struct tm *temp;
47
48      temp = localtime (&start);
49      int startyear = temp->tm_year + 1900;
50      int startmonth = temp->tm_mon + 1;
51      int startday = temp->tm_mday;
52      temp = localtime (&end);
53      int endyear = temp->tm_year + 1900;
54      int endmonth = temp->tm_mon + 1;
55      int endday = temp->tm_mday;
56      cs_log ("Active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i, startyear, startmonth, startday,
57          endyear, endmonth, endday);
58    }
59  }
60  return 1;
61}
62
63uchar xor (uchar * cmd, int cmdlen)
64{
65  int i;
66  uchar checksum = 0x00;
67  for (i = 0; i < cmdlen; i++)
68    checksum ^= cmd[i];
69  return checksum;
70}
71
72
73int dre_command (uchar * cmd, int cmdlen)   //attention: inputcommand will be changed!!!! answer will be in cta_res, length cta_lr ; returning 1 = no error, return 0 = err
74{
75  static uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 };   //any command starts with this,
76  //last byte is nr of bytes of the command that will be sent
77  //after the startcmd
78//response on startcmd+cmd:     = { 0x61, 0x05 }  //0x61 = "OK", last byte is nr. of bytes card will send
79  static uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 }; //after command answer has to be requested,
80  //last byte must be nr. of bytes that card has reported to send
81  uchar command[256];
82  int headerlen = sizeof (startcmd);
83  startcmd[4] = cmdlen + 3; //commandlength + type + len + checksum bytes
84  memcpy (command, startcmd, headerlen);
85  command[headerlen++] = CMD_BYTE;  //type
86  command[headerlen++] = cmdlen + 1;    //len = command + 1 checksum byte
87  memcpy (command + headerlen, cmd, cmdlen);
88
89  uchar checksum = ~xor (cmd, cmdlen);
90  //cs_debug ("Checksum: %02x", checksum);
91  cmdlen += headerlen;
92  command[cmdlen++] = checksum;
93
94  reader_cmd2icc (command, cmdlen);
95
96  if ((cta_lr != 2) || (cta_res[0] != OK_RESPONSE)) {
97    cs_log ("DRECRYPT ERROR: unexpected answer from card: %s", cs_hexdump (0, cta_res, cta_lr));
98    return 0;           //error
99  }
100
101  reqans[4] = cta_res[1];   //adapt length byte
102  reader_cmd2icc (reqans, 5);
103
104  if (cta_res[0] != CMD_BYTE) {
105    cs_log ("DRECRYPT Unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
106    return 0;
107  }
108  if ((cta_res[1] == 0x03) && (cta_res[2] == 0xe2)) {
109    switch (cta_res[3]) {
110    case 0xe1:
111      cs_log ("DRECRYPT checksum error: %s.", cs_hexdump (0, cta_res, cta_lr));
112      break;
113    case 0xe2:
114      cs_log ("DRECRYPT wrong provider: %s.", cs_hexdump (0, cta_res, cta_lr));
115      break;
116    case 0xec:
117      cs_log ("DRECRYPT wrong signature: %s.", cs_hexdump (0, cta_res, cta_lr));
118      break;
119    default:
120      cs_debug ("DRECRYPT unknown error: %s.", cs_hexdump (0, cta_res, cta_lr));
121      break;
122    }
123    return 0;           //error
124  }
125  int length_excl_leader = cta_lr;
126  if ((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0x00))
127    length_excl_leader -= 2;
128
129  checksum = ~xor (cta_res + 2, length_excl_leader - 3);
130
131  if (cta_res[length_excl_leader - 1] != checksum) {
132    cs_log ("DRECRYPT checksum does not match, expected %02x received %02x:%s", checksum,
133        cta_res[length_excl_leader - 1], cs_hexdump (0, cta_res, cta_lr));
134    return 0;           //error
135  }
136  return 1;
137}
138
139int dre_card_init (uchar * atr, int atrsize)
140{
141  static uchar ua[] = { 0x43, 0x15 };   // get serial number (UA)
142  static uchar providers[] = { 0x49, 0x15 };    // get providers
143  int i;
144
145  if ((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12 || atr[4] != 0xca || atr[5] != 0x07))
146    return (0);
147
148  provider = atr[6];
149  uchar checksum = xor (atr + 1, 6);
150
151  if (checksum != atr[7])
152    cs_log ("DRECRYPT Warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]);
153
154  switch (atr[6]) {
155  case 0x11:
156    card = "Tricolor Centr";
157    reader[ridx].caid[0] = 0x4ae0;
158    mode = 41;
159    break;          //59 type card = MSP (74 type = ATMEL)
160  case 0x12:
161    card = "Cable TV";
162    reader[ridx].caid[0] = 0x4ae0;  //TODO not sure about this one
163    mode = 41;          //TODO not sure
164    break;
165  case 0x14:
166    card = "Tricolor Syberia / Platforma HD new";
167    reader[ridx].caid[0] = 0x4ae1;
168    mode = 51;
169    break;          //59 type card
170  case 0x15:
171    card = "Platforma HD / DW old";
172    reader[ridx].caid[0] = 0x4ae1;  //TODO not sure
173    mode = 41;          //TODO not sure
174    break;          //59 type card
175  default:
176    card = "Unknown";
177    reader[ridx].caid[0] = 0x4ae1;  //TODO: what is sensible value here?
178    mode = 51;
179    break;
180  }
181
182  memset (reader[ridx].prid, 0x00, 8);
183
184  static uchar cmd30[] =
185    { 0x30, 0x81, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05, 0x06, 0x87, 0x08, 0x09, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05,
186    0x00
187  };
188  dre_cmd (cmd30);      //unknown command, generates error on card 0x11 and 0x14
189/*
190response:
19159 03 E2 E3
192FE 48 */
193
194  static uchar cmd54[] = { 0x54, 0x14 };    // geocode
195  cmd54[1] = provider;
196  uchar geocode = 0;
197  if ((dre_cmd (cmd54)))    //error would not be fatal, like on 0x11 cards
198    geocode = cta_res[3];
199
200  providers[1] = provider;
201  if (!(dre_cmd (providers)))
202    return 0;           //fatal error
203  if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
204    return 0;
205  uchar provname[128];
206  for (i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++) {
207    provname[i] = cta_res[6 + i];
208    if (provname[i] == 0x00)
209      break;
210  }
211  int major_version = cta_res[3];
212  int minor_version = cta_res[4];
213
214  ua[1] = provider;
215  dre_cmd (ua);         //error would not be fatal
216
217  int hexlength = cta_res[1] - 2;   //discard first and last byte, last byte is always checksum, first is answer code
218
219  reader[ridx].hexserial[0] = 0;
220  reader[ridx].hexserial[1] = 0;
221  memcpy (reader[ridx].hexserial + 2, cta_res + 3, hexlength);
222
223  int low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
224  int dre_chksum = 0;
225  uchar buf[32];
226  sprintf (buf, "%i%i%08i", provider - 16, major_version + 1, low_dre_id);
227  for (i = 0; i < 32; i++) {
228    if (buf[i] == 0x00)
229      break;
230    dre_chksum += buf[i] - 48;
231  }
232
233  //cs_ri_log("type: DRECrypt, caid: %04X, serial: %llu, card: v%x",
234  cs_log ("type: DRECrypt, caid: %04X, serial: %s, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
235      reader[ridx].caid[0], cs_hexdump (0, reader[ridx].hexserial + 2, 4), dre_chksum, provider - 16,
236      major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
237  cs_log ("Provider name:%s.", provname);
238
239
240  memset (reader[ridx].sa, 0, sizeof (reader[ridx].sa));
241  memcpy (reader[ridx].sa[0], reader[ridx].hexserial + 2, 1);   //copy first byte of unique address also in shared address, because we dont know what it is...
242
243  cs_log ("DEBUG: SA = %02X%02X%02X%02X, UA = %s", reader[ridx].sa[0][0], reader[ridx].sa[0][1], reader[ridx].sa[0][2],
244      reader[ridx].sa[0][3], cs_hexdump (0, reader[ridx].hexserial + 2, 4));
245
246  //reader[ridx].nprov = 1; TODO doesnt seem necessary
247
248  if (!dre_set_provider_info ())
249    return 0;           //fatal error
250
251
252  /* Unknown function 51
253     59
254     23 51 82 3B 05 00 4A D4 CA
255     A3 1D A2
256     DF 95 29 90 65 E1 95 B8 1C 91 87 C8 B5 CB 62 2F
257     09
258     F7 BC 18 BA 14  some byte seems to be missing !?!
259
260     ANOTHER INS is the same except last line:
261     EF C7 1D 4C E3 14 last byte stays the same = provider byte???
262
263     response: DW info retour
264     59 12 D2 8E 7A FE BA 6C DF 31 49
265     1A 8F 34
266     98 48 42 CE 0D DE
267     90 00 */
268
269
270  //memcpy(&reader[ridx].prid[i][2], cta_res, 2);
271
272//############### PLAYGROUND ////
273
274//from bbs, provider = 15???
275//static uchar ecmtest[] = { 0x51, 0x01, 0x56, 0x00, 0x00, 0x48, 0xC6, 0xF0, 0x19, 0x01, 0xD4, 0xDF, 0x4F, 0xD7, 0x91, 0x55, 0x68, 0x02, 0x72, 0xF7, 0x98, 0x28, 0xBD, 0x78, 0x8E, 0x4E, 0xE8, 0xED, 0x0B, 0x51, 0xBF, 0xA4, 0x4E, 0x15 };
276//from log, works:
277//static uchar ecmtest[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, 0x9C, 0xDA, 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, 0x14 };
278/*  static uchar ecmtest[] =
279    { 0x51, 0x03, 0x56, 0x05, 0x00, 0x4A, 0xE4, 0x58, 0x02, 0x8B, 0xAE, 0x42, 0xEE, 0xE2, 0x6A, 0x7F, 0x51, 0xE0, 0x7D,
2800xCE, 0x20, 0x8A, 0x24, 0xE8, 0xBA, 0xA6, 0xC3, 0xCB, 0x35, 0x45, 0x35, 0x52, 0x94, 0x14 };
281*/
282//from platforma itself through dvbviewer
283/*
284  static uchar ecmtest[] =
285    { 0x51, 0x02, 0x56, 0x00, 0x00, 0x4A, 0xEC, 0x00, 0xAA, 0x31, 0x39, 0x06, 0x57, 0x94, 0x55, 0x1D, 0x23, 0x52, 0x88,
2860x3D, 0xA8, 0x62, 0xDC, 0xA2, 0x98, 0xD7, 0xAB, 0x0D, 0x80, 0x60, 0x15, 0xF5, 0x07, 0x14 };
287*/
288  //from redirected dvbviewer
289  static uchar ecmtest[] =
290    { 0x51, 0x02, 0x56, 0x00, 0x00, 0x4A, 0xEC, 0x3B, 0xF6, 0x56, 0x5A, 0x43, 0x95, 0x43, 0x05, 0x02, 0xBB, 0x46, 0x22,
291    0x27, 0xEF, 0x33, 0xF4, 0xA9, 0xD0, 0x65, 0xDB, 0x57, 0x8F, 0x8F, 0x7C, 0x19, 0x36, 0x14
292  };
293
294//rest: 0x93, 0x36, 0x58, 0xC9
295
296
297  //ecmcmd51[33]=provider; //FIXME part of signatur
298
299//int hans, index, save;
300//for (index=1; index<3; index++) {
301//  save = ecmtest[index];
302//  for (hans=0; hans<256; hans++) {
303//   ecmtest[index] = hans;
304//    if ((dre_cmd(ecmtest)))
305//      cs_log("HANS SUCCESS");
306//  }
307//  ecmtest[index] = save;
308//}
309
310  EMM_PACKET *eptmp;
311  eptmp = malloc (sizeof (EMM_PACKET));
312//  static unsigned char tempser[] = { 0, 0, 0xC8, 0x4D, 0x25, 0x5A };
313//  memcpy (reader[ridx].hexserial, tempser, 8);
314  dre_do_emm (eptmp);
315  free (eptmp);
316//############### PLAYGROUND ////
317  cs_log ("ready for requests");
318  return (1);
319}
320
321/*
322static int get_prov_index (char *provid)    //returns provider id or -1 if not found
323{
324  int prov;
325  for (prov = 0; prov < reader[ridx].nprov; prov++) //search for provider index
326    if (!memcmp (provid, &reader[ridx].prid[prov][2], 2))
327      return (prov);
328  return (-1);
329}
330*/
331
332int dre_do_ecm (ECM_REQUEST * er)
333{
334  //
335  //cmd41 is not known for card provider 0x14 ???
336  if (mode == 41) {
337    static uchar ecmcmd41[] = { 0x41,
338      0x58, 0x1f, 0x00,     //fixed part, dont change
339      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   //0x01 - 0x08: next key
340      0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,   //0x11 - 0x18: current key
341      0x3b, 0x59, 0x11      //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
342    };
343    ecmcmd41[22] = provider;
344    memcpy (ecmcmd41 + 4, er->ecm + 8, 16);
345    ecmcmd41[20] = er->ecm[6];  //keynumber
346    ecmcmd41[21] = 0x58 + er->ecm[25];  //package number
347    cs_debug ("DEBUG: unused ECM info front:%s", cs_hexdump (0, er->ecm, 8));
348    cs_debug ("DEBUG: unused ECM info back:%s", cs_hexdump (0, er->ecm + 24, er->ecm[2] + 2 - 24));
349    if ((dre_cmd (ecmcmd41))) { //ecm request
350      if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
351    return (0);     //exit if response is not 90 00 //TODO: if response is 9027 ppv mode is possible!
352      //memcpy(er->cw,cta_res+3,16);
353      //or swap bytes:
354      memcpy (er->cw, cta_res + 11, 8);
355      memcpy (er->cw + 8, cta_res + 3, 8);
356
357      //  return 0; //FIXME only used for testing CWs
358      return 1;
359    }
360  }
361  else {
362
363    //cmd51 is used for provider 0x14
364    static uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3,   //fixed header?
365      0x9C, 0xDA,       //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
366      0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E,   //next key?
367      0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD,   //current key?
368      0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11,   //key or signature?
369      0x14          //provider
370    };
371    memcpy (ecmcmd51 + 1, er->ecm + 5, 0x21);
372    //cs_log ("DEBUG: ECM: %s", cs_hexdump (0, er->ecm, er->ecm[2] + 3));
373    cs_debug ("DEBUG: unused ECM info front:%s", cs_hexdump (0, er->ecm, 5));
374    cs_debug ("DEBUG: unused ECM info back:%s", cs_hexdump (0, er->ecm + 37, 4));
375    ecmcmd51[33] = provider;    //no part of sig
376    if ((dre_cmd (ecmcmd51))) { //ecm request
377      if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
378    return (0);     //exit if response is not 90 00 //TODO: if response is 9027 ppv mode is possible!
379      //memcpy(er->cw,cta_res+3,16);
380      //or swap bytes:
381      memcpy (er->cw, cta_res + 11, 8);
382      memcpy (er->cw + 8, cta_res + 3, 8);
383
384      //  return 0; //FIXME only used for testing CWs
385      return 1;
386    }
387  }
388  return 0;
389}
390
391int dre_do_emm (EMM_PACKET * ep)
392{
393  //return 0;                   //FIXME STUB
394  /*
395  uchar emmtest[] = { 0x87, 0x00, 0x8C, 0xC8, 0x4D, 0x25, 0x5A, 0x02, 0xA9, 0xA5, 0x34, 0x31, 0xAB, 0x9C, 0x9B, 0x59,
396    0x5D, 0x47, 0x95, 0xB3, 0xB1, 0x61, 0x47, 0xE6, 0x85, 0xE0, 0x17, 0xC8, 0x25, 0x70, 0x59, 0x73,
397    0x12, 0x1F, 0x2B, 0x9B, 0x02, 0x5A, 0x9D, 0x3A, 0x05, 0x56, 0x85, 0x58, 0x00, 0xC8, 0x4D, 0x25,
398    0x5A, 0x06, 0x02, 0x23, 0xB4, 0x37, 0x1E, 0xE0, 0x7E, 0x59, 0xFC, 0x38, 0xCA, 0x13, 0x21, 0x0D,
399    0x3E, 0x09, 0xDF, 0xB4, 0x45, 0x6C, 0x99, 0x7E, 0x3E, 0xDA, 0xA4, 0xC7, 0xB9, 0x7B, 0xAB, 0x4A,
400    0xB5, 0xE2, 0x1D, 0xA3, 0xCD, 0x03, 0xAF, 0xDA, 0xBA, 0xEA, 0x3B, 0x85, 0x58, 0x00, 0xC8, 0x4D,
401    0x25, 0x5A, 0x05, 0xF4, 0xAF, 0x8B, 0x8F, 0x2F, 0x6C, 0xF2, 0x43, 0x8C, 0x86, 0x03, 0xFD, 0x1C,
402    0xDF, 0x7A, 0xE4, 0xB6, 0x0B, 0xF9, 0x70, 0x72, 0xFC, 0x2A, 0xEC, 0x0F, 0x6D, 0x8D, 0x82, 0xC6,
403    0x4C, 0x16, 0x81, 0xDC, 0xC9, 0x3C, 0x34, 0x84, 0x35, 0x9A, 0xA7, 0xED, 0xB1, 0x39, 0xBC
404  }; //UNIQE EMM
405*/
406
407  uchar emmtest[] = { 0x89, 0x00, 0x68, 0x00, 0x4D, 0x56, 0x85, 0x58, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x58,
408    0x89, 0x04, 0x3A, 0xEE, 0x15, 0xB1, 0x38, 0x4A, 0x75, 0x5A, 0x21, 0xEE, 0x4D, 0x37, 0xF3, 0x53,
409    0xF8, 0xAC, 0x1F, 0x8D, 0xEA, 0xDF, 0x12, 0x73, 0x00, 0x69, 0xBB, 0x67, 0x5D, 0x8A, 0x96, 0x2D,
410    0x1C, 0x08, 0xEB, 0xF1, 0xCA, 0x40, 0x3B, 0x85, 0x58, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x85,
411    0xF2, 0xE1, 0xD9, 0x86, 0xEA, 0x19, 0x6A, 0xEF, 0x3B, 0x9D, 0x0C, 0xEA, 0xF3, 0x7B, 0x74, 0xE5,
412    0xF7, 0x4F, 0xD6, 0x9C, 0x85, 0x6C, 0x7E, 0x79, 0xDF, 0x18, 0xD1, 0xC3, 0x54, 0xA9, 0x47, 0xCB,
413    0xAC, 0xB6, 0x18, 0x71, 0xC8, 0x69, 0x6B, 0x10, 0xFF, 0x9D, 0x11 }; //GLOBAL EMM
414
415  memcpy (ep->emm, emmtest, 0x8f);
416
417  int emm_length = ((ep->emm[1] & 0x0f) << 8) + ep->emm[2];
418
419  cs_ddump (ep->emm, emm_length + 3, "EMM:");
420  ep->type = ep->emm[0];
421  cs_debug ("ep->type%x", ep->type);
422
423  if (mode != 41) {
424    cs_log ("EMM Mode not implemented yet");
425    return 0;
426  }
427
428  static 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
436  switch (ep->type) {
437  case 0x88:            //shared EMM
438    {
439      cs_debug ("HANS: checkpoint 1");
440      if (memcmp (ep->emm + 9, reader[ridx].sa[0], 1)) {    //in case of SHARED EMM, only first byte has to match?
441    cs_log ("EMM: Shared update did not match; EMM SA:%02X%02X%02X%02X, Reader SA:%s.", ep->emm[9], ep->emm[10],
442        ep->emm[11], ep->emm[12], cs_hexdump (0, reader[ridx].sa[0], 4));
443    return (0);
444      }
445      else {
446    cs_log ("EMM: Shared update matched for EMM SA %02X%02X%02X%02X.", ep->emm[9], ep->emm[19], ep->emm[11],
447        ep->emm[12]);
448      }
449      /*
450         01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
451         88 00 68 C8 4D 56 85 58 01 C8 00 00 00 05 B8 0C
452
453         17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 --
454         BD 7B 07 04 C8 77 31 95 F2 30 B7 E9 EE 0F 81 39
455
456         33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 --
457         1C 1F A9 11 3E E5 0E 8E 50 A4 31 BB 01 00 D6 AF
458
459         49 50 51 52 53 54X55 56 57 58 59 60 61 62 63 64 --
460         69 60 04 70 3A 91 3B 85 58 01 C8 00 00 00 05 B1
461
462         65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 --
463         3F BF A0 05 6E BD AB 0A 70 77 30 C2 AC EC 06 C2
464
465         81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 --
466         3D 47 50 8D B1 77 68 62 6B 26 6B CE A9 EF 1B 6A
467
468         97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 --
469         DF 7B 39 52 A4 5A 0E B0 A6 ED 7B DC 82 3C AE A3
470
471         Here we have:
472
473         Bytes ...
474         01 (88) - EMM filter can be a value 87
475         03 (68) - length of data EMM
476         04 (C8) - the number of SA for the filter (C8 - is a map)
477         06 (56) - index kriptodannyh (56/3B alternate) are likely key number
478
479         07 (85) - choice of algorithm (8x - MSP / 4x - Atmel), in the cards until only 85
480         08 (01) - the type of EMM (00 - EMM_U, solo / 01 - EMM_S, group)
481         10 - 13 (C8 00 00 00) - here only for SA EMM_S
482         14 (05) - additional flags
483         15 - 54 (V8. .. 91) own body EMM, information about the key.
484         55 (3B) may be a checksum.
485
486         Bytes 56 - 104 - for the second key.
487         Appointment of the remaining bytes is unknown.
488       */
489    }               // end shared EMM NO BREAK so rest happens in global EMM
490  case 0x89:            //global EMM ??
491    {
492      if (ep->type == 0x89)
493    cs_log ("EMM: Global update");
494      /* 89 00 68 00 4D 56 85 58 01 00 00 00 00 06 29 58
495       * 89 04 3A EE 15 B1 38 4A 75 5A 21 EE 4D 37 F3 53
496       * F8 AC 1F 8D EA DF 12 73 00 69 BB 67 5D 8A 96 2D
497       * 1C 08 EB F1 CA 40X3BX85 58 01 00 00 00 00 05 85
498       * F2 E1 D9 86 EA 19 6A EF 3B 9D 0C EA F3 7B 74 E5
499       * F7 4F D6 9C 85 6C 7E 79 DF 18 D1 C3 54 A9 47 CB
500       * AC B6 18 71 C8 69 6B 10 FF 9D 11
501       */
502      memcpy (emmcmd42 + 1, ep->emm + 6, 48);
503      emmcmd42[51] = provider;
504      //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
505      emmcmd42[49] = ep->emm[5];    //keynr
506      /* response:
507         59 05 A2 02 05 01 5B
508         90 00 */
509      cs_debug ("HANS: checkpoint 5");
510      if ((dre_cmd (emmcmd42))) {   //first emm request
511    if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
512      return (0);       //exit if response is not 90 00
513
514    cs_debug ("HANS: checkpoint 6");
515    memcpy (emmcmd42 + 1, ep->emm + 55, 7);
516    memcpy (emmcmd42 + 8, ep->emm + 67, 41);
517    emmcmd42[51] = provider;
518    //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
519    emmcmd42[49] = ep->emm[54]; //keynr
520    if ((dre_cmd (emmcmd42))) { //second emm request
521      if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
522        return (0);     //exit if response is not 90 00
523      return 1;     //success
524    }
525      }
526
527      break;
528    }               //end global EMM
529  case 0x87:            //unique EMM
530    {
531      /*
532         0x87, 0x00, 0x8C, ser1, ser2, ser3, ser4, 0x02, 0xA9, 0xA5, 0x34, 0x31, 0xAB, 0x9C, 0x9B, 0x59,
533         0x5D, 0x47, 0x95, 0xB3, 0xB1, 0x61, 0x47, 0xE6, 0x85, 0xE0, 0x17, 0xC8, 0x25, 0x70, 0x59, 0x73,
534         0x12, 0x1F, 0x2B, 0x9B, 0x02, 0x5A, 0x9D, 0x3A, 0x05, 0x56, 0x85, 0x58, 0x00, 0xC8, 0x4D, 0x25,
535         0x5A, 0x06, 0x02, 0x23, 0xB4, 0x37, 0x1E, 0xE0, 0x7E, 0x59, 0xFC, 0x38, 0xCA, 0x13, 0x21, 0x0D,
536         0x3E, 0x09, 0xDF, 0xB4, 0x45, 0x6C, 0x99, 0x7E, 0x3E, 0xDA, 0xA4, 0xC7, 0xB9, 0x7B, 0xAB, 0x4A,
537         0xB5, 0xE2, 0x1D, 0xA3, 0xCD, 0x03, 0xAF, 0xDA, 0xBA, 0xEA, 0x3B, 0x85, 0x58, 0x00, 0xC8, 0x4D,
538         0x25, 0x5A, 0x05, 0xF4, 0xAF, 0x8B, 0x8F, 0x2F, 0x6C, 0xF2, 0x43, 0x8C, 0x86, 0x03, 0xFD, 0x1C,
539         0xDF, 0x7A, 0xE4, 0xB6, 0x0B, 0xF9, 0x70, 0x72, 0xFC, 0x2A, 0xEC, 0x0F, 0x6D, 0x8D, 0x82, 0xC6,
540         0x4C, 0x16, 0x81, 0xDC, 0xC9, 0x3C, 0x34, 0x84, 0x35, 0x9A, 0xA7, 0xED, 0xB1, 0x39, 0xBC
541       */
542      cs_debug ("HANS: checkpoint 2");
543      //first test if UA matches
544      if (memcmp (reader[ridx].hexserial + 2, ep->emm + 3, 4)) {
545    cs_log ("EMM: Unique update did not match; EMM Serial:%02X%02X%02X%02X, Reader Serial:%s.", ep->emm[3],
546        ep->emm[4], ep->emm[5], ep->emm[6], cs_hexdump (0, reader[ridx].hexserial + 2, 4));
547    return (0);
548      }
549      else {
550    cs_log ("EMM: Unique update matched EMM Serial:%02X%02X%02X%02X.", ep->emm[3], ep->emm[4], ep->emm[5],
551        ep->emm[6]);
552    cs_log ("EMM: layout of EMM 0x87 unknown, cannot be processed yet.");
553      }
554      break;
555    }               //end unique EMM
556  default:
557    cs_log
558      ("EMM: Congratulations, you have discovered a new EMM type on DRECRYPT. This has not been decoded yet, so send this output to authors:");
559    cs_dump (ep->emm, emm_length + 3, "EMM:");
560    return 0;           //unknown
561  }             //end of switch
562
563
564  cs_debug ("HANS: checkpoint 3");
565  return 0;
566}
567
568int dre_card_info (void)
569{
570  return (1);
571}
Note: See TracBrowser for help on using the repository browser.