From a6d32b3aab3fea937958df970ab0a958b900f0e5 Mon Sep 17 00:00:00 2001 From: fairbird Date: Thu, 3 Oct 2024 15:11:19 +0300 Subject: [PATCH] Add support Tongfang3 (NTIC2) CAS (Thanks to @nx111) * Add support Tongfang3 (NTIC2) CAS (Thanks to @nx111) cherry-pick >https://git.streamboard.tv/common/oscam/-/commit/178662a1c636579f24b4f6845962f4a5837d528d --- globals.h | 10 +- module-cccam.c | 3 +- module-webif.c | 18 ++ ncam-config-reader.c | 98 +++++++- reader-tongfang.c | 213 ++++++++++-------- webif/pages_index.txt | 1 + webif/readerconfig/readerconfig_hwreader.html | 1 + .../readerconfig_hwreader_tongfang.html | 8 +- 8 files changed, 253 insertions(+), 99 deletions(-) diff --git a/globals.h b/globals.h index e2c92edcd..7f8d0c564 100644 --- a/globals.h +++ b/globals.h @@ -1692,8 +1692,14 @@ struct s_reader CAIDTAB ctab; uint32_t boxid; #ifdef READER_TONGFANG - uint32_t tongfang3_calibsn; - uint8_t tongfang3_commkey[8]; + uint32_t tongfang_version; + uint8_t tongfang3_commkey[8]; + uint32_t tongfang3_calibsn; + uint32_t tongfang_boxid; + uint8_t tongfang3_deskey[8]; + uint8_t tongfang3_deskey_length; + uint8_t stbid[8]; + uint8_t stbid_length; #endif #ifdef READER_JET uint8_t jet_vendor_key[32]; diff --git a/module-cccam.c b/module-cccam.c index e801b431f..251e36239 100644 --- a/module-cccam.c +++ b/module-cccam.c @@ -1289,8 +1289,7 @@ int32_t get_UA_ofs(uint16_t caid) case 0x0D: // CRYPTOWORKS //ofs = 1; //break; - case 0x4A: // STREAMGUARD: - case 0x4B: // TONGFANG + case 0x4A: // TONGFANG case 0x09: // VIDEOGUARD case 0x0B: // CONAX case 0x18: // NAGRA diff --git a/module-webif.c b/module-webif.c index 6bdc2bb44..616692881 100644 --- a/module-webif.c +++ b/module-webif.c @@ -3128,6 +3128,24 @@ static char *send_ncam_reader_config(struct templatevars *vars, struct uriparams if(rdr->tongfang3_calibsn) { tpl_printf(vars, TPLADD, "TONGFANGCALIBSN", "%08X", rdr->tongfang3_calibsn); } + if(rdr->tongfang_boxid) + { tpl_printf(vars, TPLADD, "TONGFANGBOXID", "%08X", rdr->tongfang_boxid); } + + if(rdr->tongfang3_deskey_length > 0) + { + for(i = 0; i < rdr->tongfang3_deskey_length ; i++) + { + tpl_printf(vars, TPLAPPEND, "TONGFANGDESKEY", "%02X", rdr->tongfang3_deskey[i]); + } + } + + if(rdr->stbid_length > 0) + { + for(i = 0; i < rdr->stbid_length ; i++) + { + tpl_printf(vars, TPLAPPEND, "STBID", "%02X", rdr->stbid[i]); + } + } #endif #ifdef READER_JET for(i = 0; (size_t)i < sizeof(rdr->jet_authorize_id) && rdr->jet_authorize_id[i] == 0; i++); diff --git a/ncam-config-reader.c b/ncam-config-reader.c index 76819c280..04ba16aab 100644 --- a/ncam-config-reader.c +++ b/ncam-config-reader.c @@ -305,7 +305,7 @@ static void tongfang3_calibsn_fn(const char *token, char *value, void *setting, struct s_reader *rdr = setting; if(value) { - rdr->tongfang3_calibsn = cs_strlen(value) ? a2i(value, 4) : 0; + rdr->tongfang3_calibsn = strlen(value) ? a2i(value, 4) : 0; return; } if(rdr->tongfang3_calibsn) @@ -313,6 +313,96 @@ static void tongfang3_calibsn_fn(const char *token, char *value, void *setting, else if(cfg.http_full_cfg) { fprintf_conf(f, token, "\n"); } } + +static void tongfang_boxid_fn(const char *token, char *value, void *setting, FILE *f) +{ + struct s_reader *rdr = setting; + if(value) + { + rdr->tongfang_boxid = cs_strlen(value) ? a2i(value, 4) : 0; + return; + } + if(rdr->tongfang_boxid) + { fprintf_conf(f, token, "%08X\n", rdr->tongfang_boxid); } + else if(cfg.http_full_cfg) + { fprintf_conf(f, token, "\n"); } +} + +static void stbid_fn(const char *token, char *value, void *setting, FILE *f) +{ + struct s_reader *rdr = setting; + if(value) + { + int32_t len = cs_strlen(value); + if(len != 16) + { + rdr->stbid_length = 0; + memset(rdr->stbid, 0, 8); + } + else + { + if(key_atob_l(value, rdr->stbid, len)) + { + fprintf(stderr, "reader stbid parse error, %s=%s\n", token, value); + rdr->stbid_length = 0; + memset(rdr->stbid, 0, sizeof(rdr->stbid)); + } + else + { + rdr->stbid_length = len/2; + } + } + return; + } + int32_t len = rdr->stbid_length; + if(len > 0) + { + char tmp[len * 2 + 1]; + fprintf_conf(f, "stbid", "%s\n", cs_hexdump(0, rdr->stbid, len, tmp, sizeof(tmp))); + } + else if(cfg.http_full_cfg) + { + fprintf_conf(f, "stbid", "\n"); + } +} + +static void tongfang3_deskey_fn(const char *token, char *value, void *setting, FILE *f) +{ + struct s_reader *rdr = setting; + if(value) + { + int32_t len = cs_strlen(value); + if(len != 16) + { + rdr->tongfang3_deskey_length = 0; + memset(rdr->tongfang3_deskey, 0, 8); + } + else + { + if(key_atob_l(value, rdr->tongfang3_deskey, len)) + { + fprintf(stderr, "reader tongfang3_deskey parse error, %s=%s\n", token, value); + rdr->tongfang3_deskey_length = 0; + memset(rdr->tongfang3_deskey, 0, sizeof(rdr->tongfang3_deskey)); + } + else + { + rdr->tongfang3_deskey_length = len/2; + } + } + return; + } + int32_t len = rdr->tongfang3_deskey_length; + if(len > 0) + { + char tmp[len * 2 + 1]; + fprintf_conf(f, "tongfang3_deskey", "%s\n", cs_hexdump(0, rdr->tongfang3_deskey, len, tmp, sizeof(tmp))); + } + else if(cfg.http_full_cfg) + { + fprintf_conf(f, "tongfang3_deskey", "\n"); + } +} #endif static void rsakey_fn(const char *token, char *value, void *setting, FILE *f) @@ -1300,6 +1390,9 @@ static const struct config_list reader_opts[] = #endif #ifdef READER_TONGFANG DEF_OPT_FUNC("tongfang3_calibsn" , 0, tongfang3_calibsn_fn), + DEF_OPT_FUNC("tongfang_boxid" , 0, tongfang_boxid_fn), + DEF_OPT_FUNC("stbid" , 0, stbid_fn), + DEF_OPT_FUNC("tongfang3_deskey" , 0, tongfang3_deskey_fn), #endif #ifdef READER_JET DEF_OPT_FUNC("jet_authorize_id" , 0, jet_authorize_id_fn), @@ -1444,6 +1537,9 @@ static bool reader_check_setting(const struct config_list *UNUSED(clist), void * #if defined(READER_DRE) || defined(READER_DRECAS) "exec_cmd_file", #endif +#if defined(READER_TONGFANG) + "tongfang3_calibsn", "tongfang_boxid", "stbid", "tongfang3_deskey", +#endif #ifdef WITH_AZBOX "mode", #endif diff --git a/reader-tongfang.c b/reader-tongfang.c index 818fe3e63..0c5ca0b9f 100644 --- a/reader-tongfang.c +++ b/reader-tongfang.c @@ -4,20 +4,6 @@ #include "cscrypt/des.h" #include -static const uint32_t tongfang3_calibsn = 2991124752UL; //B248F110<=; - -//=======main functions=========== - -uint32_t tongfang3_get_true_calibsn(uint32_t value) -{ - size_t i; - uint32_t result = 0; - - for(i = 0; i < 8; i++) - result |= ((value >> (4 * i)) % 0x10) << (28 - 4 * i); - return result; -} - // returns 1 if cw_is_valid, returns 0 if cw is all zeros static int32_t cw_is_valid(uint8_t *cw) { @@ -35,7 +21,7 @@ static int32_t cw_is_valid(uint8_t *cw) static int32_t tongfang_read_data(struct s_reader *reader, uint8_t size, uint8_t *cta_res, uint16_t *status) { - uint8_t read_data_cmd[] = { 0x00, 0xc0, 0x00, 0x00, 0xff }; + uint8_t read_data_cmd[] = {0x00, 0xc0, 0x00, 0x00, 0xff}; uint16_t cta_lr; read_data_cmd[4] = size; @@ -48,23 +34,21 @@ static int32_t tongfang_read_data(struct s_reader *reader, uint8_t size, uint8_t static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) { - const uint8_t get_ppua_cmdv1[] = { 0x00, 0xa4, 0x04, 0x00, 0x05, 0xf9, 0x5a, 0x54, 0x00, 0x06 }; - const uint8_t get_ppua_cmdv3[] = { 0x80, 0x46, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x08 }; - uint8_t get_serial_cmdv1[] = { 0x80, 0x32, 0x00, 0x00, 0x58 }; - uint8_t get_serial_cmdv2[] = { 0x80, 0x46, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04 }; - uint8_t get_serial_cmdv3[] = { 0x80, 0x46, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x14 }; - uint8_t get_commkey_cmd[17] = { 0x80, 0x56, 0x00, 0x00, 0x0c }; - uint8_t confirm_commkey_cmd[21] = { 0x80, 0x4c, 0x00, 0x00, 0x10 }; - uint8_t pairing_cmd[200] = { 0x80, 0x4c, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF }; - - const uint8_t des_key[8] = { 0x24, 0x76, 0x92, 0xec, 0x7c, 0x02, 0xba, 0x30 }; + const uint8_t get_ppua_cmdv1[] = {0x00, 0xa4, 0x04, 0x00, 0x05, 0xf9, 0x5a, 0x54, 0x00, 0x06}; + const uint8_t get_ppua_cmdv3[] = {0x80, 0x46, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x08}; + uint8_t get_serial_cmdv1[] = {0x80, 0x32, 0x00, 0x00, 0x58}; + uint8_t get_serial_cmdv2[] = {0x80, 0x46, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04}; + uint8_t get_serial_cmdv3[] = {0x80, 0x46, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x14}; + uint8_t get_commkey_cmd[17] = {0x80, 0x56, 0x00, 0x00, 0x0c}; + uint8_t confirm_commkey_cmd[21] = {0x80, 0x4c, 0x00, 0x00, 0x10}; + uint8_t pairing_cmd[9] = {0x80, 0x4c, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t data[257]; uint8_t card_id[20]; uint16_t status = 0; - uint8_t boxID[] = { 0xFF, 0xFF, 0xFF, 0xFF }; - uint8_t stbid[8] = { 0x01, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00 }; + uint8_t boxID[] = {0xFF, 0xFF, 0xFF, 0xFF}; uint8_t zero[8] = {0}; + uint8_t deskey[8]; int32_t i; uint32_t calibsn = 0; int8_t readsize = 0; @@ -72,27 +56,27 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) get_atr; def_resp; - if(!(reader->cas_version & 0x010000)) + if(!(reader->tongfang_version & 0x010000)) { if(atr_size == 8 && atr[0] == 0x3B && atr[1] == 0x64) { - reader->cas_version = 1; + reader->tongfang_version = 1; } else if(atr_size > 9 && atr[0] == 0x3B && (atr[1] & 0xF0) == 0x60 && 0 == memcmp(atr + 4, "NTIC", 4)) { - reader->cas_version = atr[8] - 0x30 + 1; + reader->tongfang_version = atr[8] - 0x30 + 1; } else if((atr_size == ((uint32_t)(atr[1] & 0x0F) + 4)) && (atr[0] == 0x3B) && ((atr[1] & 0xF0) == 0x60) && (atr[2] == 0x00) && ((atr[3] & 0xF0) == 0x00)) { - reader->cas_version = 2; + reader->tongfang_version = 2; } else { - return ERROR; - } //not yxsb/yxtf + return ERROR; //not yxsb/yxtf + } } - uint32_t cas_version = reader->cas_version & 0x00FFFFL; + uint32_t cas_version = reader->tongfang_version & 0x00FFFFL; reader->caid = 0x4A02; reader->nprov = 1; @@ -100,25 +84,26 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) memset(card_id, 0, sizeof(card_id)); memset(reader->hexserial, 0, 8); - if(reader->boxid > 0) + if(reader->tongfang_boxid > 0) { for(i = 0; (size_t)i < sizeof(boxID); i++) { - boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100; + boxID[i] = (reader->tongfang_boxid >> (8 * (3 - i))) % 0x100; } } - if(cas_version <= 2) //tongfang 1-2 - { + if(cas_version <= 2) + { //tongfang 1-2 write_cmd(get_ppua_cmdv1, get_ppua_cmdv1 + 5); if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; } rdr_log(reader, "Tongfang %d card detected", cas_version); + //get card serial - if(atr[8] == 0x31) //degrade card from version 3 - { + if(atr[8] == 0x31) + { //degrade card from version 3 write_cmd(get_serial_cmdv2, get_serial_cmdv2 + 5); if((cta_res[cta_lr - 2] & 0xf0) != 0x60) { @@ -141,6 +126,12 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) rdr_log(reader, "error: get card serial failed."); return ERROR; } + readsize = cta_res[cta_lr - 1]; + if(readsize != tongfang_read_data(reader, readsize, data, &status) || status != 0x9000) + { + rdr_log(reader, "error: card get serial data failed."); + return ERROR; + } memcpy(reader->hexserial + 2, cta_res, 4); } @@ -148,18 +139,18 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) write_cmd(pairing_cmd, pairing_cmd + 5); if((cta_res[cta_lr - 2] == 0x94) && (cta_res[cta_lr - 1] == 0xB1)) { - rdr_log_dbg(reader, D_IFD, "the card needlessly pairing with any box."); + rdr_log_dbg(reader, D_READER, "the card needlessly pairing with any box."); } else if((cta_res[cta_lr - 2] == 0x94) && (cta_res[cta_lr - 1] == 0xB2)) { - if(reader->boxid > 0) + if(reader->tongfang_boxid > 0) { memcpy(pairing_cmd + 5, boxID, 4); write_cmd(pairing_cmd, pairing_cmd + 5); if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { - rdr_log(reader, "error: this card pairing failed with the box,please check your boxid setting."); + rdr_log(reader, "error: this card pairing failed with the box, please check your boxid setting."); //return ERROR; } } @@ -173,38 +164,54 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) { rdr_log(reader, "error: this card pairing failed with the box(return code:0x%02X%02X).", cta_res[cta_lr - 2], cta_res[cta_lr - 1]); } + } else if(cas_version == 3) - { //tongfang 3 + { //tongfang 3 write_cmd(get_ppua_cmdv3, get_ppua_cmdv3 + 5); if((cta_res[cta_lr - 2] & 0xf0) != 0x60) { return ERROR; } + readsize = cta_res[cta_lr - 1]; + if(readsize != tongfang_read_data(reader, readsize, data, &status)) + { + rdr_log(reader, "error: get ppua v3 failed."); + return ERROR; + } rdr_log(reader, "Tongfang3 card detected"); // get commkey - /* tongfang3_KeyBlockToKey(tongfang3_keyblock,des_key); */ + if(!reader->tongfang3_deskey_length) + { + rdr_log(reader, "error: tongfang3_deskey must be configured."); + return ERROR; + } + else + { + memcpy(deskey, reader->tongfang3_deskey, sizeof(reader->tongfang3_deskey)); + } memcpy(data, zero, sizeof(zero)); - des_ecb_encrypt(data, des_key, 8); + des_ecb_encrypt(data, deskey, 8); memcpy(get_commkey_cmd + 5, data, 8); - if(reader->tongfang3_calibsn) + if(reader->tongfang3_calibsn > 0) { calibsn = reader->tongfang3_calibsn; } else { - calibsn = tongfang3_get_true_calibsn(tongfang3_calibsn); + rdr_log(reader, "error: tongfang3_calibsn must be configured."); + return ERROR; } get_commkey_cmd[5 + 8] = (calibsn >> 24) & 0xFF; get_commkey_cmd[5 + 8 + 1] = (calibsn >> 16) & 0xFF; get_commkey_cmd[5 + 8 + 2] = (calibsn >> 8) & 0xFF; - get_commkey_cmd[5 + 8 + 3] = (calibsn)&0xFF; + get_commkey_cmd[5 + 8 + 3] = (calibsn) & 0xFF; write_cmd(get_commkey_cmd, get_commkey_cmd + 5); if((cta_res[cta_lr - 2] & 0xf0) != 0x60) { - rdr_log(reader, "error: get card commkey failed."); + rdr_log(reader,"error: get card commkey failed."); return ERROR; } readsize = cta_res[cta_lr - 1]; @@ -215,9 +222,9 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) } //rdr_log(reader, "card seed got."); memcpy(reader->tongfang3_commkey, data, 8); - des_ecb_encrypt(reader->tongfang3_commkey, des_key, 8); + des_ecb_encrypt(reader->tongfang3_commkey, deskey, 8); - rdr_log_dbg(reader, D_IFD, "card commkey got(%llX)", (unsigned long long)b2ll(8, reader->tongfang3_commkey)); + rdr_log_dbg(reader, D_READER, "card commkey got(%llX)",(unsigned long long)b2ll(8,reader->tongfang3_commkey)); //get card serial write_cmd(get_serial_cmdv3, get_serial_cmdv3 + 5); @@ -241,10 +248,10 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) card_id[sizeof(card_id) - 1] = '\0'; //confirm commkey and pairing - memcpy(data, stbid, sizeof(stbid)); + memcpy(data, reader->stbid, sizeof(reader->stbid)); des_ecb_encrypt(data, reader->tongfang3_commkey, 8); - if(reader->boxid > 0) + if(reader->tongfang_boxid > 0) { memcpy(zero + 2, boxID, 4); } @@ -254,35 +261,48 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) memcpy(confirm_commkey_cmd + 5, data, 16); write_cmd(confirm_commkey_cmd, confirm_commkey_cmd + 5); - if(cta_res[cta_lr - 2] == 0x90 && cta_res[cta_lr - 2] == 0x00) - { - rdr_log_dbg(reader, D_IFD, "the card is not pairing with any box,continue..."); - } - else + if((cta_res[cta_lr - 2] & 0xf0) == 0x60) { readsize = cta_res[cta_lr - 1]; - if(readsize != tongfang_read_data(reader, readsize, data, &status) || status != 0x9000) + if(readsize != tongfang_read_data(reader, readsize, data, &status)) { rdr_log(reader, "error: confirm commkey failed(read response data failed)."); - //return ERROR; } if(data[0] == 0x90 && data[1] == 0x00) { - rdr_log_dbg(reader, D_IFD, "the card pairing with any box succeed."); + rdr_log_dbg(reader, D_READER, "the card pairing with any box succeed."); } else if(data[0] == 0x94 && data[1] == 0xB1) { - rdr_log_dbg(reader, D_IFD, "the card needlessly pairing with any box"); + rdr_log_dbg(reader, D_READER, "the card needlessly pairing with any box"); } - else if(data[0] == 0x94 && data[1] == 0xB2) + else if (data[0] == 0x94 && data[1] == 0xB2) { - write_cmd(pairing_cmd, pairing_cmd + 5); - if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) - { - rdr_log(reader, "warning: the card pairing with some box."); - //return ERROR; - } + rdr_log(reader, "error: this card pairing failed with the box, please check your boxid setting."); + } + } + else + { + if(cta_res[cta_lr - 2] == 0x90 && cta_res[cta_lr - 1] == 0x00) + { + rdr_log_dbg(reader, D_READER, "the card pairing with any box succeed."); + } + else if(cta_res[cta_lr - 2] == 0x94 && cta_res[cta_lr - 1] == 0xB1) + { + rdr_log_dbg(reader, D_READER, "the card needlessly pairing with any box"); + } + else if(cta_res[cta_lr - 2] == 0x94 && cta_res[cta_lr - 1] == 0xB2) + { + rdr_log(reader, "error: this card pairing failed with the box, please check your boxid setting."); + } + else if(cta_res[cta_lr - 2] == 0x94 && cta_res[cta_lr - 1] == 0xB4) + { + rdr_log(reader, "error: this card initializing failed, please check your deskey setting, calibsn setting, and verify that stbid starts with 0000 or 0100."); + } + else + { + rdr_log(reader, "error: confirm commkey failed(return code:0x%02X%02X).", cta_res[cta_lr - 2], cta_res[cta_lr - 1]); } } } @@ -292,11 +312,7 @@ static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr) return ERROR; } - rdr_log_sensitive(reader, "type: Tongfang, caid: %04X, serial: {%llu}, hex serial: {%llX}, Card ID: {%s}, BoxID: {%08X}", - reader->caid, - (unsigned long long)b2ll(6, reader->hexserial), - (unsigned long long)b2ll(4, reader->hexserial + 2), - card_id, b2i(4, boxID)); + rdr_log_sensitive(reader, "type: Tongfang, caid: %04X, serial: {%llu}, hex serial: {%llX}, Card ID: {%s}, BoxID: {%08X}", reader->caid, (unsigned long long) b2ll(6, reader->hexserial), (unsigned long long) b2ll(4, reader->hexserial + 2), card_id, b2i(4, boxID)); return OK; } @@ -321,7 +337,7 @@ D9 3C EE 51 CD 6E 70 A2 EC 71 FF 0F D6 E8 52 D6 */ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea) { - uint8_t ecm_buf[512]; //{ 0x80,0x3a,0x00,0x01,0x53 }; + uint8_t ecm_buf[512]; //{0x80,0x3a,0x00,0x01,0x53}; uint8_t *ecm_cmd = ecm_buf; int32_t ecm_len = 0; uint8_t data[256] = {0}; @@ -331,9 +347,11 @@ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, s size_t read_size = 0; size_t data_len = 0; uint16_t status = 0; - uint32_t cas_version = reader->cas_version & 0x00FFFFL; + + uint32_t cas_version = reader->tongfang_version & 0x00FFFFL; def_resp; + if(cs_malloc(&tmp, er->ecmlen * 3 + 1)) { rdr_log_dbg(reader, D_IFD, "ECM: %s", cs_hexdump(1, er->ecm, er->ecmlen, tmp, er->ecmlen * 3 + 1)); @@ -342,14 +360,13 @@ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, s if((ecm_len = check_sct_len(er->ecm, 3, sizeof(er->ecm))) < 0) { - rdr_log(reader, "error: check_sct_len failed, smartcard section too long %d > %zd", - SCT_LEN(er->ecm), sizeof(er->ecm) - 3); + rdr_log(reader, "error: check_sct_len failed, smartcard section too long %d > %zd", SCT_LEN(er->ecm), sizeof(er->ecm) - 3); return ERROR; } for(i = 0; i < ecm_len; i++) { - if((i < ecm_len - 1) && (er->ecm[i] == 0x80) && (er->ecm[i + 1] == 0x3a) && (er->ecm[i + 2] == er->ecm[5]) && (er->ecm[i + 3] == er->ecm[6])) + if ((i < (ecm_len - 1)) && (er->ecm[i] == 0x80) && (er->ecm[i + 1] == 0x3a) && (er->ecm[i + 2] == er->ecm[5]) && (er->ecm[i + 3] == er->ecm[6])) { break; } @@ -363,7 +380,7 @@ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, s write_len = er->ecm[i + 4] + 5; if(write_len > (sizeof(ecm_buf))) { - if(write_len > MAX_ECM_SIZE || !cs_malloc(&ecm_cmd, write_len)) + if(write_len > MAX_ECM_SIZE || !cs_malloc(&ecm_cmd,write_len)) { rdr_log(reader, "error: ecm data too long,longer than sizeof ecm_buf(%zd > %zd).", write_len, sizeof(ecm_cmd)); return ERROR; @@ -385,8 +402,7 @@ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, s else { char ecm_cmd_string[150]; - rdr_log(reader, "error: card send parsing ecm command failed!(%s)", - cs_hexdump(1, ecm_cmd, write_len, ecm_cmd_string, sizeof(ecm_cmd_string))); + rdr_log(reader, "error: card send parsing ecm command failed!(%s)", cs_hexdump(1, ecm_cmd, write_len, ecm_cmd_string, sizeof(ecm_cmd_string))); if(ecm_cmd != ecm_buf) { NULLFREE(ecm_cmd); @@ -410,8 +426,7 @@ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, s if(data_len < 23) { char ecm_string[256 * 3 + 1]; - rdr_log(reader, "error: card return cw data failed,return data len=%zd(ECM:%s).", data_len, - cs_hexdump(1, er->ecm, er->ecmlen, ecm_string, sizeof(ecm_string))); + rdr_log(reader, "error: card return cw data failed, return data len=%zd(ECM:%s).", data_len, cs_hexdump(1, er->ecm, er->ecmlen, ecm_string, sizeof(ecm_string))); return ERROR; } @@ -428,11 +443,11 @@ static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, s // All zeroes is no valid CW, can be a result of wrong boxid if(!cw_is_valid(ea->cw) || !cw_is_valid(ea->cw + 8)) { - rdr_log(reader, "error: cw is invalid."); + rdr_log(reader,"error: cw is invalid."); return ERROR; } - if(cas_version >= 3) + if(cas_version == 3) { des_ecb_encrypt(ea->cw, reader->tongfang3_commkey, 8); des_ecb_encrypt(ea->cw + 8, reader->tongfang3_commkey, 8); @@ -468,9 +483,9 @@ static int32_t tongfang_do_emm(struct s_reader *reader, EMM_PACKET *ep) static int32_t tongfang_card_info(struct s_reader *reader) { - static const uint8_t get_provider_cmd[] = { 0x80, 0x44, 0x00, 0x00, 0x08 }; - uint8_t get_subscription_cmd[] = { 0x80, 0x48, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x13 }; - static const uint8_t get_agegrade_cmd[] = { 0x80, 0x46, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x09 }; + static const uint8_t get_provider_cmd[] = {0x80, 0x44, 0x00, 0x00, 0x08}; + uint8_t get_subscription_cmd[] = {0x80, 0x48, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x13}; + static const uint8_t get_agegrade_cmd[] = {0x80, 0x46, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x09}; def_resp; int32_t i; uint8_t data[256]; @@ -493,7 +508,7 @@ static int32_t tongfang_card_info(struct s_reader *reader) int found = 0; for(j = 0; j < reader->nprov; j++) { - if(reader->nprov > 0 && reader->prid[j][2] == cta_res[i * 2] && reader->prid[j][3] == cta_res[i * 2 + 1]) + if(reader->nprov > 0 && reader->prid[j][2] == cta_res[i * 2] && reader->prid[j][3] == cta_res[i *2 + 1]) { found = 1; break; @@ -501,23 +516,31 @@ static int32_t tongfang_card_info(struct s_reader *reader) } if(found == 1) + { continue; + } + memcpy(&reader->prid[reader->nprov][2], cta_res + i * 2, 2); rdr_log(reader, "Provider:%06X", b2i(2, cta_res + i * 2)); - reader->nprov++; + reader->nprov ++; } } cs_clear_entitlement(reader); + for(i = 0; i < reader->nprov; i++) { get_subscription_cmd[2] = reader->prid[i][2]; get_subscription_cmd[3] = reader->prid[i][3]; write_cmd(get_subscription_cmd, get_subscription_cmd + 5); if((cta_res[cta_lr - 2] & 0xF0) != 0x60) + { continue; + } if((3 > tongfang_read_data(reader, cta_res[cta_lr - 1], data, &status)) || (status != 0x9000)) + { continue; + } uint16_t count = data[2]; int j; @@ -540,12 +563,16 @@ static int32_t tongfang_card_info(struct s_reader *reader) strftime(end_day, sizeof(end_day), "%Y/%m/%d", &tm_end); if(!j) + { rdr_log(reader, "entitlements for provider: %d (%04X:%06X)", i, reader->caid, b2i(2, &reader->prid[i][2])); - rdr_log(reader, " chid: %04" PRIX64 " date: %s - %s", product_id, start_day, end_day); + } + + rdr_log(reader, " chid: %04"PRIX64" date: %s - %s", product_id, start_day, end_day); cs_add_entitlement(reader, reader->caid, b2i(2, &reader->prid[i][2]), product_id, 0, start_t, end_t, 0, 1); } } + write_cmd(get_agegrade_cmd, get_agegrade_cmd + 5); if((cta_res[cta_lr - 2] & 0xF0) != 0x60) { diff --git a/webif/pages_index.txt b/webif/pages_index.txt index 46a721244..19433badd 100644 --- a/webif/pages_index.txt +++ b/webif/pages_index.txt @@ -234,6 +234,7 @@ READERCONFIGVIACCESS readerconfig/readerconfig_hwreader_viaccess.html READERCONFIGDRE readerconfig/readerconfig_hwreader_dre.html READER_DRE READERCONFIGBOXID readerconfig/readerconfig_hwreader_boxid.html READER_VIDEOGUARD,READER_STREAMGUARD,READER_TONGFANG READERCONFIGVIDEOGUARD readerconfig/readerconfig_hwreader_videoguard.html READER_VIDEOGUARD +READERCONFIGTONGFANG readerconfig/readerconfig_hwreader_tongfang.html READER_TONGFANG READERCONFIGCASVERSION readerconfig/readerconfig_hwreader_casversion.html READER_JET,READER_STREAMGUARD,READER_TONGFANG READERCONFIGTONGFANG readerconfig/readerconfig_hwreader_tongfang.html READER_TONGFANG READERCONFIGJET readerconfig/readerconfig_hwreader_jet.html READER_JET diff --git a/webif/readerconfig/readerconfig_hwreader.html b/webif/readerconfig/readerconfig_hwreader.html index b63b123d7..d1f32e503 100644 --- a/webif/readerconfig/readerconfig_hwreader.html +++ b/webif/readerconfig/readerconfig_hwreader.html @@ -27,6 +27,7 @@ ##TPLREADERCONFIGVIACCESS## ##TPLREADERCONFIGDRE## ##TPLREADERCONFIGVIDEOGUARD## +##TPLREADERCONFIGTONGFANG## ##TPLREADERCONFIGCASVERSION## ##TPLREADERCONFIGTONGFANG## ##TPLREADERCONFIGJET## diff --git a/webif/readerconfig/readerconfig_hwreader_tongfang.html b/webif/readerconfig/readerconfig_hwreader_tongfang.html index 77eeae91a..2f978c8dd 100644 --- a/webif/readerconfig/readerconfig_hwreader_tongfang.html +++ b/webif/readerconfig/readerconfig_hwreader_tongfang.html @@ -1,2 +1,8 @@ Reader specific settings for TongFang - CalibSN for TONGFANG v3: + + DES Key for TONGFANG v3: + CalibSN for TONGFANG v3: + + STB ID for TONGFANG v3: + Box ID for TONGFANG: +