From: Pim Zandbergen Date: Mon, 1 Jan 2024 19:36:04 +0000 (+0100) Subject: descrambler: support ICAM if detected in libdvbcsa X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=899b38ae5b960688b600be3e77526d92cecea536;p=thirdparty%2Ftvheadend.git descrambler: support ICAM if detected in libdvbcsa --- diff --git a/src/descrambler/caid.h b/src/descrambler/caid.h index 109204f3d..726999d74 100644 --- a/src/descrambler/caid.h +++ b/src/descrambler/caid.h @@ -46,6 +46,7 @@ uint16_t name2caid(const char *str); card_type_t detect_card_type(const uint16_t caid); static inline int caid_is_irdeto(uint16_t caid) { return (caid >> 8) == 0x06; } +static inline int caid_is_videoguard(uint16_t caid) { return (caid >> 8) == 0x09; } static inline int caid_is_powervu(uint16_t caid) { return (caid >> 8) == 0x0e; } static inline int caid_is_betacrypt(uint16_t caid) { return (caid >> 8) == 0x17; } static inline int caid_is_dvn(uint16_t caid) { return caid == 0x4a30; } diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 71cc9ebd6..b169929a9 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -1301,6 +1301,8 @@ descrambler_table_callback int64_t clk, clk2, clk3; uint8_t ki; int i, j; + caid_t *ca; + elementary_stream_t *st; if (len < 6) return 0; @@ -1362,13 +1364,20 @@ descrambler_table_callback if (dr->dr_ecm_parity == ECM_PARITY_81EVEN_80ODD) j ^= 1; dr->dr_ecm_start[j] = clk; - if (dr->dr_quick_ecm) { - ki = 1 << (j + 6); /* 0x40 = even, 0x80 = odd */ - for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { - tk = &dr->dr_keys[i]; + ki = 1 << (j + 6); /* 0x40 = even, 0x80 = odd */ + for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { + tk = &dr->dr_keys[i]; + if (dr->dr_quick_ecm) tk->key_valid &= ~ki; - if (tk->key_pid == 0) break; + TAILQ_FOREACH(st, &mt->mt_service->s_components.set_filter, es_filter_link) { + if (st->es_pid != mt->mt_pid) continue; + LIST_FOREACH(ca, &st->es_caids, link) { + if (ca->use == 0) continue; + tk->key_csa.csa_ecm = (caid_is_videoguard(ca->caid) && (ptr[2] - ptr[4]) == 4) ? ptr[21] : 0; + tvhtrace(LS_DESCRAMBLER, "key ecm=%X (caid=%04X)", tk->key_csa.csa_ecm, ca->caid); + } } + if (tk->key_pid == 0) break; } } tvhtrace(LS_DESCRAMBLER, "ECM message %02x:%02x (section %d, len %d, pid %d) for service \"%s\"", diff --git a/src/descrambler/tvhcsa.c b/src/descrambler/tvhcsa.c index 942ce92b5..0cd57c292 100644 --- a/src/descrambler/tvhcsa.c +++ b/src/descrambler/tvhcsa.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "tvhcsa.h" #include "input.h" @@ -29,6 +30,10 @@ #include "descrambler/algo/libaes128dec.h" #include "descrambler/algo/libdesdec.h" +#if ENABLE_DVBCSA +static int dvbcsa_dl_loaded; +static dvbcsa_dl_bs_key_set_type dvbcsa_dl_bs_key_set_ecm; +#endif static void tvhcsa_empty_flush @@ -225,7 +230,7 @@ void tvhcsa_set_key_even( tvhcsa_t *csa, const uint8_t *even ) switch (csa->csa_type) { case DESCRAMBLER_CSA_CBC: #if ENABLE_DVBCSA - dvbcsa_bs_key_set(even, csa->csa_key_even); + dvbcsa_bs_key_set_wrap(csa->csa_ecm, even, csa->csa_key_even); #endif break; case DESCRAMBLER_DES_NCB: @@ -247,7 +252,7 @@ void tvhcsa_set_key_odd( tvhcsa_t *csa, const uint8_t *odd ) switch (csa->csa_type) { case DESCRAMBLER_CSA_CBC: #if ENABLE_DVBCSA - dvbcsa_bs_key_set(odd, csa->csa_key_odd); + dvbcsa_bs_key_set_wrap(csa->csa_ecm, odd, csa->csa_key_odd); #endif break; case DESCRAMBLER_DES_NCB: @@ -267,6 +272,31 @@ void tvhcsa_set_key_odd( tvhcsa_t *csa, const uint8_t *odd ) void tvhcsa_init ( tvhcsa_t *csa ) { +#if ENABLE_DVBCSA + void *dvbcsa_dlh; + + if (!dvbcsa_dl_loaded) + { + dvbcsa_dl_loaded++; + dvbcsa_dlh = dlopen(NULL, RTLD_LAZY); + if (dvbcsa_dlh) + { + dvbcsa_dl_bs_key_set_ecm = (dvbcsa_dl_bs_key_set_type) dlsym(dvbcsa_dlh, "dvbcsa_bs_key_set_ecm"); + if (dvbcsa_dl_bs_key_set_ecm) + tvhinfo(LS_DESCRAMBLER, "dvbcsa_bs_key_set_ecm() function detected in libdvbcsa"); + else + { + dlclose(dvbcsa_dlh); + tvhinfo(LS_DESCRAMBLER, "dvbcsa_bs_key_set_ecm() function not detected in libdvbcsa"); + } + } + else + { + dvbcsa_dl_bs_key_set_ecm = NULL; + tvhwarn(LS_DESCRAMBLER, "could not dlopen libdvbcsa"); + } + } +#endif csa->csa_type = 0; csa->csa_keylen = 0; } @@ -305,3 +335,14 @@ tvhcsa_destroy ( tvhcsa_t *csa ) } memset(csa, 0, sizeof(*csa)); } + +#if ENABLE_DVBCSA +void +dvbcsa_bs_key_set_wrap(const unsigned char ecm, const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key) +{ + if (dvbcsa_dl_bs_key_set_ecm) + dvbcsa_dl_bs_key_set_ecm(ecm, cw, key); + else + dvbcsa_bs_key_set(cw, key); +} +#endif diff --git a/src/descrambler/tvhcsa.h b/src/descrambler/tvhcsa.h index 855de5acc..17020f9fe 100644 --- a/src/descrambler/tvhcsa.h +++ b/src/descrambler/tvhcsa.h @@ -47,6 +47,7 @@ typedef struct tvhcsa uint8_t *csa_tsbcluster; int csa_fill; int csa_fill_size; + uint8_t csa_ecm; #if ENABLE_DVBCSA struct dvbcsa_bs_batch_s *csa_tsbbatch_even; @@ -84,4 +85,9 @@ static inline void tvhcsa_destroy ( tvhcsa_t *csa ) { }; #endif +#if ENABLE_DVBCSA +typedef void* (*dvbcsa_dl_bs_key_set_type)(const unsigned char ecm, const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key); +void dvbcsa_bs_key_set_wrap(const unsigned char ecm, const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key); +#endif + #endif /* __TVH_CSA_H__ */