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_nb(cmd, len, cmd_type, crypted, keynum) \
181 dre_command(reader, cmd, len, cta_res, &cta_lr, crypted, keynum, crypted, cmd_type); \
183 #define dre_script(cmd, len, cmd_type, crypted, keynum) \
185 dre_script_nb(cmd, len, cmd_type, crypted, keynum) \
188 #define dre_cmd_nb(cmd) \
189 dre_command(reader, cmd, sizeof(cmd), cta_res, &cta_lr, 0, 0, 0, 0); \
191 #define dre_cmd(cmd) \
196 #define dre_cmd_c_nb(cmd,crypted,keynum) \
197 dre_command(reader, cmd, sizeof(cmd),cta_res,&cta_lr, crypted, keynum, 1, 0); \
199 #define dre_cmd_c(cmd,crypted,keynum) \
201 dre_cmd_c_nb(cmd,crypted,keynum) \
204 static int32_t dre_set_provider_info(struct s_reader
*reader
)
208 int subscr_cmd_len
= 4;
209 uint8_t subscr
[4]; // = { 0x59, 0x14 }; // subscriptions
210 uint8_t dates
[] = { 0x5b, 0x00, 0x14 }; // validity dates
211 uint8_t subscr_len
= 0, n
= 0;
212 struct dre_data
*csystem_data
= reader
->csystem_data
;
214 cs_clear_entitlement(reader
);
216 switch(csystem_data
->provider
)
223 subscr
[3] = csystem_data
->provider
;
234 subscr
[3] = csystem_data
->provider
;
241 subscr
[1] = csystem_data
->provider
;
248 if(({dre_script_nb(subscr
, subscr_cmd_len
, 0, 0, 0)})) // ask subscription packages, returns error on 0x11 card
250 uint8_t pbm
[subscr_len
];
251 char tmp_dbg
[subscr_len
*2+1];
252 memcpy(pbm
, cta_res
+ 3, cta_lr
- 6);
253 rdr_log_dbg(reader
, D_READER
, "pbm: %s", cs_hexdump(0, pbm
, subscr_len
, tmp_dbg
, sizeof(tmp_dbg
)));
255 for(i
= 0; i
< subscr_len
; i
++)
260 dates
[2] = csystem_data
->provider
;
261 dre_cmd(dates
); // ask for validity dates
265 start
= (cta_res
[3] << 24) | (cta_res
[4] << 16) | (cta_res
[5] << 8) | cta_res
[6];
266 end
= (cta_res
[7] << 24) | (cta_res
[8] << 16) | (cta_res
[9] << 8) | cta_res
[10];
270 localtime_r(&start
, &temp
);
271 int32_t startyear
= temp
.tm_year
+ 1900;
272 int32_t startmonth
= temp
.tm_mon
+ 1;
273 int32_t startday
= temp
.tm_mday
;
274 localtime_r(&end
, &temp
);
275 int32_t endyear
= temp
.tm_year
+ 1900;
276 int32_t endmonth
= temp
.tm_mon
+ 1;
277 int32_t endday
= temp
.tm_mday
;
278 rdr_log(reader
, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i",
279 i
+ n
, startyear
, startmonth
, startday
, endyear
, endmonth
, endday
);
280 cs_add_entitlement(reader
, reader
->caid
, b2ll(4, reader
->prid
[0]), 0, i
+ n
, start
, end
, 5, 1);
285 if(subscr_len
== 0x5F) // read second part subscription packages, for DRE3 and DRE4
297 static void dre_read_ee(struct s_reader
*reader
, const char *path
, uint8_t provid
)
301 uint8_t *ee
= malloc(2048);
302 if(ee
== NULL
) return;
304 uint8_t drecmd43
[] = { 0x80, 0x00, 0x00, 0x00, 0x05, 0x59, 0x03, 0x43, 0x11, 0xAD };
305 uint8_t drecmd45
[] = { 0x45, 0x11 };
307 drecmd43
[8] = drecmd45
[1] = provid
;
308 drecmd43
[9] = ~xor(&drecmd43
[7], 2);
310 for(i
= 0; i
< 8; i
++)
312 for(n
= 0; n
< 8; n
++)
314 reader_cmd2icc(reader
, drecmd43
, 10, cta_res
, &cta_lr
);
316 dre_cmd_c(drecmd45
, n
, i
* 32);
318 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
321 rdr_log(reader
, "ERROR read ee.bin from card");
325 memcpy(&ee
[((n
* 8) + i
) * 32] ,&cta_res
[2] ,32);
330 FILE *pFile
= fopen(path
, "wb");
338 fwrite(ee
, 2048, 1, pFile
);
341 rdr_log(reader
, "ee.bin saved to %s", path
);
344 static void cmd_test(struct s_reader *reader)
348 uint8_t drecmd[] = { 0x00, 0x02 };
351 for(i = 0; i <= 0xFF; i++)
353 if(i == 0x45) continue;
356 if(cta_res[2] == 0xE2)
358 if(cta_res[3] != 0xE3) rdr_log(reader, "cmd %02X error %02X",i ,cta_res[3]);
362 rdr_log(reader, "cmd %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
368 //memset(drecmd, 0, 64);
370 for(i = 2; i <= 64; i++)
372 memset(drecmd, 0, 64);
376 dre_script(drecmd, i, 0, 0, 0);
378 if(cta_res[2] == 0xE2)
380 if((cta_res[3] != 0xE2) & (cta_res[3] != 0xED)) rdr_log(reader, "Len %02X error %02X",i ,cta_res[3]);
381 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)));
385 rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
390 static int32_t dre_card_init(struct s_reader
*reader
, ATR
*newatr
)
394 uint8_t ua
[] = { 0x43, 0x15 }; // get serial number (UA)
395 uint8_t providers
[] = { 0x49, 0x15 }; // get providers
396 uint8_t cmd56
[] = { 0x56, 0x00 };
401 if((atr
[0] != 0x3b) || (atr
[1] != 0x15) || (atr
[2] != 0x11) || (atr
[3] != 0x12) || (
402 ((atr
[4] != 0x01) || (atr
[5] != 0x01)) &&
403 ((atr
[4] != 0xca) || (atr
[5] != 0x07)) &&
404 ((atr
[4] != 0xcb) || (atr
[5] != 0x07)) &&
405 ((atr
[4] != 0xcc) || (atr
[5] != 0x07)) &&
406 ((atr
[4] != 0xcd) || (atr
[5] != 0x07))
410 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct dre_data
)))
412 struct dre_data
*csystem_data
= reader
->csystem_data
;
414 csystem_data
->provider
= atr
[6];
415 uint8_t checksum
= xor(atr
+ 1, 6);
417 if(checksum
!= atr
[7])
418 { rdr_log(reader
, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum
, atr
[7]); }
423 if(!({dre_cmd_nb(cmd56
)})) { return ERROR
; }
424 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00)) { return ERROR
; }
429 card
= "Tricolor Centr DRE3";
430 reader
->caid
= 0x4ae1;
434 card
= "Tricolor Syberia DRE3";
435 reader
->caid
= 0x4ae1;
440 card
= "Tricolor Centr DRE4";
441 reader
->caid
= 0x2710;
445 card
= "Tricolor Syberia DRE4";
446 reader
->caid
= 0x2710;
452 csystem_data
->provider
= cta_res
[4];
457 card
= "Tricolor Centr DRE2";
458 reader
->caid
= 0x4ae1;
459 break; // 59 type card = MSP (74 type = ATMEL)
463 reader
->caid
= 0x4ae1; // TODO not sure about this one
467 card
= "Tricolor Syberia DRE2";
468 reader
->caid
= 0x4ae1;
469 break; // 59 type card
472 card
= "Platforma HD / DW old";
473 reader
->caid
= 0x4ae1;
474 break; // 59 type card
480 memset(reader
->prid
, 0x00, 8);
484 reader
->prid
[0][3] = atr
[6];
488 reader
->prid
[0][3] = csystem_data
->provider
;
491 uint8_t cmd54
[] = { 0x54, 0x14 }; // geocode
492 cmd54
[1] = csystem_data
->provider
;
495 if(({dre_cmd_nb(cmd54
)})) // error would not be fatal, like on 0x11 cards
496 { geocode
= cta_res
[3]; }
498 providers
[1] = csystem_data
->provider
;
499 if(!({dre_cmd_nb(providers
)}))
500 { return ERROR
; } // fatal error
502 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
505 uint8_t provname
[128];
507 for(i
= 0; ((i
< cta_res
[2] - 6) && (i
< 128)); i
++)
509 provname
[i
] = cta_res
[6 + i
];
510 if(provname
[i
] == 0x00)
514 int32_t major_version
= cta_res
[3];
515 int32_t minor_version
= cta_res
[4];
517 ua
[1] = csystem_data
->provider
;
518 dre_cmd(ua
); // error would not be fatal
520 int32_t hexlength
= cta_res
[1] - 2; // discard first and last byte, last byte is always checksum, first is answer code
524 rdr_log(reader
, "WARNING!!! used UA from force_ua %08X", reader
->force_ua
);
525 memcpy(cta_res
+ 3, &reader
->force_ua
, 4);
528 reader
->hexserial
[0] = 0;
529 reader
->hexserial
[1] = 0;
530 memcpy(reader
->hexserial
+ 2, cta_res
+ 3, hexlength
);
532 int32_t low_dre_id
, dre_chksum
;
535 if(major_version
< 0x3)
537 low_dre_id
= ((cta_res
[4] << 16) | (cta_res
[5] << 8) | cta_res
[6]) - 48608;
539 snprintf((char *)buf
, sizeof(buf
), "%i%i%08i", csystem_data
->provider
- 16, major_version
+ 1, low_dre_id
);
541 for(i
= 0; i
< 32; i
++)
545 dre_chksum
+= buf
[i
] - 48;
548 if(major_version
< 2)
550 reader
->caid
= 0x4ae0;
551 card
= csystem_data
->provider
== 0x11 ? "Tricolor Centr DRE1" : "Tricolor Syberia DRE1";
554 rdr_log(reader
, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
555 reader
->caid
, cs_hexdump(0, reader
->hexserial
+ 2, 4, tmp
, sizeof(tmp
)), dre_chksum
,
556 csystem_data
->provider
- 16, major_version
+ 1, low_dre_id
, geocode
, card
, major_version
, minor_version
);
560 low_dre_id
= ((cta_res
[4] << 16) | (cta_res
[5] << 8) | cta_res
[6]);
562 snprintf((char *)buf
, sizeof(buf
), "%i%i%08i", csystem_data
->provider
, major_version
, low_dre_id
);
564 for(i
= 0; i
< 32; i
++)
568 dre_chksum
+= buf
[i
] - 48;
570 rdr_log(reader
, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%03i%i%08i, geocode %i, card: %s v%i.%i",
571 reader
->caid
, cs_hexdump(0, reader
->hexserial
+ 2, 4, tmp
, sizeof(tmp
)), dre_chksum
, csystem_data
->provider
,
572 major_version
, low_dre_id
, geocode
, card
, major_version
, minor_version
);
575 rdr_log(reader
, "Provider name:%s.", provname
);
578 memset(reader
->sa
, 0, sizeof(reader
->sa
));
579 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...
581 rdr_log_sensitive(reader
, "SA = %02X%02X%02X%02X, UA = {%s}", reader
->sa
[0][0], reader
->sa
[0][1], reader
->sa
[0][2],
582 reader
->sa
[0][3], cs_hexdump(0, reader
->hexserial
+ 2, 4, tmp
, sizeof(tmp
)));
588 // exec user script, wicardd format
589 if(reader
->userscript
!= NULL
)
591 uint8_t *usercmd
= NULL
;
594 char *tempbuf
= malloc(2048);
595 trim2(reader
->userscript
);
596 FILE *pFile
= fopen(reader
->userscript
, "rt");
600 uint8_t ignoreProvid
= 0;
602 uint8_t cryptkey
= 0;
606 if(usercmd
!= NULL
) NULLFREE(usercmd
);
608 if(fgets(tempbuf
, 2048, pFile
) == NULL
) continue;
610 if(cs_strlen(tempbuf
) < 10) continue;
618 if(tempbuf
[0] == '8' && tempbuf
[1] == '6' && csystem_data
->provider
== 0x11) ignoreProvid
= 1;
619 else if(strncmp(tempbuf
,"REG2" ,4) == 0)
621 dre_read_ee(reader
, &tempbuf
[4] ,csystem_data
->provider
);
624 else if(strncmp(tempbuf
,"CR" ,2) == 0)
627 cryptkey
= ((tempbuf
[2] - (tempbuf
[2] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf
[3] - (tempbuf
[3] > 0x39 ? 0x37:0x30)) & 0xF);
629 else if(tempbuf
[0] != '5' && tempbuf
[1] != '9') continue;
633 cmd_len
= cs_strlen(tempbuf
) / 2 - 3 + ignoreProvid
- (crypted
* 2);
634 usercmd
= malloc(cmd_len
);
636 for(i
= 0, n
= 4 + (crypted
* 4); i
< cmd_len
; i
++, n
+= 2)
638 usercmd
[i
] = ((tempbuf
[n
] - (tempbuf
[n
] > 0x39 ? 0x37 : 0x30)) << 4) + ((tempbuf
[n
+ 1] - (tempbuf
[n
+ 1] > 0x39 ? 0x37 : 0x30)) & 0xF);
641 /*if(usercmd[cmd_len-1] != csystem_data->provider && !ignoreProvid)
643 rdr_log(reader, "Skip script: current provid %02X , script provid %02X", csystem_data->provider, usercmd[cmd_len-1]);
647 rdr_log(reader
, "User script: %s", tempbuf
);
651 rdr_log(reader
, "Script %s", ({dre_script_nb(usercmd
, cmd_len
, ignoreProvid
, crypted
, cryptkey
)}) ? "done" : "error");
657 rdr_log(reader
, "Can't open script file (%s)", reader
->userscript
);
660 if(usercmd
!= NULL
) free(usercmd
);
661 if(tempbuf
!= NULL
) free(tempbuf
);
664 if(csystem_data
->provider
== 0x11)
666 memset(reader
->prid
[1], 0x00, 8);
667 reader
->prid
[1][3] = 0xFE;
671 if(!dre_set_provider_info(reader
))
672 { return ERROR
; } // fatal error
675 rdr_log(reader
, "ready for requests");
679 static void DREover(struct s_reader
*reader
, const uint8_t *ECMdata
, uint8_t *DW
)
681 uint32_t key_schedule
[32];
683 if(reader
->des_key_length
< 128)
685 rdr_log(reader
, "error: deskey is missing or too short");
689 if(ECMdata
[2] >= (43 + 4) && ECMdata
[40] == 0x3A && ECMdata
[41] == 0x4B)
691 des_set_key(&reader
->des_key
[(ECMdata
[42] & 0x0F) * 8], key_schedule
);
693 des(DW
, key_schedule
, 0); // even DW post-process
694 des(DW
+ 8, key_schedule
, 0); // odd DW post-process
698 static int32_t dre_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
701 uint16_t overcryptId
;
704 struct dre_data
*csystem_data
= reader
->csystem_data
;
705 if(reader
->caid
== 0x4ae0)
707 uint8_t ecmcmd41
[] = { 0x41,
708 0x58, 0x1f, 0x00, // fixed part, dont change
709 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x01 - 0x08: next key
710 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // 0x11 - 0x18: current key
711 0x3b, 0x59, 0x11 }; // 0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
713 ecmcmd41
[22] = csystem_data
->provider
;
714 memcpy(ecmcmd41
+ 4, er
->ecm
+ 8, 16);
715 ecmcmd41
[20] = er
->ecm
[6]; // keynumber
716 ecmcmd41
[21] = 0x58 + er
->ecm
[25]; // package number
717 rdr_log_dbg(reader
, D_READER
, "unused ECM info front:%s", cs_hexdump(0, er
->ecm
, 8, tmp_dbg
, sizeof(tmp_dbg
)));
718 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
)));
720 if(({dre_cmd_nb(ecmcmd41
)})) // ecm request
722 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
723 { return ERROR
; } // exit if response is not 90 00
724 memcpy(ea
->cw
, cta_res
+ 11, 8);
725 memcpy(ea
->cw
+ 8, cta_res
+ 3, 8);
730 else if(reader
->caid
== 0x4ae1)
732 if(csystem_data
->provider
== 0x11 || csystem_data
->provider
== 0x14)
734 uint8_t ecmcmd51
[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, // fixed header?
735 0x9C, 0xDA, // first three nibbles count up, fourth nibble counts down; all ECMs sent twice
736 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, // next key?
737 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, // current key?
738 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, // key or signature?
741 memcpy(ecmcmd51
+ 1, er
->ecm
+ 5, 0x21);
742 rdr_log_dbg(reader
, D_READER
, "unused ECM info front:%s", cs_hexdump(0, er
->ecm
, 5, tmp_dbg
, sizeof(tmp_dbg
)));
743 rdr_log_dbg(reader
, D_READER
, "unused ECM info back:%s", cs_hexdump(0, er
->ecm
+ 37, 4, tmp_dbg
, sizeof(tmp_dbg
)));
744 ecmcmd51
[33] = csystem_data
->provider
; // no part of sig
746 if(({dre_cmd_nb(ecmcmd51
)})) // ecm request
748 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
749 { return ERROR
; } // exit if response is not 90 00
751 if(er
->ecm
[2] >= 46 && er
->ecm
[43] == 1 && csystem_data
->provider
== 0x11)
753 memcpy(tmp
, cta_res
+ 11, 8);
754 memcpy(tmp
+ 8, cta_res
+ 3, 8);
755 overcryptId
= b2i(2, &er
->ecm
[44]);
756 rdr_log_dbg(reader
, D_READER
, "ICG ID: %04X", overcryptId
);
758 Drecrypt2OverCW(overcryptId
,tmp
);
762 memcpy(ea
->cw
, tmp
, 16);
768 DREover(reader
, er
->ecm
, cta_res
+ 3);
770 if(isValidDCW(cta_res
+ 3))
772 memcpy(ea
->cw
, cta_res
+ 11, 8);
773 memcpy(ea
->cw
+ 8, cta_res
+ 3, 8);
778 else if((csystem_data
->provider
== 0x02 || csystem_data
->provider
== 0x03) && er
->ecm
[3] == 3)
784 memcpy(ea
->cw
, &er
->ecm
[42], 8);
785 memcpy(&ea
->cw
[8], &er
->ecm
[34], 8);
790 uint8_t crypted
= er
->ecm
[8] & 1;
791 uint8_t cryptkey
= (er
->ecm
[8] & 6) >> 1;
802 uint8_t ecmcmd
[cmdlen
];
804 memcpy(ecmcmd
, &er
->ecm
[17], 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);
817 else if(reader
->caid
== 0x2710 && er
->ecm
[3] == 4)
823 memcpy(ea
->cw
, &er
->ecm
[22], 8);
824 memcpy(&ea
->cw
[8], &er
->ecm
[14], 8);
829 uint8_t crypted
= er
->ecm
[8] & 1;
830 uint8_t cryptkey
= (er
->ecm
[8] & 6) >> 1;
841 uint8_t ecmcmd
[cmdlen
];
843 memcpy(ecmcmd
, &er
->ecm
[9], cmdlen
- 1);
844 ecmcmd
[cmdlen
- 1] = csystem_data
->provider
;
846 dre_cmd_c(ecmcmd
, crypted
, cryptkey
);
848 if(cta_res
[2] == 0xD2 && isValidDCW(cta_res
+ 3))
850 memcpy(ea
->cw
, cta_res
+ 11, 8);
851 memcpy(ea
->cw
+ 8, cta_res
+ 3, 8);
858 static int32_t dre_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
861 struct dre_data
*csystem_data
= reader
->csystem_data
;
863 if(reader
->caid
== 0x4ae1)
865 if(reader
->caid
!= b2i(2, ep
->caid
)) return ERROR
;
867 if(ep
->type
== UNIQUE
&& ep
->emm
[39] == 0x3d)
869 /* For new package activation. */
870 uint8_t emmcmd58
[26];
872 memcpy(&emmcmd58
[1], &ep
->emm
[40], 24);
873 emmcmd58
[25] = csystem_data
->provider
;
875 if(({dre_cmd_nb(emmcmd58
)}))
876 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
879 else if(ep
->emm
[0] == 0x86 && ep
->emm
[4] == 0x02 /*&& csystem_data->provider != 0x11*/)
881 uint8_t emmcmd52
[0x3a];
884 for(i
= 0; i
< 2; i
++)
886 memcpy(emmcmd52
+ 1, ep
->emm
+ 5 + 32 + i
* 56, 56);
888 // check for shared address
889 if(ep
->emm
[3] != reader
->sa
[0][0])
890 { return OK
; } // ignore, wrong address
892 emmcmd52
[0x39] = csystem_data
->provider
;
894 if(({dre_cmd_nb(emmcmd52
)}))
895 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
896 { return ERROR
; } // exit if response is not 90 00
899 else if(ep
->emm
[0] == 0x86 && ep
->emm
[4] == 0x4D && csystem_data
->provider
== 0x11)
901 uint8_t emmcmd52
[0x3a];
905 emmcmd52
[2] = ep
->emm
[5];
907 emmcmd52
[4] = ep
->emm
[3];
914 memcpy(emmcmd52
+ 13, ep
->emm
+ 0x5C, 4);
917 for(i
= 0; i
< 2; i
++)
919 emmcmd52
[8] = ep
->emm
[0x61 + i
* 0x29];
920 if(i
== 0) emmcmd52
[12] = ep
->emm
[0x60] == 0x56 ? 0x56 : 0x3B;
921 else emmcmd52
[12] = ep
->emm
[0x60] == 0x56 ? 0x3B : 0x56;
922 memcpy(emmcmd52
+ 0x11, ep
->emm
+ 0x62 + i
* 0x29, 40);
924 // check for shared address
925 if(ep
->emm
[3] != reader
->sa
[0][0])
926 { return OK
; } // ignore, wrong address
928 emmcmd52
[0x39] = csystem_data
->provider
;
930 if(({dre_cmd_nb(emmcmd52
)}))
931 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
932 { return ERROR
; } // exit if response is not 90 00
935 else if (ep
->emm
[0] == 0x8c && (csystem_data
->provider
== 0x02 || csystem_data
->provider
== 0x03)) // dre3 group emm
937 if(ep
->emm
[3] != reader
->sa
[0][0])
938 { return OK
; } // ignore, wrong address
940 uint8_t crypted
= ep
->emm
[10];
942 if ((crypted
& 1) == 1)
944 uint8_t emmcmd
[0x49];
946 memcpy(emmcmd
, &ep
->emm
[0x13], 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 memcpy(emmcmd
, &ep
->emm
[0x5B], 0x48);
957 emmcmd
[0x48] = csystem_data
->provider
;
959 dre_cmd_c(emmcmd
, crypted
& 1, (crypted
& 6) >> 1);
961 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
962 { return ERROR
; } //exit if response is not 90 00
968 uint8_t emmcmd
[0x42];
970 memcpy(emmcmd
, &ep
->emm
[0x13], 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 memcpy(emmcmd
, &ep
->emm
[0x5B], 0x41);
981 emmcmd
[0x41] = csystem_data
->provider
;
983 dre_cmd_c(emmcmd
, crypted
& 1, (crypted
& 6) >> 1);
985 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
986 { return ERROR
; } // exit if response is not 90 00
991 else if(ep
->type
== GLOBAL
&& ep
->emm
[0] == 0x91)
993 Drecrypt2OverEMM(ep
->emm
);
998 else if(reader
->caid
== 0x2710)
1001 if(ep
->type
== UNIQUE
)
1004 uint8_t class, hlbUA
, KEYindex
;
1006 uint8_t CMDtype
= ep
->emm
[7];
1007 uint16_t EMMlen
= ep
->emm
[2] | ((ep
->emm
[1] & 0xF) << 8);
1008 uint8_t cryptflag
= ep
->emm
[10];
1009 uint8_t crypted
= cryptflag
& 1;
1010 uint8_t cryptkey
= (cryptflag
& 6) >> 1;
1012 if (CMDtype
== 0x61)
1014 uint8_t emmcmd91
[19];
1017 emmcmd91
[1] = ep
->emm
[19];
1018 emmcmd91
[2] = ep
->emm
[8];
1019 emmcmd91
[3] = ep
->emm
[20];
1020 if(reader
->force_ua
) emmcmd91
[3] += 2;
1021 memcpy(&emmcmd91
[4], &reader
->hexserial
[2], 4);
1023 emmcmd91
[17] = ep
->emm
[22];
1024 emmcmd91
[18] = csystem_data
->provider
;
1026 if ((EMMlen
- 24) > 16)
1028 hlbUA
= reader
->hexserial
[5] & 0xF;
1030 uint16_t keypos
= cryptflag
== 2 ? 17 : 9;
1031 keycount
= (EMMlen
- 24) / keypos
;
1033 for(i
= 0; i
<= keycount
;i
++)
1035 if (i
== keycount
) return OK
;
1036 if (hlbUA
== (ep
->emm
[23 + (keypos
* i
)] & 0xF) ) break;
1039 keypos
= 24 + (keypos
* i
);
1041 memcpy(&emmcmd91
[9], &ep
->emm
[keypos
], 8);
1043 if(({dre_cmd_nb(emmcmd91
)}))
1044 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00) || (cta_res
[2] != 0xA2))
1045 return ERROR
; // exit if response is not 90 00
1049 if (emmcmd91
[17] == 0x56) KEYindex
= 0x3B;
1050 else KEYindex
= 0x56;
1053 memcpy(&emmcmd91
[9], &ep
->emm
[keypos
], 8);
1054 emmcmd91
[17] = KEYindex
;
1058 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00) || (cta_res
[2] != 0xA2))
1059 { return ERROR
; } // exit if response is not 90 00
1066 else if (CMDtype
== 0x62)
1068 if (!memcmp(&reader
->hexserial
[2], &ep
->emm
[3], 4))
1079 uint8_t emmcmd92
[cmdlen
];
1081 memcpy(emmcmd92
, &ep
->emm
[19], cmdlen
- 1);
1082 emmcmd92
[cmdlen
- 1] = csystem_data
->provider
;
1086 dre_cmd_c(emmcmd92
, crypted
, cryptkey
);
1093 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1094 { return ERROR
; } // exit if response is not 90 00
1098 uint8_t emmcmd95
[3];
1101 emmcmd95
[1] = class;
1102 emmcmd95
[2] = csystem_data
->provider
;
1106 uint8_t emmcmd91
[19];
1109 emmcmd91
[1] = ep
->emm
[102];
1110 emmcmd91
[2] = ep
->emm
[8];
1111 emmcmd91
[3] = ep
->emm
[103];
1112 if(reader
->force_ua
) emmcmd91
[3] += 2;
1113 memcpy(&emmcmd91
[4], &reader
->hexserial
[2], 4);
1114 emmcmd91
[8] = ep
->emm
[104];
1115 memcpy(&emmcmd91
[9], &ep
->emm
[72], 8);
1116 emmcmd91
[17] = ep
->emm
[105];
1117 emmcmd91
[18] = csystem_data
->provider
;
1121 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00) || (cta_res
[2] != 0xA2) )
1122 { return ERROR
; } // exit if response is not 90 00
1124 if (emmcmd91
[17] == 0x56) KEYindex
= 0x3B;
1125 else KEYindex
= 0x56;
1127 memcpy(&emmcmd91
[9], &ep
->emm
[86], 8);
1128 emmcmd91
[17] = KEYindex
;
1132 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1133 { return ERROR
; } // exit if response is not 90 00
1139 if (memcmp(&reader
->hexserial
[2], &ep
->emm
[3], 4)) return OK
;
1141 if (CMDtype
== 0x63)
1143 uint8_t emmcmdA5
[7];
1147 memcpy(&emmcmdA5
[2], &reader
->hexserial
[2], 4);
1148 emmcmdA5
[6] = csystem_data
->provider
;
1152 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1153 { return ERROR
; } //exit if response is not 90 00
1156 if (crypted
) cmdlen
= EMMlen
- 19;
1157 else cmdlen
= ep
->emm
[11] + 1;
1159 uint8_t emmcmd
[cmdlen
];
1161 memcpy(emmcmd
, &ep
->emm
[19], cmdlen
- 1);
1162 emmcmd
[cmdlen
- 1] = csystem_data
->provider
;
1164 if(emmcmd
[0] == 0x45)
1166 cs_log("TRICOLOR Send KILL command for your card");
1170 dre_cmd_c(emmcmd
, crypted
, cryptkey
);
1172 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1173 { return ERROR
; } //exit if response is not 90 00
1179 else if(reader
->caid
!= 0x2710 && reader
->caid
!= 0x4AE1)
1181 uint8_t emmcmd42
[] =
1183 0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
1184 0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
1185 0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
1194 for(i
= 0; i
< 2; i
++)
1196 memcpy(emmcmd42
+ 1, ep
->emm
+ 42 + i
* 49, 48);
1197 emmcmd42
[49] = ep
->emm
[i
* 49 + 41]; // keynr
1198 emmcmd42
[50] = 0x58 + ep
->emm
[40]; // package nr
1199 emmcmd42
[51] = csystem_data
->provider
;
1200 if(({dre_cmd_nb(emmcmd42
)}))
1202 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1203 { return ERROR
; } // exit if response is not 90 00
1210 memcpy(emmcmd42
+ 1, ep
->emm
+ 6, 48);
1211 emmcmd42
[51] = csystem_data
->provider
;
1212 //emmcmd42[50] = ecmcmd42[2]; // TODO package nr could also be fixed 0x58
1213 emmcmd42
[50] = 0x58;
1214 emmcmd42
[49] = ep
->emm
[5]; // keynr
1217 59 05 A2 02 05 01 5B
1220 if(({dre_cmd_nb(emmcmd42
)})) // first emm request
1222 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1223 { return ERROR
; } // exit if response is not 90 00
1225 memcpy(emmcmd42
+ 1, ep
->emm
+ 55, 7); // TODO OR next two lines?
1226 //memcpy (emmcmd42 + 1, ep->emm + 55, 7); // FIXME either I cant count or my EMM log contains errors
1227 //memcpy (emmcmd42 + 8, ep->emm + 67, 41);
1228 emmcmd42
[51] = csystem_data
->provider
;
1229 //emmcmd42[50] = ecmcmd42[2]; // TODO package nr could also be fixed 0x58
1230 emmcmd42
[50] = 0x58;
1231 emmcmd42
[49] = ep
->emm
[54]; // keynr
1233 if(({dre_cmd_nb(emmcmd42
)})) // second emm request
1235 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1] != 0x00))
1236 { return ERROR
; } // exit if response is not 90 00
1245 static int32_t dre_card_info(struct s_reader
*UNUSED(rdr
))
1250 const struct s_cardsystem reader_dre
=
1253 .caids
= (uint16_t[]){ 0x4AE0, 0x4AE1, 0x7BE0, 0x7BE1, 0x2710, 0 },
1254 .do_emm
= dre_do_emm
,
1255 .do_ecm
= dre_do_ecm
,
1256 .card_info
= dre_card_info
,
1257 .card_init
= dre_card_init
,
1258 .get_emm_type
= dre_common_get_emm_type
,
1259 .get_emm_filter
= dre_common_get_emm_filter
,