From 98dd35342fb1315ae260bc2c4043825d7d1feb48 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 10 Apr 2012 15:48:07 +0200 Subject: [PATCH] cwc: Use "per stream" update id for Cryptoworks and Viaccess CA composed emms This fixes possible shared EMM messages composing issues when multiple streams are sending EMMs to the card reader. Just make sure, that both parts of compose messages are from one "stream". Signed-off-by: Jaroslav Kysela --- src/cwc.c | 23 ++++++++++++++--------- src/cwc.h | 2 +- src/dvb/dvb_tables.c | 11 ++++++----- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/cwc.c b/src/cwc.c index a90c1f3a..e2442ea8 100644 --- a/src/cwc.c +++ b/src/cwc.c @@ -243,6 +243,7 @@ typedef struct cwc { int shared_toggle; int shared_len; uint8_t * shared_emm; + void *ca_update_id; } cwc_viaccess_emm; #define cwc_cryptoworks_emm cwc_viaccess_emm @@ -279,10 +280,10 @@ void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_dre(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len); -void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len); +void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len, void *ca_update_id); void cwc_emm_nagra(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len); -void cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len); +void cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len, void *ca_update_id); /** @@ -1188,7 +1189,7 @@ cwc_emm_cache_lookup(cwc_t *cwc, uint32_t crc) * */ void -cwc_emm(uint8_t *data, int len, uint16_t caid) +cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id) { cwc_t *cwc; @@ -1208,7 +1209,7 @@ cwc_emm(uint8_t *data, int len, uint16_t caid) cwc_emm_seca(cwc, data, len); break; case CARD_VIACCESS: - cwc_emm_viaccess(cwc, data, len); + cwc_emm_viaccess(cwc, data, len, ca_update_id); break; case CARD_DRE: cwc_emm_dre(cwc, data, len); @@ -1220,7 +1221,7 @@ cwc_emm(uint8_t *data, int len, uint16_t caid) cwc_emm_nds(cwc, data, len); break; case CARD_CRYPTOWORKS: - cwc_emm_cryptoworks(cwc, data, len); + cwc_emm_cryptoworks(cwc, data, len, ca_update_id); break; case CARD_UNKNOWN: break; @@ -1382,7 +1383,7 @@ static int via_provider_id(uint8_t * data) void -cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen) +cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen, void *ca_update_id) { /* Get SCT len */ int len = 3 + ((data[1] & 0x0f) << 8) + data[2]; @@ -1414,13 +1415,15 @@ cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen) if (cwc->cwc_viaccess_emm.shared_emm) { cwc->cwc_viaccess_emm.shared_len = len; memcpy(cwc->cwc_viaccess_emm.shared_emm, data, len); + cwc->cwc_viaccess_emm.ca_update_id = ca_update_id; } cwc->cwc_viaccess_emm.shared_toggle = data[0]; } } break; case 0x8e: - if (cwc->cwc_viaccess_emm.shared_emm) { + if (cwc->cwc_viaccess_emm.shared_emm && + cwc->cwc_viaccess_emm.ca_update_id == ca_update_id) { int match = 0; int i; /* Match SA and provider in shared */ @@ -1667,7 +1670,7 @@ cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len) } void -cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len) +cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len, void *ca_update_id) { int match = 0; @@ -1686,11 +1689,13 @@ cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len) if (cwc->cwc_cryptoworks_emm.shared_emm) { cwc->cwc_cryptoworks_emm.shared_len = len; memcpy(cwc->cwc_cryptoworks_emm.shared_emm, data, len); + cwc->cwc_cryptoworks_emm.ca_update_id = ca_update_id; } } break; case 0x86: /* emm-sb */ - if (cwc->cwc_cryptoworks_emm.shared_emm) { + if (cwc->cwc_cryptoworks_emm.shared_emm && + cwc->cwc_cryptoworks_emm.ca_update_id == ca_update_id) { /* python: EMM_SH[0:12] + EMM_SB[5:-1] + EMM_SH[12:-1] */ uint32_t elen = len - 5 + cwc->cwc_cryptoworks_emm.shared_len - 12; uint8_t *tmp = malloc(elen); diff --git a/src/cwc.h b/src/cwc.h index da2381bf..3c28710a 100644 --- a/src/cwc.h +++ b/src/cwc.h @@ -23,6 +23,6 @@ void cwc_init(void); void cwc_service_start(struct service *t); -void cwc_emm(uint8_t *data, int len, uint16_t caid); +void cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id); #endif /* CWC_H_ */ diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index efcd5024..f2e83653 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -44,7 +44,7 @@ #define TDT_CRC 0x1 #define TDT_QUICKREQ 0x2 -#define TDT_INC_TABLE_HDR 0x4 +#define TDT_CA 0x4 static void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid); @@ -214,8 +214,9 @@ dvb_proc_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt, uint8_t *sec, ptr = &sec[3]; if(chkcrc) len -= 4; /* Strip trailing CRC */ - if(tdt->tdt_flags & TDT_INC_TABLE_HDR) - ret = tdt->tdt_callback(tdmi, sec, len + 3, tableid, tdt->tdt_opaque); + if(tdt->tdt_flags & TDT_CA) + ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt, + sec, len + 3, tableid, tdt->tdt_opaque); else ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt->tdt_opaque); @@ -828,7 +829,7 @@ static int dvb_ca_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque) { - cwc_emm(ptr, len, (uintptr_t)opaque); + cwc_emm(ptr, len, (uintptr_t)opaque, (void *)tdmi); return 0; } @@ -864,7 +865,7 @@ dvb_cat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, break; tdt_add(tdmi, NULL, dvb_ca_callback, (void *)caid, "CA", - TDT_INC_TABLE_HDR, pid, NULL); + TDT_CA, pid, NULL); break; default: