]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
descrambler: support ICAM if detected in libdvbcsa
authorPim Zandbergen <pim@zandbergen.org>
Mon, 1 Jan 2024 19:36:04 +0000 (20:36 +0100)
committerFlole998 <Flole998@users.noreply.github.com>
Thu, 4 Jan 2024 23:41:39 +0000 (00:41 +0100)
src/descrambler/caid.h
src/descrambler/descrambler.c
src/descrambler/tvhcsa.c
src/descrambler/tvhcsa.h

index 109204f3dd09b462dd985355b00a637046faaa04..726999d74a781cee31d2da93128da51412ab74f1 100644 (file)
@@ -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; }
index 71cc9ebd6a60794bb5517c6afa8c4a03fd14caf9..b169929a95d51494a81889357aa49a7c83a53191 100644 (file)
@@ -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\"",
index 942ce92b5cdd25b4506576e77570f1b99d993784..0cd57c2920d4944937102fb4c156fdc9862d09d9 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <assert.h>
+#include <dlfcn.h>
 
 #include "tvhcsa.h"
 #include "input.h"
 #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
index 855de5acc2b40ae04c29591fc2571603fc5899f9..17020f9fe22bda42cd5c2e2ff240b148742670c6 100644 (file)
@@ -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__ */