- fix for ticker #4787
[oscam.git] / reader-dre.c
blob181318e7e305b70d72e8c785deab0804fe93d948
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 uint8_t xor(const uint8_t *cmd, int32_t cmdlen)
17 int32_t i;
18 uint8_t 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 uint8_t *cmd, int32_t cmdlen, uint8_t *cta_res,
46 uint16_t *p_cta_lr, uint8_t crypted, uint8_t keynum, uint8_t dre_v, uint8_t cmd_type)
48 // attention: inputcommand will be changed!!!!
49 //answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
51 uint8_t startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 }; // any command starts with this,
52 // last byte is nr of bytes of the command that will be sent
53 // after the startcmd
54 // response on startcmd+cmd: = { 0x61, 0x05 } // 0x61 = "OK", last byte is nr. of bytes card will send
55 uint8_t reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 }; // after command answer has to be requested,
56 // last byte must be nr. of bytes that card has reported to send
57 uint8_t command[256];
58 uint8_t checksum;
59 char tmp[256];
60 int32_t headerlen = sizeof(startcmd);
62 if(dre_v > 0)
64 startcmd[1] = 0;
65 startcmd[2] = crypted;
66 startcmd[3] = keynum;
69 startcmd[4] = cmdlen + 3 - cmd_type; // commandlength + type + len + checksum bytes
70 memcpy(command, startcmd, headerlen);
71 command[headerlen++] = cmd_type ? 0x86 : CMD_BYTE; // type
72 command[headerlen++] = cmdlen + (cmd_type == 1 ? 0 : 1); // len = command + 1 checksum byte
73 memcpy(command + headerlen, cmd, cmdlen);
75 if(!cmd_type)
77 checksum = ~xor(cmd, cmdlen);
78 //rdr_log_dbg(reader, D_READER, "Checksum: %02x", checksum);
79 cmdlen += headerlen;
80 command[cmdlen++] = checksum;
82 else cmdlen += headerlen;
84 reader_cmd2icc(reader, command, cmdlen, cta_res, p_cta_lr);
86 if((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE))
88 rdr_log(reader, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
89 rdr_log(reader, "unexpected answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
90 return ERROR; // error
93 rdr_log_dbg(reader, D_READER, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
94 rdr_log_dbg(reader, D_READER, "answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
96 reqans[4] = cta_res[1]; // adapt length byte
97 reader_cmd2icc(reader, reqans, 5, cta_res, p_cta_lr);
99 if(cta_res[0] != CMD_BYTE)
101 rdr_log(reader, "unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
102 return ERROR;
105 if((cta_res[1] == 0x03) && (cta_res[2] == 0xe2))
107 switch(cta_res[3 + dre_v])
109 case 0xe1:
110 rdr_log(reader, "checksum error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
111 break;
113 case 0xe2:
114 rdr_log(reader, "wrong cmd len: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
115 break;
117 case 0xe3:
118 rdr_log(reader, "illegal command: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
119 break;
121 case 0xe4:
122 rdr_log(reader, "wrong adress type: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
123 break;
125 case 0xe5:
126 rdr_log(reader, "wrong CMD param: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
127 break;
129 case 0xe6:
130 rdr_log(reader, "wrong UA: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
131 break;
133 case 0xe7:
134 rdr_log(reader, "wrong group: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
135 break;
137 case 0xe8:
138 rdr_log(reader, "wrong key num: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
139 break;
141 case 0xeb:
142 rdr_log(reader, "No key or subscribe: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
143 break;
145 case 0xec:
146 rdr_log(reader, "wrong signature: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
147 break;
149 case 0xed:
150 rdr_log(reader, "wrong provider: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
151 break;
153 case 0xef:
154 rdr_log(reader, "wrong GEO code: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
155 break;
157 default:
158 rdr_log_dbg(reader, D_READER, "unknown error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
159 break;
161 return ERROR; // error
164 int32_t length_excl_leader = *p_cta_lr;
166 if((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
167 { length_excl_leader -= 2; }
169 checksum = ~xor(cta_res + 2, length_excl_leader - 3);
171 if(cta_res[length_excl_leader - 1] != checksum)
173 rdr_log(reader, "checksum does not match, expected %02x received %02x:%s", checksum,
174 cta_res[length_excl_leader - 1], cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
175 return ERROR; // error
177 return OK;
180 #define dre_script(cmd, len, cmd_type, crypted, keynum) \
182 dre_command(reader, cmd, len, cta_res, &cta_lr, crypted, keynum, crypted, cmd_type); \
185 #define dre_cmd(cmd) \
187 dre_command(reader, cmd, sizeof(cmd), cta_res, &cta_lr, 0, 0, 0, 0); \
190 #define dre_cmd_c(cmd,crypted,keynum) \
192 dre_command(reader, cmd, sizeof(cmd),cta_res,&cta_lr, crypted, keynum, 1, 0); \
195 static int32_t dre_set_provider_info(struct s_reader *reader)
197 def_resp;
198 int32_t i;
199 int subscr_cmd_len = 4;
200 uint8_t subscr[4]; // = { 0x59, 0x14 }; // subscriptions
201 uint8_t dates[] = { 0x5b, 0x00, 0x14 }; // validity dates
202 uint8_t subscr_len = 0, n = 0;
203 struct dre_data *csystem_data = reader->csystem_data;
205 cs_clear_entitlement(reader);
207 switch(csystem_data->provider)
209 case 0x02:
210 case 0x03:
211 subscr[0] = 0x84;
212 subscr[1] = 0;
213 subscr[2] = 0x5F;
214 subscr[3] = csystem_data->provider;
215 dates[0] = 0x85;
216 subscr_len = 0x5F;
217 break;
219 case 0x18:
220 case 0x19:
221 case 0x1A:
222 subscr[0] = 0x94;
223 subscr[1] = 0;
224 subscr[2] = 0x5F;
225 subscr[3] = csystem_data->provider;
226 dates[0] = 0x95;
227 subscr_len = 0x5F;
228 break;
230 default:
231 subscr[0] = 0x59;
232 subscr[1] = csystem_data->provider;
233 subscr_len = 0x20;
234 subscr_cmd_len = 2;
237 chk_subscr:
239 if((dre_script(subscr, subscr_cmd_len, 0, 0, 0))) // ask subscription packages, returns error on 0x11 card
241 uint8_t pbm[subscr_len];
242 char tmp_dbg[subscr_len*2+1];
243 memcpy(pbm, cta_res + 3, cta_lr - 6);
244 rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, subscr_len, tmp_dbg, sizeof(tmp_dbg)));
246 for(i = 0; i < subscr_len; i++)
248 if(pbm[i] != 0xff)
250 dates[1] = i;
251 dates[2] = csystem_data->provider;
252 dre_cmd(dates); // ask for validity dates
254 time_t start;
255 time_t end;
256 start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
257 end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];
259 struct tm temp;
261 localtime_r(&start, &temp);
262 int32_t startyear = temp.tm_year + 1900;
263 int32_t startmonth = temp.tm_mon + 1;
264 int32_t startday = temp.tm_mday;
265 localtime_r(&end, &temp);
266 int32_t endyear = temp.tm_year + 1900;
267 int32_t endmonth = temp.tm_mon + 1;
268 int32_t endday = temp.tm_mday;
269 rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i",
270 i + n, startyear, startmonth, startday, endyear, endmonth, endday);
271 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, i + n, start, end, 5, 1);
276 if(subscr_len == 0x5F) // read second part subscription packages, for DRE3 and DRE4
278 subscr[1] = 0x5F;
279 subscr[2] = 0x21;
280 subscr_len = 0x21;
281 n = 0x5F;
282 goto chk_subscr;
285 return OK;
288 static void dre_read_ee(struct s_reader *reader, const char *path, uint8_t provid)
290 def_resp;
291 int i, n;
292 uint8_t *ee = malloc(2048);
293 if(ee == NULL) return;
295 uint8_t drecmd43[] = { 0x80, 0x00, 0x00, 0x00, 0x05, 0x59, 0x03, 0x43, 0x11, 0xAD };
296 uint8_t drecmd45[] = { 0x45, 0x11 };
298 drecmd43[8] = drecmd45[1] = provid;
299 drecmd43[9] = ~xor(&drecmd43[7], 2);
301 for(i = 0; i < 8; i++)
303 for(n = 0; n < 8; n++)
305 reader_cmd2icc(reader, drecmd43, 10, cta_res, &cta_lr);
307 dre_cmd_c(drecmd45, n, i * 32);
309 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
311 free(ee);
312 rdr_log(reader, "ERROR read ee.bin from card");
313 return;
316 memcpy(&ee[((n * 8) + i) * 32] ,&cta_res[2] ,32);
321 FILE *pFile = fopen(path, "wb");
323 if(pFile == NULL)
325 free(ee);
326 return ;
329 fwrite(ee, 2048, 1, pFile);
330 fclose(pFile);
331 free(ee);
332 rdr_log(reader, "ee.bin saved to %s", path);
335 static void cmd_test(struct s_reader *reader)
337 def_resp;
338 int i;
339 uint8_t drecmd[] = { 0x00, 0x02 };
340 char tmp[64];
342 for(i = 0; i <= 0xFF; i++)
344 if(i == 0x45) continue;
345 drecmd[0] = i;
346 dre_cmd(drecmd);
347 if(cta_res[2] == 0xE2)
349 if(cta_res[3] != 0xE3) rdr_log(reader, "cmd %02X error %02X",i ,cta_res[3]);
351 else
353 rdr_log(reader, "cmd %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
357 uint8_t drecmd[64];
359 //memset(drecmd, 0, 64);
360 //drecmd[0] = 0x71;
361 for(i = 2; i <= 64; i++)
363 memset(drecmd, 0, 64);
364 drecmd[i-1] = 0x02;
365 drecmd[0] = 0x71;
367 dre_script(drecmd, i, 0, 0, 0);
369 if(cta_res[2] == 0xE2)
371 if((cta_res[3] != 0xE2) & (cta_res[3] != 0xED)) rdr_log(reader, "Len %02X error %02X",i ,cta_res[3]);
372 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)));
374 else
376 rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
381 static int32_t dre_card_init(struct s_reader *reader, ATR *newatr)
383 get_atr;
384 def_resp;
385 uint8_t ua[] = { 0x43, 0x15 }; // get serial number (UA)
386 uint8_t providers[] = { 0x49, 0x15 }; // get providers
387 uint8_t cmd56[] = { 0x56, 0x00 };
388 int32_t i;
389 char *card;
390 char tmp[9];
392 if((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12) || (
393 ((atr[4] != 0x01) || (atr[5] != 0x01)) &&
394 ((atr[4] != 0xca) || (atr[5] != 0x07)) &&
395 ((atr[4] != 0xcb) || (atr[5] != 0x07)) &&
396 ((atr[4] != 0xcc) || (atr[5] != 0x07)) &&
397 ((atr[4] != 0xcd) || (atr[5] != 0x07))
399 { return ERROR; }
401 if(!cs_malloc(&reader->csystem_data, sizeof(struct dre_data)))
402 { return ERROR; }
403 struct dre_data *csystem_data = reader->csystem_data;
405 csystem_data->provider = atr[6];
406 uint8_t checksum = xor(atr + 1, 6);
408 if(checksum != atr[7])
409 { rdr_log(reader, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]); }
411 switch(atr[6])
413 case 0:
414 if(!(dre_cmd(cmd56))) { return ERROR; }
415 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; }
417 switch(cta_res[4])
419 case 0x02:
420 card = "Tricolor Centr DRE3";
421 reader->caid = 0x4ae1;
422 break;
424 case 0x03:
425 card = "Tricolor Syberia DRE3";
426 reader->caid = 0x4ae1;
427 break;
429 case 0x18:
430 case 0x19:
431 card = "Tricolor Centr DRE4";
432 reader->caid = 0x2710;
433 break;
435 case 0x1A:
436 card = "Tricolor Syberia DRE4";
437 reader->caid = 0x2710;
438 break;
440 default:
441 return ERROR;
443 csystem_data->provider = cta_res[4];
444 providers[0] = 0x83;
445 break;
447 case 0x11:
448 card = "Tricolor Centr DRE2";
449 reader->caid = 0x4ae1;
450 break; // 59 type card = MSP (74 type = ATMEL)
452 case 0x12:
453 card = "Cable TV";
454 reader->caid = 0x4ae1; // TODO not sure about this one
455 break;
457 case 0x14:
458 card = "Tricolor Syberia DRE2";
459 reader->caid = 0x4ae1;
460 break; // 59 type card
462 case 0x15:
463 card = "Platforma HD / DW old";
464 reader->caid = 0x4ae1;
465 break; // 59 type card
467 default:
468 return ERROR;
471 memset(reader->prid, 0x00, 8);
473 if(atr[6] > 0)
475 reader->prid[0][3] = atr[6];
477 else
479 reader->prid[0][3] = csystem_data->provider;
482 uint8_t cmd54[] = { 0x54, 0x14 }; // geocode
483 cmd54[1] = csystem_data->provider;
484 uint8_t geocode = 0;
486 if((dre_cmd(cmd54))) // error would not be fatal, like on 0x11 cards
487 { geocode = cta_res[3]; }
489 providers[1] = csystem_data->provider;
490 if(!(dre_cmd(providers)))
491 { return ERROR; } // fatal error
493 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
494 { return ERROR; }
496 uint8_t provname[128];
498 for(i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++)
500 provname[i] = cta_res[6 + i];
501 if(provname[i] == 0x00)
502 { break; }
505 int32_t major_version = cta_res[3];
506 int32_t minor_version = cta_res[4];
508 ua[1] = csystem_data->provider;
509 dre_cmd(ua); // error would not be fatal
511 int32_t hexlength = cta_res[1] - 2; // discard first and last byte, last byte is always checksum, first is answer code
513 if(reader->force_ua)
515 rdr_log(reader, "WARNING!!! used UA from force_ua %08X", reader->force_ua);
516 memcpy(cta_res + 3, &reader->force_ua, 4);
519 reader->hexserial[0] = 0;
520 reader->hexserial[1] = 0;
521 memcpy(reader->hexserial + 2, cta_res + 3, hexlength);
523 int32_t low_dre_id, dre_chksum;
524 uint8_t buf[32];
526 if(major_version < 0x3)
528 low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
529 dre_chksum = 0;
530 snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider - 16, major_version + 1, low_dre_id);
532 for(i = 0; i < 32; i++)
534 if(buf[i] == 0x00)
535 { break; }
536 dre_chksum += buf[i] - 48;
539 if(major_version < 2)
541 reader->caid = 0x4ae0;
542 card = csystem_data->provider == 0x11 ? "Tricolor Centr DRE1" : "Tricolor Syberia DRE1";
545 rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
546 reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum,
547 csystem_data->provider - 16, major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
549 else
551 low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]);
552 dre_chksum = 0;
553 snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider, major_version, low_dre_id);
555 for(i = 0; i < 32; i++)
557 if(buf[i] == 0x00)
558 { break; }
559 dre_chksum += buf[i] - 48;
561 rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%03i%i%08i, geocode %i, card: %s v%i.%i",
562 reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider,
563 major_version, low_dre_id, geocode, card, major_version, minor_version);
566 rdr_log(reader, "Provider name:%s.", provname);
569 memset(reader->sa, 0, sizeof(reader->sa));
570 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...
572 rdr_log_sensitive(reader, "SA = %02X%02X%02X%02X, UA = {%s}", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
573 reader->sa[0][3], cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)));
575 reader->nprov = 1;
577 //cmd_test(reader);
579 // exec user script, wicardd format
580 if(reader->userscript != NULL)
582 uint8_t *usercmd = NULL;
583 int cmd_len;
584 int n;
585 char *tempbuf = malloc(2048);
586 trim2(reader->userscript);
587 FILE *pFile = fopen(reader->userscript, "rt");
589 if(pFile != NULL)
591 uint8_t ignoreProvid = 0;
592 uint8_t crypted = 0;
593 uint8_t cryptkey = 0;
596 tempbuf[0] = '\0';
597 if(usercmd != NULL) free(usercmd);
599 if(fgets(tempbuf, 2048, pFile) == NULL) continue;
601 if(strlen(tempbuf) < 10) continue;
603 trim2(tempbuf);
605 ignoreProvid = 0;
606 crypted = 0;
607 cryptkey = 0;
609 if(tempbuf[0] == '8' && tempbuf[1] == '6' && csystem_data->provider == 0x11) ignoreProvid = 1;
610 else if(strncmp(tempbuf ,"REG2" ,4) == 0)
612 dre_read_ee(reader, &tempbuf[4] ,csystem_data->provider);
613 continue;
615 else if(strncmp(tempbuf ,"CR" ,2) == 0)
617 crypted = 1;
618 cryptkey = ((tempbuf[2] - (tempbuf[2] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf[3] - (tempbuf[3] > 0x39 ? 0x37:0x30)) & 0xF);
620 else if(tempbuf[0] != '5' && tempbuf[1] != '9') continue;
622 strtoupper(tempbuf);
624 cmd_len = strlen(tempbuf) / 2 - 3 + ignoreProvid - (crypted * 2);
625 usercmd = malloc(cmd_len);
627 for(i = 0, n = 4 + (crypted * 4); i < cmd_len; i++, n += 2)
629 usercmd[i] = ((tempbuf[n] - (tempbuf[n] > 0x39 ? 0x37 : 0x30)) << 4) + ((tempbuf[n + 1] - (tempbuf[n + 1] > 0x39 ? 0x37 : 0x30)) & 0xF);
632 /*if(usercmd[cmd_len-1] != csystem_data->provider && !ignoreProvid)
634 rdr_log(reader, "Skip script: current provid %02X , script provid %02X", csystem_data->provider, usercmd[cmd_len-1]);
635 continue;
638 rdr_log(reader, "User script: %s", tempbuf);
640 /*ret =*/
642 rdr_log(reader, "Script %s", (dre_script(usercmd, cmd_len, ignoreProvid, crypted, cryptkey)) ? "done" : "error");
644 while(!feof(pFile));
646 else
648 rdr_log(reader, "Can't open script file (%s)", reader->userscript);
651 //if(usercmd != NULL) free(usercmd);
652 if(tempbuf != NULL) free(tempbuf);
655 if(csystem_data->provider == 0x11)
657 memset(reader->prid[1], 0x00, 8);
658 reader->prid[1][3] = 0xFE;
659 reader->nprov = 2;
662 if(!dre_set_provider_info(reader))
663 { return ERROR; } // fatal error
666 rdr_log(reader, "ready for requests");
667 return OK;
670 static void DREover(struct s_reader *reader, const uint8_t *ECMdata, uint8_t *DW)
672 uint32_t key_schedule[32];
674 if(reader->des_key_length < 128)
676 rdr_log(reader, "error: deskey is missing or too short");
677 return;
680 if(ECMdata[2] >= (43 + 4) && ECMdata[40] == 0x3A && ECMdata[41] == 0x4B)
682 des_set_key(&reader->des_key[(ECMdata[42] & 0x0F) * 8], key_schedule);
684 des(DW, key_schedule, 0); // even DW post-process
685 des(DW + 8, key_schedule, 0); // odd DW post-process
689 static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
691 def_resp;
692 uint16_t overcryptId;
693 uint8_t tmp[16];
694 char tmp_dbg[256];
695 struct dre_data *csystem_data = reader->csystem_data;
696 if(reader->caid == 0x4ae0)
698 uint8_t ecmcmd41[] = { 0x41,
699 0x58, 0x1f, 0x00, // fixed part, dont change
700 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x01 - 0x08: next key
701 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // 0x11 - 0x18: current key
702 0x3b, 0x59, 0x11 }; // 0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
704 ecmcmd41[22] = csystem_data->provider;
705 memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
706 ecmcmd41[20] = er->ecm[6]; // keynumber
707 ecmcmd41[21] = 0x58 + er->ecm[25]; // package number
708 rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
709 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)));
711 if((dre_cmd(ecmcmd41))) // ecm request
713 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
714 { return ERROR; } // exit if response is not 90 00
715 memcpy(ea->cw, cta_res + 11, 8);
716 memcpy(ea->cw + 8, cta_res + 3, 8);
718 return OK;
721 else if(reader->caid == 0x4ae1)
723 if(csystem_data->provider == 0x11 || csystem_data->provider == 0x14)
725 uint8_t ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, // fixed header?
726 0x9C, 0xDA, // first three nibbles count up, fourth nibble counts down; all ECMs sent twice
727 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, // next key?
728 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, // current key?
729 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, // key or signature?
730 0x14 }; // provider
732 memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
733 rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
734 rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
735 ecmcmd51[33] = csystem_data->provider; // no part of sig
737 if((dre_cmd(ecmcmd51))) // ecm request
739 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
740 { return ERROR; } // exit if response is not 90 00
742 if(er->ecm[2] >= 46 && er->ecm[43] == 1 && csystem_data->provider == 0x11)
744 memcpy(tmp, cta_res + 11, 8);
745 memcpy(tmp + 8, cta_res + 3, 8);
746 overcryptId = b2i(2, &er->ecm[44]);
747 rdr_log_dbg(reader, D_READER, "ICG ID: %04X", overcryptId);
749 Drecrypt2OverCW(overcryptId,tmp);
751 if(isValidDCW(tmp))
753 memcpy(ea->cw, tmp, 16);
754 return OK;
756 return ERROR;
759 DREover(reader, er->ecm, cta_res + 3);
761 if(isValidDCW(cta_res + 3))
763 memcpy(ea->cw, cta_res + 11, 8);
764 memcpy(ea->cw + 8, cta_res + 3, 8);
765 return OK;
769 else if((csystem_data->provider == 0x02 || csystem_data->provider == 0x03) && er->ecm[3] == 3)
771 // DRE 3
773 if (er->ecm[4] == 2)
775 memcpy(ea->cw, &er->ecm[42], 8);
776 memcpy(&ea->cw[8], &er->ecm[34], 8);
777 return OK;
780 uint8_t cmdlen;
781 uint8_t crypted = er->ecm[8] & 1;
782 uint8_t cryptkey = (er->ecm[8] & 6) >> 1;
784 if (crypted == 0)
786 cmdlen = 50;
788 else
790 cmdlen = 57;
793 uint8_t ecmcmd[cmdlen];
795 memcpy(ecmcmd, &er->ecm[17], cmdlen - 1);
796 ecmcmd[cmdlen - 1] = csystem_data->provider;
798 dre_cmd_c(ecmcmd, crypted, cryptkey);
800 if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
802 memcpy(ea->cw, cta_res + 11, 8);
803 memcpy(ea->cw + 8, cta_res + 3, 8);
804 return OK;
808 else if(reader->caid == 0x2710 && er->ecm[3] == 4)
810 // DRE 4
812 if (er->ecm[4] == 4)
814 memcpy(ea->cw, &er->ecm[22], 8);
815 memcpy(&ea->cw[8], &er->ecm[14], 8);
816 return OK;
819 uint8_t cmdlen;
820 uint8_t crypted = er->ecm[8] & 1;
821 uint8_t cryptkey = (er->ecm[8] & 6) >> 1;
823 if (crypted == 0)
825 cmdlen = 58;
827 else
829 cmdlen = 65;
832 uint8_t ecmcmd[cmdlen];
834 memcpy(ecmcmd, &er->ecm[9], cmdlen - 1);
835 ecmcmd[cmdlen - 1] = csystem_data->provider;
837 dre_cmd_c(ecmcmd, crypted, cryptkey);
839 if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
841 memcpy(ea->cw, cta_res + 11, 8);
842 memcpy(ea->cw + 8, cta_res + 3, 8);
843 return OK;
846 return ERROR;
849 static int32_t dre_do_emm(struct s_reader *reader, EMM_PACKET *ep)
851 def_resp;
852 struct dre_data *csystem_data = reader->csystem_data;
854 if(reader->caid == 0x4ae1)
856 if(reader->caid != b2i(2, ep->caid)) return ERROR;
858 if(ep->type == UNIQUE && ep->emm[39] == 0x3d)
860 /* For new package activation. */
861 uint8_t emmcmd58[26];
862 emmcmd58[0] = 0x58;
863 memcpy(&emmcmd58[1], &ep->emm[40], 24);
864 emmcmd58[25] = csystem_data->provider;
866 if((dre_cmd(emmcmd58)))
867 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
868 { return ERROR; }
870 else if(ep->emm[0] == 0x86 && ep->emm[4] == 0x02 /*&& csystem_data->provider != 0x11*/)
872 uint8_t emmcmd52[0x3a];
873 emmcmd52[0] = 0x52;
874 int32_t i;
875 for(i = 0; i < 2; i++)
877 memcpy(emmcmd52 + 1, ep->emm + 5 + 32 + i * 56, 56);
879 // check for shared address
880 if(ep->emm[3] != reader->sa[0][0])
881 { return OK; } // ignore, wrong address
883 emmcmd52[0x39] = csystem_data->provider;
885 if((dre_cmd(emmcmd52)))
886 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
887 { return ERROR; } // exit if response is not 90 00
890 else if(ep->emm[0] == 0x86 && ep->emm[4] == 0x4D && csystem_data->provider == 0x11)
892 uint8_t emmcmd52[0x3a];
894 emmcmd52[0] = 0x52;
895 emmcmd52[1] = 0x01;
896 emmcmd52[2] = ep->emm[5];
897 emmcmd52[3] = 0x01;
898 emmcmd52[4] = ep->emm[3];
899 emmcmd52[5] = 0;
900 emmcmd52[6] = 0;
901 emmcmd52[7] = 0;
902 emmcmd52[9] = 0x01;
903 emmcmd52[10] = 0x01;
904 emmcmd52[11] = 0;
905 memcpy(emmcmd52 + 13, ep->emm + 0x5C, 4);
906 int32_t i;
908 for(i = 0; i < 2; i++)
910 emmcmd52[8] = ep->emm[0x61 + i * 0x29];
911 if(i == 0) emmcmd52[12] = ep->emm[0x60] == 0x56 ? 0x56 : 0x3B;
912 else emmcmd52[12] = ep->emm[0x60] == 0x56 ? 0x3B : 0x56;
913 memcpy(emmcmd52 + 0x11, ep->emm + 0x62 + i * 0x29, 40);
915 // check for shared address
916 if(ep->emm[3] != reader->sa[0][0])
917 { return OK; } // ignore, wrong address
919 emmcmd52[0x39] = csystem_data->provider;
921 if((dre_cmd(emmcmd52)))
922 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
923 { return ERROR; } // exit if response is not 90 00
926 else if (ep->emm[0] == 0x8c && (csystem_data->provider == 0x02 || csystem_data->provider == 0x03)) // dre3 group emm
928 if(ep->emm[3] != reader->sa[0][0])
929 { return OK; } // ignore, wrong address
931 uint8_t crypted = ep->emm[10];
933 if ((crypted & 1) == 1)
935 uint8_t emmcmd[0x49];
937 memcpy(emmcmd, &ep->emm[0x13], 0x48);
939 emmcmd[0x48] = csystem_data->provider;
941 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
943 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
944 { return ERROR; } //exit if response is not 90 00
946 memcpy(emmcmd, &ep->emm[0x5B], 0x48);
948 emmcmd[0x48] = csystem_data->provider;
950 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
952 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
953 { return ERROR; } //exit if response is not 90 00
955 return OK;
957 else
959 uint8_t emmcmd[0x42];
961 memcpy(emmcmd, &ep->emm[0x13], 0x41);
963 emmcmd[0x41] = csystem_data->provider;
965 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
967 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
968 { return ERROR; } // exit if response is not 90 00
970 memcpy(emmcmd, &ep->emm[0x5B], 0x41);
972 emmcmd[0x41] = csystem_data->provider;
974 dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
976 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
977 { return ERROR; } // exit if response is not 90 00
979 return OK;
982 else if(ep->type == GLOBAL && ep->emm[0] == 0x91)
984 Drecrypt2OverEMM(ep->emm);
985 return OK;
987 else return OK;
989 else if(reader->caid == 0x2710)
991 // DRE 4
992 if(ep->type == UNIQUE)
994 uint16_t cmdlen;
995 uint8_t class, hlbUA, KEYindex;
996 int i, keycount;
997 uint8_t CMDtype = ep->emm[7];
998 uint16_t EMMlen = ep->emm[2] | ((ep->emm[1] & 0xF) << 8);
999 uint8_t cryptflag = ep->emm[10];
1000 uint8_t crypted = cryptflag & 1;
1001 uint8_t cryptkey = (cryptflag & 6) >> 1;
1003 if (CMDtype == 0x61)
1005 uint8_t emmcmd91[19];
1007 emmcmd91[0] = 0x91;
1008 emmcmd91[1] = ep->emm[19];
1009 emmcmd91[2] = ep->emm[8];
1010 emmcmd91[3] = ep->emm[20];
1011 if(reader->force_ua) emmcmd91[3] += 2;
1012 memcpy(&emmcmd91[4], &reader->hexserial[2], 4);
1013 emmcmd91[8] = 0xF0;
1014 emmcmd91[17] = ep->emm[22];
1015 emmcmd91[18] = csystem_data->provider;
1017 if ((EMMlen - 24) > 16)
1019 hlbUA = reader->hexserial[5] & 0xF;
1021 uint16_t keypos = cryptflag == 2 ? 17 : 9;
1022 keycount = (EMMlen - 24) / keypos;
1024 for(i = 0; i <= keycount ;i++)
1026 if (i == keycount) return OK;
1027 if (hlbUA == (ep->emm[23 + (keypos * i)] & 0xF) ) break;
1030 keypos = 24 + (keypos * i);
1032 memcpy(&emmcmd91[9], &ep->emm[keypos], 8);
1034 if((dre_cmd(emmcmd91)))
1035 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2))
1036 return ERROR; // exit if response is not 90 00
1038 if (cryptflag == 2)
1040 if (emmcmd91[17] == 0x56) KEYindex = 0x3B;
1041 else KEYindex = 0x56;
1043 keypos += 8;
1044 memcpy(&emmcmd91[9], &ep->emm[keypos], 8);
1045 emmcmd91[17] = KEYindex;
1047 dre_cmd(emmcmd91);
1049 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2))
1050 { return ERROR; } // exit if response is not 90 00
1052 return OK;
1055 return ERROR;
1057 else if (CMDtype == 0x62)
1059 if (!memcmp(&reader->hexserial[2], &ep->emm[3], 4))
1061 if (crypted)
1063 cmdlen = 49;
1065 else
1067 cmdlen = 42;
1070 uint8_t emmcmd92[cmdlen];
1072 memcpy(emmcmd92, &ep->emm[19], cmdlen - 1);
1073 emmcmd92[cmdlen - 1] = csystem_data->provider;
1075 if (crypted)
1077 dre_cmd_c(emmcmd92, crypted, cryptkey);
1079 else
1081 dre_cmd(emmcmd92);
1084 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1085 { return ERROR; } // exit if response is not 90 00
1087 class = ep->emm[8];
1089 uint8_t emmcmd95[3];
1091 emmcmd95[0] = 0x95;
1092 emmcmd95[1] = class;
1093 emmcmd95[2] = csystem_data->provider;
1095 dre_cmd(emmcmd95);
1097 uint8_t emmcmd91[19];
1099 emmcmd91[0] = 0x91;
1100 emmcmd91[1] = ep->emm[102];
1101 emmcmd91[2] = ep->emm[8];
1102 emmcmd91[3] = ep->emm[103];
1103 if(reader->force_ua) emmcmd91[3] += 2;
1104 memcpy(&emmcmd91[4], &reader->hexserial[2], 4);
1105 emmcmd91[8] = ep->emm[104];
1106 memcpy(&emmcmd91[9], &ep->emm[72], 8);
1107 emmcmd91[17] = ep->emm[105];
1108 emmcmd91[18] = csystem_data->provider;
1110 dre_cmd(emmcmd91);
1112 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2) )
1113 { return ERROR; } // exit if response is not 90 00
1115 if (emmcmd91[17] == 0x56) KEYindex = 0x3B;
1116 else KEYindex = 0x56;
1118 memcpy(&emmcmd91[9], &ep->emm[86], 8);
1119 emmcmd91[17] = KEYindex;
1121 dre_cmd(emmcmd91);
1123 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1124 { return ERROR; } // exit if response is not 90 00
1126 return OK;
1128 else
1130 if (memcmp(&reader->hexserial[2], &ep->emm[3], 4)) return OK;
1132 if (CMDtype == 0x63)
1134 uint8_t emmcmdA5[7];
1136 emmcmdA5[0] = 0xA5;
1137 emmcmdA5[1] = 0;
1138 memcpy(&emmcmdA5[2], &reader->hexserial[2], 4);
1139 emmcmdA5[6] = csystem_data->provider;
1141 dre_cmd(emmcmdA5);
1143 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1144 { return ERROR; } //exit if response is not 90 00
1147 if (crypted) cmdlen = EMMlen - 19;
1148 else cmdlen = ep->emm[11] + 1;
1150 uint8_t emmcmd[cmdlen];
1152 memcpy(emmcmd, &ep->emm[19], cmdlen - 1);
1153 emmcmd[cmdlen - 1] = csystem_data->provider;
1155 if(emmcmd[0] == 0x45)
1157 cs_log("TRICOLOR Send KILL command for your card");
1158 return ERROR;
1161 dre_cmd_c(emmcmd, crypted, cryptkey);
1163 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1164 { return ERROR; } //exit if response is not 90 00
1166 return OK;
1168 return ERROR;
1170 else if(reader->caid != 0x2710 && reader->caid != 0x4AE1)
1172 uint8_t emmcmd42[] =
1174 0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
1175 0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
1176 0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
1177 0x91,
1178 0x56, 0x58, 0x11
1180 int32_t i;
1182 switch(ep->type)
1184 case UNIQUE:
1185 for(i = 0; i < 2; i++)
1187 memcpy(emmcmd42 + 1, ep->emm + 42 + i * 49, 48);
1188 emmcmd42[49] = ep->emm[i * 49 + 41]; // keynr
1189 emmcmd42[50] = 0x58 + ep->emm[40]; // package nr
1190 emmcmd42[51] = csystem_data->provider;
1191 if((dre_cmd(emmcmd42)))
1193 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1194 { return ERROR; } // exit if response is not 90 00
1197 break;
1199 case SHARED:
1200 default:
1201 memcpy(emmcmd42 + 1, ep->emm + 6, 48);
1202 emmcmd42[51] = csystem_data->provider;
1203 //emmcmd42[50] = ecmcmd42[2]; // TODO package nr could also be fixed 0x58
1204 emmcmd42[50] = 0x58;
1205 emmcmd42[49] = ep->emm[5]; // keynr
1207 /* response:
1208 59 05 A2 02 05 01 5B
1209 90 00 */
1211 if((dre_cmd(emmcmd42))) // first emm request
1213 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1214 { return ERROR; } // exit if response is not 90 00
1216 memcpy(emmcmd42 + 1, ep->emm + 55, 7); // TODO OR next two lines?
1217 //memcpy (emmcmd42 + 1, ep->emm + 55, 7); // FIXME either I cant count or my EMM log contains errors
1218 //memcpy (emmcmd42 + 8, ep->emm + 67, 41);
1219 emmcmd42[51] = csystem_data->provider;
1220 //emmcmd42[50] = ecmcmd42[2]; // TODO package nr could also be fixed 0x58
1221 emmcmd42[50] = 0x58;
1222 emmcmd42[49] = ep->emm[54]; // keynr
1224 if((dre_cmd(emmcmd42))) // second emm request
1226 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1227 { return ERROR; } // exit if response is not 90 00
1231 return OK;
1233 return ERROR;
1236 static int32_t dre_card_info(struct s_reader *UNUSED(rdr))
1238 return OK;
1241 const struct s_cardsystem reader_dre =
1243 .desc = "dre",
1244 .caids = (uint16_t[]){ 0x4AE0, 0x4AE1, 0x7BE0, 0x7BE1, 0x2710, 0 },
1245 .do_emm = dre_do_emm,
1246 .do_ecm = dre_do_ecm,
1247 .card_info = dre_card_info,
1248 .card_init = dre_card_init,
1249 .get_emm_type = dre_common_get_emm_type,
1250 .get_emm_filter = dre_common_get_emm_filter,
1253 #endif