3 #include "cscrypt/des.h"
4 #include "reader-common.h"
5 #include "reader-dre-common.h"
12 #define OK_RESPONSE 0x61
15 static uint8_t xor(const uint8_t *cmd
, int32_t cmdlen
)
18 uint8_t checksum
= 0x00;
19 for(i
= 0; i
< cmdlen
; i
++)
20 { checksum
^= cmd
[i
]; }
24 static int8_t isValidDCW(uint8_t *dw
)
26 if (((dw
[0] + dw
[1] + dw
[2]) & 0xFF) != dw
[3])
30 if (((dw
[4] + dw
[5] + dw
[6]) & 0xFF) != dw
[7])
34 if (((dw
[8] + dw
[9] + dw
[10]) & 0xFF) != dw
[11])
38 if (((dw
[12] + dw
[13] + dw
[14]) & 0xFF) != dw
[15])
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
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
60 int32_t headerlen
= sizeof(startcmd
);
65 startcmd
[2] = crypted
;
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
);
77 checksum
= ~xor(cmd
, cmdlen
);
78 //rdr_log_dbg(reader, D_READER, "Checksum: %02x", checksum);
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]);
105 if((cta_res
[1] == 0x03) && (cta_res
[2] == 0xe2))
107 switch(cta_res
[3 + dre_v
])
110 rdr_log(reader
, "checksum error: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
114 rdr_log(reader
, "wrong cmd len: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
118 rdr_log(reader
, "illegal command: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
122 rdr_log(reader
, "wrong adress type: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
126 rdr_log(reader
, "wrong CMD param: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
130 rdr_log(reader
, "wrong UA: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
134 rdr_log(reader
, "wrong group: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
138 rdr_log(reader
, "wrong key num: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
142 rdr_log(reader
, "No key or subscribe: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
146 rdr_log(reader
, "wrong signature: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
150 rdr_log(reader
, "wrong provider: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
154 rdr_log(reader
, "wrong GEO code: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
158 rdr_log_dbg(reader
, D_READER
, "unknown error: %s.", cs_hexdump(0, cta_res
, *p_cta_lr
, tmp
, sizeof(tmp
)));
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
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
)
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
)
214 subscr
[3] = csystem_data
->provider
;
225 subscr
[3] = csystem_data
->provider
;
232 subscr
[1] = csystem_data
->provider
;
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
++)
251 dates
[2] = csystem_data
->provider
;
252 dre_cmd(dates
); // ask for validity dates
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];
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
288 static void dre_read_ee(struct s_reader
*reader
, const char *path
, uint8_t provid
)
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))
312 rdr_log(reader
, "ERROR read ee.bin from card");
316 memcpy(&ee
[((n
* 8) + i
) * 32] ,&cta_res
[2] ,32);
321 FILE *pFile
= fopen(path
, "wb");
329 fwrite(ee
, 2048, 1, pFile
);
332 rdr_log(reader
, "ee.bin saved to %s", path
);
335 static void cmd_test(struct s_reader *reader)
339 uint8_t drecmd[] = { 0x00, 0x02 };
342 for(i = 0; i <= 0xFF; i++)
344 if(i == 0x45) continue;
347 if(cta_res[2] == 0xE2)
349 if(cta_res[3] != 0xE3) rdr_log(reader, "cmd %02X error %02X",i ,cta_res[3]);
353 rdr_log(reader, "cmd %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
359 //memset(drecmd, 0, 64);
361 for(i = 2; i <= 64; i++)
363 memset(drecmd, 0, 64);
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)));
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
)
385 uint8_t ua
[] = { 0x43, 0x15 }; // get serial number (UA)
386 uint8_t providers
[] = { 0x49, 0x15 }; // get providers
387 uint8_t cmd56
[] = { 0x56, 0x00 };
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))
401 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct dre_data
)))
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]); }
414 if(!(dre_cmd(cmd56
))) { return ERROR
; }
415 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00)) { return ERROR
; }
420 card
= "Tricolor Centr DRE3";
421 reader
->caid
= 0x4ae1;
425 card
= "Tricolor Syberia DRE3";
426 reader
->caid
= 0x4ae1;
431 card
= "Tricolor Centr DRE4";
432 reader
->caid
= 0x2710;
436 card
= "Tricolor Syberia DRE4";
437 reader
->caid
= 0x2710;
443 csystem_data
->provider
= cta_res
[4];
448 card
= "Tricolor Centr DRE2";
449 reader
->caid
= 0x4ae1;
450 break; // 59 type card = MSP (74 type = ATMEL)
454 reader
->caid
= 0x4ae1; // TODO not sure about this one
458 card
= "Tricolor Syberia DRE2";
459 reader
->caid
= 0x4ae1;
460 break; // 59 type card
463 card
= "Platforma HD / DW old";
464 reader
->caid
= 0x4ae1;
465 break; // 59 type card
471 memset(reader
->prid
, 0x00, 8);
475 reader
->prid
[0][3] = atr
[6];
479 reader
->prid
[0][3] = csystem_data
->provider
;
482 uint8_t cmd54
[] = { 0x54, 0x14 }; // geocode
483 cmd54
[1] = csystem_data
->provider
;
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))
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)
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
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
;
526 if(major_version
< 0x3)
528 low_dre_id
= ((cta_res
[4] << 16) | (cta_res
[5] << 8) | cta_res
[6]) - 48608;
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
++)
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
);
551 low_dre_id
= ((cta_res
[4] << 16) | (cta_res
[5] << 8) | cta_res
[6]);
553 snprintf((char *)buf
, sizeof(buf
), "%i%i%08i", csystem_data
->provider
, major_version
, low_dre_id
);
555 for(i
= 0; i
< 32; i
++)
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
)));
579 // exec user script, wicardd format
580 if(reader
->userscript
!= NULL
)
582 uint8_t *usercmd
= NULL
;
585 char *tempbuf
= malloc(2048);
586 trim2(reader
->userscript
);
587 FILE *pFile
= fopen(reader
->userscript
, "rt");
591 uint8_t ignoreProvid
= 0;
593 uint8_t cryptkey
= 0;
597 if(usercmd
!= NULL
) free(usercmd
);
599 if(fgets(tempbuf
, 2048, pFile
) == NULL
) continue;
601 if(strlen(tempbuf
) < 10) continue;
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
);
615 else if(strncmp(tempbuf
,"CR" ,2) == 0)
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;
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]);
638 rdr_log(reader
, "User script: %s", tempbuf
);
642 rdr_log(reader
, "Script %s", (dre_script(usercmd
, cmd_len
, ignoreProvid
, crypted
, cryptkey
)) ? "done" : "error");
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;
662 if(!dre_set_provider_info(reader
))
663 { return ERROR
; } // fatal error
666 rdr_log(reader
, "ready for requests");
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");
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
)
692 uint16_t overcryptId
;
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);
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?
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
);
753 memcpy(ea
->cw
, tmp
, 16);
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);
769 else if((csystem_data
->provider
== 0x02 || csystem_data
->provider
== 0x03) && er
->ecm
[3] == 3)
775 memcpy(ea
->cw
, &er
->ecm
[42], 8);
776 memcpy(&ea
->cw
[8], &er
->ecm
[34], 8);
781 uint8_t crypted
= er
->ecm
[8] & 1;
782 uint8_t cryptkey
= (er
->ecm
[8] & 6) >> 1;
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);
808 else if(reader
->caid
== 0x2710 && er
->ecm
[3] == 4)
814 memcpy(ea
->cw
, &er
->ecm
[22], 8);
815 memcpy(&ea
->cw
[8], &er
->ecm
[14], 8);
820 uint8_t crypted
= er
->ecm
[8] & 1;
821 uint8_t cryptkey
= (er
->ecm
[8] & 6) >> 1;
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);
849 static int32_t dre_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
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];
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))
870 else if(ep
->emm
[0] == 0x86 && ep
->emm
[4] == 0x02 /*&& csystem_data->provider != 0x11*/)
872 uint8_t emmcmd52
[0x3a];
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];
896 emmcmd52
[2] = ep
->emm
[5];
898 emmcmd52
[4] = ep
->emm
[3];
905 memcpy(emmcmd52
+ 13, ep
->emm
+ 0x5C, 4);
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
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
982 else if(ep
->type
== GLOBAL
&& ep
->emm
[0] == 0x91)
984 Drecrypt2OverEMM(ep
->emm
);
989 else if(reader
->caid
== 0x2710)
992 if(ep
->type
== UNIQUE
)
995 uint8_t class, hlbUA
, KEYindex
;
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];
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);
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
1040 if (emmcmd91
[17] == 0x56) KEYindex
= 0x3B;
1041 else KEYindex
= 0x56;
1044 memcpy(&emmcmd91
[9], &ep
->emm
[keypos
], 8);
1045 emmcmd91
[17] = KEYindex
;
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
1057 else if (CMDtype
== 0x62)
1059 if (!memcmp(&reader
->hexserial
[2], &ep
->emm
[3], 4))
1070 uint8_t emmcmd92
[cmdlen
];
1072 memcpy(emmcmd92
, &ep
->emm
[19], cmdlen
- 1);
1073 emmcmd92
[cmdlen
- 1] = csystem_data
->provider
;
1077 dre_cmd_c(emmcmd92
, crypted
, cryptkey
);
1084 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1085 { return ERROR
; } // exit if response is not 90 00
1089 uint8_t emmcmd95
[3];
1092 emmcmd95
[1] = class;
1093 emmcmd95
[2] = csystem_data
->provider
;
1097 uint8_t emmcmd91
[19];
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
;
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
;
1123 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1124 { return ERROR
; } // exit if response is not 90 00
1130 if (memcmp(&reader
->hexserial
[2], &ep
->emm
[3], 4)) return OK
;
1132 if (CMDtype
== 0x63)
1134 uint8_t emmcmdA5
[7];
1138 memcpy(&emmcmdA5
[2], &reader
->hexserial
[2], 4);
1139 emmcmdA5
[6] = csystem_data
->provider
;
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");
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
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,
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
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
1208 59 05 A2 02 05 01 5B
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
1236 static int32_t dre_card_info(struct s_reader
*UNUSED(rdr
))
1241 const struct s_cardsystem reader_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
,