static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea) { def_resp; char tmp_dbg[256]; struct dre_data *csystem_data = reader->csystem_data; if(reader->caid == 0x4ae0) { uchar ecmcmd41[] = { 0x41, 0x58, 0x1f, 0x00, //fixed part, dont change 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //0x01 - 0x08: next key 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, //0x11 - 0x18: current key 0x3b, 0x59, 0x11 //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider }; ecmcmd41[22] = csystem_data->provider; memcpy(ecmcmd41 + 4, er->ecm + 8, 16); ecmcmd41[20] = er->ecm[6]; //keynumber ecmcmd41[21] = 0x58 + er->ecm[25]; //package number rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg))); 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))); if((dre_cmd(ecmcmd41))) //ecm request { if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; } //exit if response is not 90 00 memcpy(ea->cw, cta_res + 11, 8); memcpy(ea->cw + 8, cta_res + 3, 8); return OK; } } else { uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, //fixed header? 0x9C, 0xDA, //first three nibbles count up, fourth nibble counts down; all ECMs sent twice 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, //next key? 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, //current key? 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, //key or signature? 0x14 //provider }; memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21); rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg))); rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg))); ecmcmd51[33] = csystem_data->provider; //no part of sig if((dre_cmd(ecmcmd51))) //ecm request { if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; } //exit if response is not 90 00 DREover(er->ecm, cta_res + 3); memcpy(ea->cw, cta_res + 11, 8); memcpy(ea->cw + 8, cta_res + 3, 8); return OK; } } return ERROR; }
static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea) { def_resp; uint16_t overcryptId; uint8_t tmp[16]; char tmp_dbg[256]; struct dre_data *csystem_data = reader->csystem_data; if(reader->caid == 0x4ae0) { uchar ecmcmd41[] = { 0x41, 0x58, 0x1f, 0x00, //fixed part, dont change 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //0x01 - 0x08: next key 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, //0x11 - 0x18: current key 0x3b, 0x59, 0x11 //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider }; ecmcmd41[22] = csystem_data->provider; memcpy(ecmcmd41 + 4, er->ecm + 8, 16); ecmcmd41[20] = er->ecm[6]; //keynumber ecmcmd41[21] = 0x58 + er->ecm[25]; //package number rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg))); 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))); if((dre_cmd(ecmcmd41))) //ecm request { if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; } //exit if response is not 90 00 memcpy(ea->cw, cta_res + 11, 8); memcpy(ea->cw + 8, cta_res + 3, 8); return OK; } } else if(reader->caid == 0x4ae1) { if(csystem_data->provider == 0x11 || csystem_data->provider == 0x14) { uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, //fixed header? 0x9C, 0xDA, //first three nibbles count up, fourth nibble counts down; all ECMs sent twice 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, //next key? 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, //current key? 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, //key or signature? 0x14 //provider }; memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21); rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg))); rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg))); ecmcmd51[33] = csystem_data->provider; //no part of sig if((dre_cmd(ecmcmd51))) //ecm request { if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; } //exit if response is not 90 00 if(er->ecm[2] >= 46 && er->ecm[43] == 1 && csystem_data->provider == 0x11) { memcpy(tmp, cta_res + 11, 8); memcpy(tmp + 8, cta_res + 3, 8); overcryptId = b2i(2, &er->ecm[44]); rdr_log_dbg(reader, D_READER, "ICG ID: %04X", overcryptId); Drecrypt2OverCW(overcryptId,tmp); if(isValidDCW(tmp)) { memcpy(ea->cw, tmp, 16); return OK; } return ERROR; } DREover(reader, er->ecm, cta_res + 3); if(isValidDCW(cta_res + 3)) { memcpy(ea->cw, cta_res + 11, 8); memcpy(ea->cw + 8, cta_res + 3, 8); return OK; } } } else if((csystem_data->provider == 0x02 || csystem_data->provider == 0x03) && er->ecm[3] == 3) { // DRE 3 if (er->ecm[4] == 2) { memcpy( ea->cw , &er->ecm[42], 8); memcpy(&ea->cw[8], &er->ecm[34], 8); return OK; } uchar cmdlen; uchar crypted = er->ecm[8] & 1; uchar cryptkey = (er->ecm[8] & 6) >> 1; if (crypted == 0) { cmdlen = 50; } else { cmdlen = 57; } uchar ecmcmd[cmdlen]; memcpy(ecmcmd, &er->ecm[17], cmdlen-1); ecmcmd[cmdlen-1] = csystem_data->provider; dre_cmd_c(ecmcmd, crypted, cryptkey); if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3)) { memcpy(ea->cw, cta_res+11, 8); memcpy(ea->cw+8, cta_res+3, 8); return OK; } } } else if(reader->caid == 0x2710 && er->ecm[3] == 4)