From: Jaroslav Kysela Date: Tue, 13 Jun 2017 06:28:21 +0000 (+0200) Subject: descrambler: allow to overwrite the key type (bug in o*c*m) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=44f3beca44508538144a6cc6909c2d444c8fbca3;p=thirdparty%2Ftvheadend.git descrambler: allow to overwrite the key type (bug in o*c*m) --- diff --git a/src/descrambler.h b/src/descrambler.h index d38d18b85..e45d7f268 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -80,7 +80,7 @@ typedef struct th_descrambler_key { int64_t key_timestamp[2]; uint8_t key_index; uint8_t key_valid; - uint8_t key_changed; + uint8_t key_type_overwritten; tvhlog_limit_t key_loglimit; } th_descrambler_key_t; @@ -174,6 +174,7 @@ void descrambler_init ( void ); void descrambler_done ( void ); void descrambler_change_keystate ( th_descrambler_t *t, th_descrambler_keystate_t state, int lock ); const char *descrambler_keystate2str( th_descrambler_keystate_t keystate ); +const char *descrambler_keytype2str( th_descrambler_keystate_t keytype ); void descrambler_service_start ( struct service *t ); void descrambler_service_stop ( struct service *t ); void descrambler_caid_changed ( struct service *t ); diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 767371535..1aa1bbb17 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -44,6 +44,7 @@ typedef struct th_descrambler_data { int64_t dd_timestamp; sbuf_t dd_sbuf; th_descrambler_key_t *dd_key; + uint8_t dd_key_changed; } th_descrambler_data_t; typedef struct th_descrambler_hint { @@ -136,13 +137,14 @@ descrambler_data_append(th_descrambler_runtime_t *dr, const uint8_t *tsb, int le } static void -descrambler_data_add_key(th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, int head) +descrambler_data_add_key(th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, int change, int head) { th_descrambler_data_t *dd; dd = calloc(1, sizeof(*dd)); dd->dd_timestamp = mclk(); dd->dd_key = tk; + dd->dd_key_changed = change; debug2("%p: data %s key %d, timestamp %ld", dr, head ? "insert" : "append", tk->key_pid, dd->dd_timestamp); if (head) TAILQ_INSERT_HEAD(&dr->dr_queue, dd, dd_link); @@ -619,6 +621,19 @@ descrambler_change_keystate( th_descrambler_t *td, th_descrambler_keystate_t key pthread_mutex_unlock(&t->s_stream_mutex); } +static struct strtab keytypetab[] = { + { "CSA", DESCRAMBLER_CSA_CBC }, + { "DES", DESCRAMBLER_DES_NCB }, + { "AES EBC", DESCRAMBLER_AES_ECB }, + { "AES128 EBC", DESCRAMBLER_AES128_ECB }, +}; + +const char * +descrambler_keytype2str( th_descrambler_keystate_t keytype ) +{ + return val2str(keytype, keytypetab) ?: "INVALID"; +} + void descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, const uint8_t *even, const uint8_t *odd ) @@ -631,7 +646,7 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, char pidname[16]; const char *ktype; uint16_t pid2; - int j = 0, insert = 0; + int j, changed = 0, insert = 0; if (t == NULL || (dr = t->s_descramble) == NULL) { descrambler_change_keystate(td, DS_FORBIDDEN, 1); @@ -654,8 +669,26 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, goto fin; } - if (tvhcsa_set_type(&tk->key_csa, type) < 0) - goto fin; + if (pid == 0) + pidname[0] = '\0'; + else + snprintf(pidname, sizeof(pidname), "[%d]", pid); + ktype = descrambler_keytype2str(type); + + if (tvhcsa_set_type(&tk->key_csa, type) < 0) { + if (tk->key_type_overwritten) + goto fin; + tk->key_type_overwritten = 1; + tvhwarn(LS_DESCRAMBLER, + "Overwrite key%s type from %s to %s for service \"%s\"", + pidname, descrambler_keytype2str(tk->key_csa.csa_type), + ktype, ((mpegts_service_t *)t)->s_dvb_svcname); + tvhcsa_destroy(&tk->key_csa); + tvhcsa_init(&tk->key_csa); + if (tvhcsa_set_type(&tk->key_csa, type) < 0) + goto fin; + tk->key_valid = 0; + } LIST_FOREACH(td2, &t->s_descramblers, td_service_link) if (td2 != td && td2->td_keystate == DS_RESOLVED) { @@ -672,24 +705,10 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, goto fin; } - if (pid == 0) - pidname[0] = '\0'; - else - snprintf(pidname, sizeof(pidname), "[%d]", pid); - switch(type) { - case DESCRAMBLER_CSA_CBC: ktype = "CSA"; break; - case DESCRAMBLER_DES_NCB: ktype = "DES"; break; - case DESCRAMBLER_AES_ECB: ktype = "AES EBC"; break; - case DESCRAMBLER_AES128_ECB: ktype = "AES128 EBC"; break; - default: abort(); - } - if (even && memcmp(empty, even, tk->key_csa.csa_keylen)) { - j++; memcpy(tk->key_data[0], even, tk->key_csa.csa_keylen); tk->key_pid = pid; - tk->key_changed |= 1; - tk->key_valid |= 0x40; + changed |= 1; if (tk->key_timestamp[0] == 0) insert |= 1; tk->key_timestamp[0] = mclk(); if (dr->dr_ecm_start[0] < dr->dr_ecm_start[1]) { @@ -705,8 +724,7 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, j++; memcpy(tk->key_data[1], odd, tk->key_csa.csa_keylen); tk->key_pid = pid; - tk->key_changed |= 2; - tk->key_valid |= 0x80; + changed |= 2; if (tk->key_timestamp[1] == 0) insert |= 2; tk->key_timestamp[1] = mclk(); if (dr->dr_ecm_start[1] < dr->dr_ecm_start[0]) { @@ -719,8 +737,8 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, odd = empty; } - if (j) { - descrambler_data_add_key(dr, tk, insert); + if (changed) { + descrambler_data_add_key(dr, tk, changed, insert); if (td->td_keystate != DS_RESOLVED) tvhdebug(LS_DESCRAMBLER, "Obtained %s keys%s from %s for service \"%s\"%s", @@ -902,21 +920,22 @@ key_started( th_descrambler_runtime_t *dr, uint8_t ki ) } static void -key_flush( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, service_t *t ) +key_flush( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t changed, service_t *t ) { - if (tk->key_changed) { - debug2("%p: key[%d] flush", dr, tk->key_pid); - tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t *)t); - /* update the keys */ - if (tk->key_changed & 1) { - debug2("%p: even key[%d] set for decoder", dr, tk->key_pid); - tvhcsa_set_key_even(&tk->key_csa, tk->key_data[0]); - } - if (tk->key_changed & 2) { - debug2("%p: odd key[%d] set for decoder", dr, tk->key_pid); - tvhcsa_set_key_odd(&tk->key_csa, tk->key_data[1]); - } - tk->key_changed = 0; + if (!changed) + return; + debug2("%p: key[%d] flush", dr, tk->key_pid); + tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t *)t); + /* update the keys */ + if (changed & 1) { + debug2("%p: even key[%d] set for decoder", dr, tk->key_pid); + tvhcsa_set_key_even(&tk->key_csa, tk->key_data[0]); + tk->key_valid |= 0x40; + } + if (changed & 2) { + debug2("%p: odd key[%d] set for decoder", dr, tk->key_pid); + tvhcsa_set_key_odd(&tk->key_csa, tk->key_data[1]); + tk->key_valid |= 0x80; } } @@ -1007,7 +1026,7 @@ descrambler_descramble ( service_t *t, tsb2 = sb->sb_data; len2 = sb->sb_ptr; if (dd->dd_key) { - key_flush(dr, dd->dd_key, t); + key_flush(dr, dd->dd_key, dd->dd_key_changed, t); dd->dd_key = NULL; } if (len2 == 0) @@ -1163,7 +1182,7 @@ queue: } } else { if (dr->dr_skip || dr->dr_ca_count == 0) - ts_skip_packet2((mpegts_service_t *)dr->dr_service, tsb, len); + ts_skip_packet2((mpegts_service_t *)t, tsb, len); service_set_streaming_status_flags(t, TSS_NO_ACCESS); } if (flush_data) diff --git a/src/descrambler/tvhcsa.c b/src/descrambler/tvhcsa.c index 3f909e746..297c10a9f 100644 --- a/src/descrambler/tvhcsa.c +++ b/src/descrambler/tvhcsa.c @@ -312,32 +312,20 @@ void tvhcsa_destroy ( tvhcsa_t *csa ) { #if ENABLE_DVBCSA - if (csa->csa_key_odd) { + if (csa->csa_key_odd) dvbcsa_bs_key_free(csa->csa_key_odd); - csa->csa_key_odd = NULL; - } - if (csa->csa_key_even) { + if (csa->csa_key_even) dvbcsa_bs_key_free(csa->csa_key_even); - csa->csa_key_even = NULL; - } - if (csa->csa_tsbbatch_odd) { + if (csa->csa_tsbbatch_odd) free(csa->csa_tsbbatch_odd); - csa->csa_tsbbatch_odd = NULL; - } - if (csa->csa_tsbbatch_even) { + if (csa->csa_tsbbatch_even) free(csa->csa_tsbbatch_even); - csa->csa_tsbbatch_even = NULL; - } #else - if (csa->csa_keys) { + if (csa->csa_keys) free_key_struct(csa->csa_keys); - csa->csa_keys = NULL; - } #endif - if (csa->csa_tsbcluster) { + if (csa->csa_tsbcluster) free(csa->csa_tsbcluster); - csa->csa_tsbcluster = NULL; - } if (csa->csa_priv) { switch (csa->csa_type) { case DESCRAMBLER_CSA_CBC: @@ -354,8 +342,6 @@ tvhcsa_destroy ( tvhcsa_t *csa ) default: assert(0); } - csa->csa_priv = NULL; } - csa->csa_type = 0; - csa->csa_keylen = 0; + memset(csa, 0, sizeof(*csa)); }