revert breaks some stupid old compilers
[oscam.git] / reader-dre.c
blobd65e17c35fa9dd62a5ee21319c47aabfde44dfa5
1 #include "globals.h"
2 #ifdef READER_DRE
3 #include "cscrypt/des.h"
4 #include "reader-common.h"
5 #include "reader-dre-common.h"
7 struct dre_data
9 uint8_t provider;
12 #define OK_RESPONSE 0x61
13 #define CMD_BYTE 0x59
15 static uchar xor(const uchar *cmd, int32_t cmdlen)
17 int32_t i;
18 uchar checksum = 0x00;
19 for(i = 0; i < cmdlen; i++)
20 { checksum ^= cmd[i]; }
21 return checksum;
24 static int8_t isValidDCW(uint8_t *dw)
26 if (((dw[0]+dw[1]+dw[2]) & 0xFF) != dw[3])
28 return 0;
30 if (((dw[4]+dw[5]+dw[6]) & 0xFF) != dw[7])
32 return 0;
34 if (((dw[8]+dw[9]+dw[10]) & 0xFF) != dw[11])
36 return 0;
38 if (((dw[12]+dw[13]+dw[14]) & 0xFF) != dw[15])
40 return 0;
42 return 1;
45 static int32_t dre_command(struct s_reader *reader, const uchar *cmd, int32_t cmdlen, unsigned char *cta_res, uint16_t *p_cta_lr,
46 uint8_t crypted, uint8_t keynum, uint8_t dre_v, uint8_t cmd_type)
47 //attention: inputcommand will be changed!!!! answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
49 uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 }; //any command starts with this,
50 //last byte is nr of bytes of the command that will be sent
51 //after the startcmd
52 //response on startcmd+cmd: = { 0x61, 0x05 } //0x61 = "OK", last byte is nr. of bytes card will send
53 uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 }; //after command answer has to be requested,
54 //last byte must be nr. of bytes that card has reported to send
55 uchar command[256];
56 uchar checksum;
57 char tmp[256];
58 int32_t headerlen = sizeof(startcmd);
60 if(dre_v > 0)
62 startcmd[1] = 0;
63 startcmd[2] = crypted;
64 startcmd[3] = keynum;
67 startcmd[4] = cmdlen + 3 - cmd_type; //commandlength + type + len + checksum bytes
68 memcpy(command, startcmd, headerlen);
69 command[headerlen++] = cmd_type ? 0x86 : CMD_BYTE; //type
70 command[headerlen++] = cmdlen + (cmd_type == 1 ? 0 : 1); //len = command + 1 checksum byte
71 memcpy(command + headerlen, cmd, cmdlen);
73 if(!cmd_type)
75 checksum = ~xor(cmd, cmdlen);
76 //rdr_log_dbg(reader, D_READER, "Checksum: %02x", checksum);
77 cmdlen += headerlen;
78 command[cmdlen++] = checksum;
80 else cmdlen += headerlen;
82 reader_cmd2icc(reader, command, cmdlen, cta_res, p_cta_lr);
84 if((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE))
86 rdr_log(reader, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
87 rdr_log(reader, "unexpected answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
88 return ERROR; //error
91 rdr_log_dbg(reader, D_READER, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
92 rdr_log_dbg(reader, D_READER, "answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
94 reqans[4] = cta_res[1]; //adapt length byte
95 reader_cmd2icc(reader, reqans, 5, cta_res, p_cta_lr);
97 if(cta_res[0] != CMD_BYTE)
99 rdr_log(reader, "unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
100 return ERROR;
103 if((cta_res[1] == 0x03) && (cta_res[2] == 0xe2))
105 switch(cta_res[3+dre_v])
107 case 0xe1:
108 rdr_log(reader, "checksum error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
109 break;
110 case 0xe2:
111 rdr_log(reader, "wrong cmd len: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
112 break;
113 case 0xe3:
114 rdr_log(reader, "illegal command: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
115 break;
116 case 0xe4:
117 rdr_log(reader, "wrong adress type: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
118 break;
119 case 0xe5:
120 rdr_log(reader, "wrong CMD param: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
121 break;
122 case 0xe6:
123 rdr_log(reader, "wrong UA: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
124 break;
125 case 0xe7:
126 rdr_log(reader, "wrong group: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
127 break;
128 case 0xe8:
129 rdr_log(reader, "wrong key num: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
130 break;
131 case 0xeb:
132 rdr_log(reader, "No key or subscribe : %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
133 break;
134 case 0xec:
135 rdr_log(reader, "wrong signature: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
136 break;
137 case 0xed:
138 rdr_log(reader, "wrong provider: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
139 break;
140 case 0xef:
141 rdr_log(reader, "wrong GEO code: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
142 break;
143 default:
144 rdr_log_dbg(reader, D_READER, "unknown error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
145 break;
147 return ERROR; //error
150 int32_t length_excl_leader = *p_cta_lr;
152 if((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
153 { length_excl_leader -= 2; }
155 checksum = ~xor(cta_res + 2, length_excl_leader - 3);
157 if(cta_res[length_excl_leader - 1] != checksum)
159 rdr_log(reader, "checksum does not match, expected %02x received %02x:%s", checksum,
160 cta_res[length_excl_leader - 1], cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
161 return ERROR; //error
163 return OK;
166 #define dre_script(cmd, len, cmd_type, crypted, keynum) \
168 dre_command(reader, cmd, len, cta_res, &cta_lr, crypted, keynum, crypted, cmd_type); \
171 #define dre_cmd(cmd) \
173 dre_command(reader, cmd, sizeof(cmd), cta_res, &cta_lr, 0, 0, 0, 0); \
176 #define dre_cmd_c(cmd,crypted,keynum) \
178 dre_command(reader, cmd, sizeof(cmd),cta_res,&cta_lr, crypted, keynum, 1, 0); \
181 static int32_t dre_set_provider_info(struct s_reader *reader)
183 def_resp;
184 int32_t i;
185 int subscr_cmd_len = 4;
186 uchar subscr[4];// = { 0x59, 0x14 }; // subscriptions
187 uchar dates[] = { 0x5b, 0x00, 0x14 }; //validity dates
188 uchar subscr_len = 0, n = 0;
189 struct dre_data *csystem_data = reader->csystem_data;
191 cs_clear_entitlement(reader);
193 switch(csystem_data->provider)
195 case 0x02:
196 case 0x03:
197 subscr[0] = 0x84;
198 subscr[1] = 0;
199 subscr[2] = 0x5F;
200 subscr[3] = csystem_data->provider;
201 dates[0] = 0x85;
202 subscr_len = 0x5F;
203 break;
204 case 0x18:
205 case 0x19:
206 case 0x1A:
207 subscr[0] = 0x94;
208 subscr[1] = 0;
209 subscr[2] = 0x5F;
210 subscr[3] = csystem_data->provider;
211 dates[0] = 0x95;
212 subscr_len = 0x5F;
213 break;
214 default:
215 subscr[0] = 0x59;
216 subscr[1] = csystem_data->provider;
217 subscr_len = 0x20;
218 subscr_cmd_len = 2;
221 chk_subscr:
223 if((dre_script(subscr, subscr_cmd_len, 0, 0, 0))) //ask subscription packages, returns error on 0x11 card
225 uchar pbm[subscr_len];
226 char tmp_dbg[subscr_len*2+1];
227 memcpy(pbm, cta_res + 3, cta_lr - 6);
228 rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, subscr_len, tmp_dbg, sizeof(tmp_dbg)));
230 for(i = 0; i < subscr_len; i++)
231 if(pbm[i] != 0xff)
233 dates[1] = i;
234 dates[2] = csystem_data->provider;
235 dre_cmd(dates); //ask for validity dates
237 time_t start;
238 time_t end;
239 start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
240 end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];
242 struct tm temp;
244 localtime_r(&start, &temp);
245 int32_t startyear = temp.tm_year + 1900;
246 int32_t startmonth = temp.tm_mon + 1;
247 int32_t startday = temp.tm_mday;
248 localtime_r(&end, &temp);
249 int32_t endyear = temp.tm_year + 1900;
250 int32_t endmonth = temp.tm_mon + 1;
251 int32_t endday = temp.tm_mday;
252 rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i+n, startyear, startmonth, startday,
253 endyear, endmonth, endday);
254 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, i+n, start, end, 5, 1);
258 if(subscr_len == 0x5F) // read second part subscription packages, for DRE3 and DRE4
260 subscr[1] = 0x5F;
261 subscr[2] = 0x21;
262 subscr_len = 0x21;
263 n = 0x5F;
264 goto chk_subscr;
267 return OK;
270 static void dre_read_ee(struct s_reader *reader, const char *path, uchar provid)
272 def_resp;
273 int i, n;
274 uchar *ee = malloc(2048);
275 if(ee == NULL) return;
277 uchar drecmd43[] = { 0x80, 0x00, 0x00, 0x00, 0x05, 0x59, 0x03, 0x43, 0x11, 0xAD };
278 uchar drecmd45[] = { 0x45, 0x11 };
280 drecmd43[8] = drecmd45[1] = provid;
281 drecmd43[9] = ~xor(&drecmd43[7], 2);
284 for(i = 0; i < 8; i++)
286 for(n = 0; n < 8; n++)
288 reader_cmd2icc(reader, drecmd43, 10, cta_res, &cta_lr);
290 dre_cmd_c(drecmd45, n, i*32);
292 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
294 free(ee);
295 rdr_log(reader, "ERROR read ee.bin from card");
296 return;
299 memcpy(&ee[((n*8)+i)*32] ,&cta_res[2] ,32);
304 FILE *pFile = fopen(path, "wb");
306 if(pFile == NULL)
308 free(ee);
309 return ;
312 fwrite(ee, 2048, 1, pFile);
313 fclose(pFile);
314 free(ee);
315 rdr_log(reader, "ee.bin saved to %s", path);
318 static void cmd_test(struct s_reader *reader)
320 def_resp;
321 int i;
322 uchar drecmd[] = { 0x00, 0x02 };
323 char tmp[64];
325 for(i = 0; i <= 0xFF; i++)
327 if(i == 0x45) continue;
328 drecmd[0] = i;
329 dre_cmd(drecmd);
330 if(cta_res[2] == 0xE2)
332 if(cta_res[3] != 0xE3) rdr_log(reader, "cmd %02X error %02X",i ,cta_res[3]);
334 else
336 rdr_log(reader, "cmd %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
340 uchar drecmd[64];
342 //memset(drecmd, 0, 64);
343 //drecmd[0] = 0x71;
344 for(i = 2; i <= 64; i++)
346 memset(drecmd, 0, 64);
347 drecmd[i-1] = 0x02;
348 drecmd[0] = 0x71;
350 dre_script(drecmd, i, 0, 0, 0);
352 if(cta_res[2] == 0xE2)
354 if((cta_res[3] != 0xE2) & (cta_res[3] != 0xED)) rdr_log(reader, "Len %02X error %02X",i ,cta_res[3]);
355 if((cta_res[3] & 0xF0) != 0xE0) rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
357 else
359 rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
364 static int32_t dre_card_init(struct s_reader *reader, ATR *newatr)
366 get_atr;
367 def_resp;
368 uchar ua[] = { 0x43, 0x15 }; // get serial number (UA)
369 uchar providers[] = { 0x49, 0x15 }; // get providers
370 uchar cmd56[] = { 0x56, 0x00 };
371 int32_t i;
372 char *card;
373 char tmp[9];
375 if((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12) || (
376 ((atr[4] != 0x01) || (atr[5] != 0x01)) &&
377 ((atr[4] != 0xca) || (atr[5] != 0x07)) &&
378 ((atr[4] != 0xcb) || (atr[5] != 0x07)) &&
379 ((atr[4] != 0xcc) || (atr[5] != 0x07)) &&
380 ((atr[4] != 0xcd) || (atr[5] != 0x07))
382 { return ERROR; }
384 if(!cs_malloc(&reader->csystem_data, sizeof(struct dre_data)))
385 { return ERROR; }
386 struct dre_data *csystem_data = reader->csystem_data;
388 csystem_data->provider = atr[6];
389 uchar checksum = xor(atr + 1, 6);
391 if(checksum != atr[7])
392 { rdr_log(reader, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]); }
394 switch(atr[6])
396 case 0:
398 if(!(dre_cmd(cmd56))) { return ERROR; }
399 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; }
401 switch(cta_res[4])
403 case 0x02:
404 card = "Tricolor Centr DRE3";
405 reader->caid = 0x4ae1;
406 break;
407 case 0x03:
408 card = "Tricolor Syberia DRE3";
409 reader->caid = 0x4ae1;
410 break;
411 case 0x18:
412 case 0x19:
413 card = "Tricolor Centr DRE4";
414 reader->caid = 0x2710;
415 break;
416 case 0x1A:
417 card = "Tricolor Syberia DRE4";
418 reader->caid = 0x2710;
419 break;
420 default:
421 return ERROR;
423 csystem_data->provider = cta_res[4];
424 providers[0] = 0x83;
425 break;
426 case 0x11:
427 card = "Tricolor Centr DRE2";
428 reader->caid = 0x4ae1;
429 break; //59 type card = MSP (74 type = ATMEL)
430 case 0x12:
431 card = "Cable TV";
432 reader->caid = 0x4ae1; //TODO not sure about this one
433 break;
434 case 0x14:
435 card = "Tricolor Syberia DRE2";
436 reader->caid = 0x4ae1;
437 break; //59 type card
438 case 0x15:
439 card = "Platforma HD / DW old";
440 reader->caid = 0x4ae1;
441 break; //59 type card
442 default:
443 return ERROR;
446 memset(reader->prid, 0x00, 8);
448 if(atr[6] > 0)
450 reader->prid[0][3] = atr[6];
452 else
454 reader->prid[0][3] = csystem_data->provider;
457 uchar cmd54[] = { 0x54, 0x14 }; // geocode
458 cmd54[1] = csystem_data->provider;
459 uchar geocode = 0;
460 if((dre_cmd(cmd54))) //error would not be fatal, like on 0x11 cards
461 { geocode = cta_res[3]; }
463 providers[1] = csystem_data->provider;
464 if(!(dre_cmd(providers)))
465 { return ERROR; } //fatal error
466 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
467 { return ERROR; }
469 uchar provname[128];
470 for(i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++)
472 provname[i] = cta_res[6 + i];
473 if(provname[i] == 0x00)
474 { break; }
477 int32_t major_version = cta_res[3];
478 int32_t minor_version = cta_res[4];
480 ua[1] = csystem_data->provider;
481 dre_cmd(ua); //error would not be fatal
483 int32_t hexlength = cta_res[1] - 2; //discard first and last byte, last byte is always checksum, first is answer code
485 if(reader->force_ua)
487 rdr_log(reader, "WARNING!!!! used UA from force_ua %08X", reader->force_ua);
488 memcpy(cta_res + 3, &reader->force_ua, 4);
491 reader->hexserial[0] = 0;
492 reader->hexserial[1] = 0;
493 memcpy(reader->hexserial + 2, cta_res + 3, hexlength);
495 int32_t low_dre_id, dre_chksum;
496 uchar buf[32];
498 if(major_version < 0x3)
500 low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
501 dre_chksum = 0;
502 snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider - 16, major_version + 1, low_dre_id);
504 for(i = 0; i < 32; i++)
506 if(buf[i] == 0x00)
507 { break; }
508 dre_chksum += buf[i] - 48;
511 if(major_version < 2)
513 reader->caid = 0x4ae0;
514 card = csystem_data->provider == 0x11 ? "Tricolor Centr DRE1" : "Tricolor Syberia DRE1";
517 rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
518 reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider - 16,
519 major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
521 else
523 low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]);
524 dre_chksum = 0;
525 snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider, major_version, low_dre_id);
527 for(i = 0; i < 32; i++)
529 if(buf[i] == 0x00)
530 { break; }
531 dre_chksum += buf[i] - 48;
533 rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%03i%i%08i, geocode %i, card: %s v%i.%i",
534 reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider,
535 major_version, low_dre_id, geocode, card, major_version, minor_version);
538 rdr_log(reader, "Provider name:%s.", provname);
541 memset(reader->sa, 0, sizeof(reader->sa));
542 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...
544 rdr_log_sensitive(reader, "SA = %02X%02X%02X%02X, UA = {%s}", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
545 reader->sa[0][3], cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)));
547 reader->nprov = 1;
549 // cmd_test(reader);
551 // exec user script, wicardd format
552 if(reader->userscript != NULL)
554 uint8_t *usercmd = NULL;
555 int cmd_len;
556 int n;
557 char *tempbuf = malloc(2048);
558 trim2(reader->userscript);
559 FILE *pFile = fopen(reader->userscript, "rt");
561 if(pFile != NULL)
563 uchar ignoreProvid = 0;
564 uchar crypted = 0;
565 uchar cryptkey = 0;
568 tempbuf[0] = '\0';
569 if(usercmd != NULL) free(usercmd);
571 if(fgets(tempbuf, 2048, pFile) == NULL) continue;
573 if(strlen(tempbuf) < 10) continue;
575 trim2(tempbuf);
577 ignoreProvid = 0;
578 crypted = 0;
579 cryptkey = 0;
581 if(tempbuf[0] == '8' && tempbuf[1] == '6' && csystem_data->provider == 0x11) ignoreProvid = 1;
582 else if(strncmp(tempbuf ,"REG2" ,4) == 0)
584 dre_read_ee(reader, &tempbuf[4] ,csystem_data->provider);
585 continue;
587 else if(strncmp(tempbuf ,"CR" ,2) == 0)
589 crypted = 1;
590 cryptkey = ((tempbuf[2] - (tempbuf[2] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf[3] - (tempbuf[3] > 0x39 ? 0x37:0x30)) & 0xF);
592 else if(tempbuf[0] != '5' && tempbuf[1] != '9') continue;
594 strtoupper(tempbuf);
596 cmd_len = strlen(tempbuf) / 2 - 3 + ignoreProvid - (crypted * 2);
597 usercmd = malloc(cmd_len);
599 for(i=0,n= 4+(crypted * 4);i<cmd_len;i++,n+=2)
601 usercmd[i] = ((tempbuf[n] - (tempbuf[n] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf[n+1] - (tempbuf[n+1] > 0x39 ? 0x37:0x30)) & 0xF);
604 /*if(usercmd[cmd_len-1] != csystem_data->provider && !ignoreProvid)
606 rdr_log(reader, "Skip script: current provid %02X , script provid %02X", csystem_data->provider, usercmd[cmd_len-1]);
607 continue;
610 rdr_log(reader, "User script: %s", tempbuf);
612 /*ret =*/
614 rdr_log(reader, "Script %s", (dre_script(usercmd, cmd_len, ignoreProvid, crypted, cryptkey)) ? "done" : "error");
616 while(!feof(pFile));
618 else
620 rdr_log(reader, "Can't open script file (%s)", reader->userscript);
623 //if(usercmd != NULL) free(usercmd);
624 if(tempbuf != NULL) free(tempbuf);
627 if(csystem_data->provider == 0x11)
629 memset(reader->prid[1], 0x00, 8);
630 reader->prid[1][3] = 0xFE;
631 reader->nprov = 2;
634 if(!dre_set_provider_info(reader))
635 { return ERROR; } //fatal error
638 rdr_log(reader, "ready for requests");
639 return OK;
643 static void DREover(struct s_reader *reader, const uint8_t *ECMdata, uint8_t *DW)
645 uint32_t key_schedule[32];
647 if(reader->des_key_length < 128)
649 rdr_log(reader, "error: deskey is missing or too short");
650 return;
653 if(ECMdata[2] >= (43 + 4) && ECMdata[40] == 0x3A && ECMdata[41] == 0x4B)
655 des_set_key(&reader->des_key[(ECMdata[42] & 0x0F) * 8], key_schedule);
657 des(DW, key_schedule, 0); // even DW post-process
658 des(DW + 8, key_schedule, 0); // odd DW post-process
662 static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
664 def_resp;
665 uint16_t overcryptId;
666 uint8_t tmp[16];
667 char tmp_dbg[256];
668 struct dre_data *csystem_data = reader->csystem_data;
669 if(reader->caid == 0x4ae0)
671 uchar ecmcmd41[] = { 0x41,
672 0x58, 0x1f, 0x00, //fixed part, dont change
673 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //0x01 - 0x08: next key
674 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, //0x11 - 0x18: current key
675 0x3b, 0x59, 0x11 //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
677 ecmcmd41[22] = csystem_data->provider;
678 memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
679 ecmcmd41[20] = er->ecm[6]; //keynumber
680 ecmcmd41[21] = 0x58 + er->ecm[25]; //package number
681 rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
682 rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 24, er->ecm[2] + 2 - 24, tmp_dbg, sizeof(tmp_dbg)));
683 if((dre_cmd(ecmcmd41))) //ecm request
685 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
686 { return ERROR; } //exit if response is not 90 00
687 memcpy(ea->cw, cta_res + 11, 8);
688 memcpy(ea->cw + 8, cta_res + 3, 8);
690 return OK;
693 else if(reader->caid == 0x4ae1)
695 if(csystem_data->provider == 0x11 || csystem_data->provider == 0x14)
697 uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, //fixed header?
698 0x9C, 0xDA, //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
699 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, //next key?
700 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, //current key?
701 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, //key or signature?
702 0x14 //provider
704 memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
705 rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
706 rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
707 ecmcmd51[33] = csystem_data->provider; //no part of sig
709 if((dre_cmd(ecmcmd51))) //ecm request
711 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
712 { return ERROR; } //exit if response is not 90 00
714 if(er->ecm[2] >= 46 && er->ecm[43] == 1 && csystem_data->provider == 0x11)
716 memcpy(tmp, cta_res + 11, 8);
717 memcpy(tmp + 8, cta_res + 3, 8);
718 overcryptId = b2i(2, &er->ecm[44]);
719 rdr_log_dbg(reader, D_READER, "ICG ID: %04X", overcryptId);
720 Drecrypt2OverCW(overcryptId,tmp);
721 if(isValidDCW(tmp))
723 memcpy(ea->cw, tmp, 16);
724 return OK;
726 return ERROR;
729 DREover(reader, er->ecm, cta_res + 3);
731 if(isValidDCW(cta_res + 3))
733 memcpy(ea->cw, cta_res + 11, 8);
734 memcpy(ea->cw + 8, cta_res + 3, 8);
735 return OK;
739 else if((csystem_data->provider == 0x02 || csystem_data->provider == 0x03) && er->ecm[3] == 3)
741 // DRE 3
743 if (er->ecm[4] == 2)
745 memcpy( ea->cw , &er->ecm[42], 8);
746 memcpy(&ea->cw[8], &er->ecm[34], 8);
747 return OK;
750 uchar cmdlen;
751 uchar crypted = er->ecm[8] & 1;
752 uchar cryptkey = (er->ecm[8] & 6) >> 1;
754 if (crypted == 0)
756 cmdlen = 50;
758 else
760 cmdlen = 57;
763 uchar ecmcmd[cmdlen];
765 memcpy(ecmcmd, &er->ecm[17], cmdlen-1);
766 ecmcmd[cmdlen-1] = csystem_data->provider;
768 dre_cmd_c(ecmcmd, crypted, cryptkey);
770 if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
772 memcpy(ea->cw, cta_res+11, 8);
773 memcpy(ea->cw+8, cta_res+3, 8);
774 return OK;
778 else if(reader->caid == 0x2710 && er->ecm[3] == 4)
780 // DRE 4
782 if (er->ecm[4] == 4)
784 memcpy( ea->cw , &er->ecm[22], 8);
785 memcpy(&ea->cw[8], &er->ecm[14], 8);
786 return OK;
789 uchar cmdlen;
790 uchar crypted = er->ecm[8] & 1;
791 uchar cryptkey = (er->ecm[8] & 6) >> 1;
793 if (crypted == 0)
795 cmdlen = 58;
797 else
799 cmdlen = 65;
802 uchar ecmcmd[cmdlen];
804 memcpy(ecmcmd, &er->ecm[9], cmdlen-1);
805 ecmcmd[cmdlen-1] = csystem_data->provider;
807 dre_cmd_c(ecmcmd, crypted, cryptkey);
809 if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
811 memcpy(ea->cw, cta_res+11, 8);
812 memcpy(ea->cw+8, cta_res+3, 8);
813 return OK;
816 return ERROR;
819 static int32_t dre_do_emm(struct s_reader *reader, EMM_PACKET *ep)
821 def_resp;
822 struct dre_data *csystem_data = reader->csystem_data;
824 if(reader->caid == 0x4ae1)
826 if(reader->caid != b2i(2, ep->caid)) return ERROR;
828 if(ep->type == UNIQUE && ep->emm[39] == 0x3d)
830 /* For new package activation. */
831 uchar emmcmd58[26];
832 emmcmd58[0] = 0x58;
833 memcpy(&emmcmd58[1], &ep->emm[40], 24);
834 emmcmd58[25] = csystem_data->provider;
835 if((dre_cmd(emmcmd58)))
836 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
837 { return ERROR; }
839 else if(ep->emm[0] == 0x86 && ep->emm[4] == 0x02 /*&& csystem_data->provider != 0x11*/)
841 uchar emmcmd52[0x3a];
842 emmcmd52[0] = 0x52;
843 int32_t i;
844 for(i = 0; i < 2; i++)
846 memcpy(emmcmd52 + 1, ep->emm + 5 + 32 + i * 56, 56);
847 // check for shared address
848 if(ep->emm[3] != reader->sa[0][0])
849 { return OK; } // ignore, wrong address
850 emmcmd52[0x39] = csystem_data->provider;
851 if((dre_cmd(emmcmd52)))
852 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
853 { return ERROR; } //exit if response is not 90 00
856 else if(ep->emm[0] == 0x86 && ep->emm[4] == 0x4D && csystem_data->provider == 0x11)
858 uchar emmcmd52[0x3a];
859 emmcmd52[0] = 0x52;
860 emmcmd52[1] = 0x01;
861 emmcmd52[2] = ep->emm[5];
862 emmcmd52[3] = 0x01;
863 emmcmd52[4] = ep->emm[3];
864 emmcmd52[5] = 0;
865 emmcmd52[6] = 0;
866 emmcmd52[7] = 0;
867 emmcmd52[9] = 0x01;
868 emmcmd52[10] = 0x01;
869 emmcmd52[11] = 0;
870 memcpy(emmcmd52 + 13, ep->emm + 0x5C, 4);
871 int32_t i;
873 for(i = 0; i < 2; i++)
875 emmcmd52[8] = ep->emm[0x61+i*0x29];
876 if(i == 0) emmcmd52[12] = ep->emm[0x60] == 0x56 ? 0x56:0x3B;
877 else emmcmd52[12] = ep->emm[0x60] == 0x56 ? 0x3B:0x56;
878 memcpy(emmcmd52 + 0x11, ep->emm + 0x62 + i * 0x29, 40);
880 // check for shared address
881 if(ep->emm[3] != reader->sa[0][0])
882 { return OK; } // ignore, wrong address
883 emmcmd52[0x39] = csystem_data->provider;
884 if((dre_cmd(emmcmd52)))
885 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
886 { return ERROR; } //exit if response is not 90 00
889 else if (ep->emm[0] == 0x8c && (csystem_data->provider == 0x02 || csystem_data->provider == 0x03)) //dre3 group emm
891 if(ep->emm[3] != reader->sa[0][0])
892 { return OK; } // ignore, wrong address
894 uchar crypted = ep->emm[10];
896 if ((crypted & 1) == 1)
898 uchar emmcmd[0x49];
900 memcpy(emmcmd, &ep->emm[0x13], 0x48);
902 emmcmd[0x48] = csystem_data->provider;
904 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
906 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
907 { return ERROR; } //exit if response is not 90 00
909 memcpy(emmcmd, &ep->emm[0x5B], 0x48);
911 emmcmd[0x48] = csystem_data->provider;
913 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >>1);
915 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
916 { return ERROR; } //exit if response is not 90 00
918 return OK;
920 else
922 uchar emmcmd[0x42];
924 memcpy(emmcmd, &ep->emm[0x13], 0x41);
926 emmcmd[0x41] = csystem_data->provider;
928 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >>1);
930 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
931 { return ERROR; } //exit if response is not 90 00
933 memcpy(emmcmd, &ep->emm[0x5B], 0x41);
935 emmcmd[0x41] = csystem_data->provider;
937 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >>1);
939 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
940 { return ERROR; } //exit if response is not 90 00
942 return OK;
945 else if(ep->type == GLOBAL && ep->emm[0] == 0x91)
947 Drecrypt2OverEMM(ep->emm);
948 return OK;
950 else return OK;
952 else if(reader->caid == 0x2710)
954 // DRE 4
955 if(ep->type == UNIQUE)
957 uint16_t cmdlen;
958 uchar class, hlbUA, KEYindex;
959 int i, keycount;
960 uchar CMDtype = ep->emm[7];
961 uint16_t EMMlen = ep->emm[2] | ((ep->emm[1] & 0xF) << 8);
962 uchar cryptflag = ep->emm[10];
963 uchar crypted = cryptflag & 1;
964 uchar cryptkey = (cryptflag & 6) >> 1;
966 if ( CMDtype == 0x61 )
968 uchar emmcmd91[19];
970 emmcmd91[0] = 0x91;
971 emmcmd91[1] = ep->emm[19];
972 emmcmd91[2] = ep->emm[8];
973 emmcmd91[3] = ep->emm[20];
974 if(reader->force_ua) emmcmd91[3] += 2;
975 memcpy(&emmcmd91[4], &reader->hexserial[2], 4);
976 emmcmd91[8] = 0xF0;
977 emmcmd91[17] = ep->emm[22];
978 emmcmd91[18] = csystem_data->provider;
980 if ( (EMMlen - 24) > 16 )
982 hlbUA = reader->hexserial[5] & 0xF;
984 uint16_t keypos = cryptflag == 2 ? 17 : 9;
985 keycount = (EMMlen - 24) / keypos;
987 for(i=0; i <= keycount ;i++)
989 if ( i == keycount ) return OK;
990 if ( hlbUA == (ep->emm[23+(keypos*i)] & 0xF) ) break;
993 keypos = 24 + (keypos*i);
995 memcpy(&emmcmd91[9], &ep->emm[keypos], 8);
997 if((dre_cmd(emmcmd91)))
998 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2) )
999 return ERROR; //exit if response is not 90 00
1001 if ( cryptflag == 2 )
1003 if ( emmcmd91[17] == 0x56 ) KEYindex = 0x3B;
1004 else KEYindex = 0x56;
1006 keypos += 8;
1007 memcpy(&emmcmd91[9], &ep->emm[keypos], 8);
1008 emmcmd91[17] = KEYindex;
1010 dre_cmd(emmcmd91);
1012 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2))
1013 { return ERROR; } //exit if response is not 90 00
1015 return OK;
1018 return ERROR;
1020 else if ( CMDtype == 0x62 )
1022 if ( !memcmp(&reader->hexserial[2], &ep->emm[3], 4) )
1024 if ( crypted )
1026 cmdlen = 49;
1028 else
1030 cmdlen = 42;
1033 uchar emmcmd92[cmdlen];
1035 memcpy(emmcmd92, &ep->emm[19], cmdlen - 1);
1036 emmcmd92[cmdlen-1] = csystem_data->provider;
1038 if ( crypted )
1040 dre_cmd_c(emmcmd92, crypted, cryptkey);
1042 else
1044 dre_cmd(emmcmd92);
1047 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1048 { return ERROR; } //exit if response is not 90 00
1051 class = ep->emm[8];
1053 uchar emmcmd95[3];
1055 emmcmd95[0] = 0x95;
1056 emmcmd95[1] = class;
1057 emmcmd95[2] = csystem_data->provider;
1059 dre_cmd(emmcmd95);
1061 uchar emmcmd91[19];
1063 emmcmd91[0] = 0x91;
1064 emmcmd91[1] = ep->emm[102];
1065 emmcmd91[2] = ep->emm[8];
1066 emmcmd91[3] = ep->emm[103];
1067 if(reader->force_ua) emmcmd91[3] += 2;
1068 memcpy(&emmcmd91[4], &reader->hexserial[2], 4);
1069 emmcmd91[8] = ep->emm[104];
1070 memcpy(&emmcmd91[9], &ep->emm[72], 8);
1071 emmcmd91[17] = ep->emm[105];
1072 emmcmd91[18] = csystem_data->provider;
1074 dre_cmd(emmcmd91);
1076 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2) )
1077 { return ERROR; } //exit if response is not 90 00
1079 if ( emmcmd91[17] == 0x56 ) KEYindex = 0x3B;
1080 else KEYindex = 0x56;
1082 memcpy(&emmcmd91[9], &ep->emm[86], 8);
1083 emmcmd91[17] = KEYindex;
1085 dre_cmd(emmcmd91);
1087 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) )
1088 { return ERROR; } //exit if response is not 90 00
1090 return OK;
1092 else
1094 if ( memcmp(&reader->hexserial[2], &ep->emm[3], 4) ) return OK;
1096 if ( CMDtype == 0x63 )
1098 uchar emmcmdA5[7];
1100 emmcmdA5[0] = 0xA5;
1101 emmcmdA5[1] = 0;
1102 memcpy(&emmcmdA5[2], &reader->hexserial[2], 4);
1103 emmcmdA5[6] = csystem_data->provider;
1105 dre_cmd(emmcmdA5);
1107 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1108 { return ERROR; } //exit if response is not 90 00
1111 if ( crypted ) cmdlen = EMMlen - 19;
1112 else cmdlen = ep->emm[11] + 1;
1114 uchar emmcmd[cmdlen];
1116 memcpy(emmcmd, &ep->emm[19], cmdlen-1);
1117 emmcmd[cmdlen-1] = csystem_data->provider;
1119 if(emmcmd[0] == 0x45)
1121 cs_log("TRICOLOR Send KILL command for your card");
1122 return ERROR;
1125 dre_cmd_c(emmcmd, crypted, cryptkey);
1127 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1128 { return ERROR; } //exit if response is not 90 00
1130 return OK;
1132 return ERROR;
1134 else if(reader->caid != 0x2710 && reader->caid != 0x4AE1)
1136 uchar emmcmd42[] =
1138 0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
1139 0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
1140 0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
1141 0x91,
1142 0x56, 0x58, 0x11
1144 int32_t i;
1145 switch(ep->type)
1147 case UNIQUE:
1148 for(i = 0; i < 2; i++)
1150 memcpy(emmcmd42 + 1, ep->emm + 42 + i * 49, 48);
1151 emmcmd42[49] = ep->emm[i * 49 + 41]; //keynr
1152 emmcmd42[50] = 0x58 + ep->emm[40]; //package nr
1153 emmcmd42[51] = csystem_data->provider;
1154 if((dre_cmd(emmcmd42)))
1156 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1157 { return ERROR; } //exit if response is not 90 00
1160 break;
1161 case SHARED:
1162 default:
1163 memcpy(emmcmd42 + 1, ep->emm + 6, 48);
1164 emmcmd42[51] = csystem_data->provider;
1165 //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
1166 emmcmd42[50] = 0x58;
1167 emmcmd42[49] = ep->emm[5]; //keynr
1168 /* response:
1169 59 05 A2 02 05 01 5B
1170 90 00 */
1171 if((dre_cmd(emmcmd42))) //first emm request
1173 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1174 { return ERROR; } //exit if response is not 90 00
1176 memcpy(emmcmd42 + 1, ep->emm + 55, 7); //TODO OR next two lines?
1177 /*memcpy (emmcmd42 + 1, ep->emm + 55, 7); //FIXME either I cant count or my EMM log contains errors
1178 memcpy (emmcmd42 + 8, ep->emm + 67, 41); */
1179 emmcmd42[51] = csystem_data->provider;
1180 //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
1181 emmcmd42[50] = 0x58;
1182 emmcmd42[49] = ep->emm[54]; //keynr
1183 if((dre_cmd(emmcmd42))) //second emm request
1185 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1186 { return ERROR; } //exit if response is not 90 00
1190 return OK;
1192 return ERROR;
1195 static int32_t dre_card_info(struct s_reader *UNUSED(rdr))
1197 return OK;
1200 const struct s_cardsystem reader_dre =
1202 .desc = "dre",
1203 .caids = (uint16_t[]){ 0x4AE0, 0x4AE1, 0x7BE0, 0x7BE1, 0x2710, 0 },
1204 .do_emm = dre_do_emm,
1205 .do_ecm = dre_do_ecm,
1206 .card_info = dre_card_info,
1207 .card_init = dre_card_init,
1208 .get_emm_type = dre_common_get_emm_type,
1209 .get_emm_filter = dre_common_get_emm_filter,
1212 #endif