From 4bf8754ef33d925a382f48858cd3d3fd2dc31319 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 1 Aug 2014 18:32:04 +0200 Subject: [PATCH] descrambler/csa: prepare for AES keys... --- src/descrambler.h | 6 ++- src/descrambler/capmt.c | 2 +- src/descrambler/cwc.c | 2 +- src/descrambler/descrambler.c | 56 +++++++++++++++++--------- src/descrambler/tvhcsa.c | 74 ++++++++++++++++++++++++++++++++++- src/descrambler/tvhcsa.h | 30 +++++--------- 6 files changed, 127 insertions(+), 43 deletions(-) diff --git a/src/descrambler.h b/src/descrambler.h index 8c6bbff3..f0423cfc 100755 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -29,6 +29,10 @@ struct tvhcsa; struct mpegts_table; struct mpegts_mux; +#define DESCRAMBLER_NONE 0 +#define DESCRAMBLER_DES 1 +#define DESCRAMBLER_AES 2 + /** * Descrambler superclass * @@ -147,7 +151,7 @@ void descrambler_done ( void ); void descrambler_service_start ( struct service *t ); void descrambler_service_stop ( struct service *t ); void descrambler_caid_changed ( struct service *t ); -void descrambler_keys ( th_descrambler_t *t, +void descrambler_keys ( th_descrambler_t *t, int type, const uint8_t *even, const uint8_t *odd ); int descrambler_descramble ( struct service *t, struct elementary_stream *st, diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index babd1a81..6e88d0db 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -972,7 +972,7 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, uint16_t seq, if (adapter != ct->ct_adapter) continue; - descrambler_keys((th_descrambler_t *)ct, even, odd); + descrambler_keys((th_descrambler_t *)ct, DESCRAMBLER_DES, even, odd); } pthread_mutex_unlock(&capmt->capmt_mutex); } diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index a47caf2a..5b7138a5 100755 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -808,7 +808,7 @@ forbid: "Obtained key for service \"%s\" in %"PRId64" ms, from %s", t->s_dvb_svcname, delay, ct->td_nicename); - descrambler_keys((th_descrambler_t *)ct, msg + 3, msg + 3 + 8); + descrambler_keys((th_descrambler_t *)ct, DESCRAMBLER_DES, msg + 3, msg + 3 + 8); LIST_FOREACH(ep, &ct->cs_pids, ep_link) { for(i = 0; i < ep->ep_last_section; i++) { diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 2e02a7b7..ed790daa 100755 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -154,12 +154,13 @@ descrambler_caid_changed ( service_t *t ) } void -descrambler_keys ( th_descrambler_t *td, +descrambler_keys ( th_descrambler_t *td, int type, const uint8_t *even, const uint8_t *odd ) { service_t *t = td->td_service; th_descrambler_runtime_t *dr; th_descrambler_t *td2; + tvhcsa_t *csa = td->td_csa; int i, j = 0; if (t == NULL || (dr = t->s_descramble) == NULL) { @@ -167,6 +168,9 @@ descrambler_keys ( th_descrambler_t *td, return; } + if (tvhcsa_set_type(td->td_csa, type) < 0) + return; + pthread_mutex_lock(&t->s_stream_mutex); LIST_FOREACH(td2, &t->s_descramblers, td_service_link) @@ -181,18 +185,18 @@ descrambler_keys ( th_descrambler_t *td, goto fin; } - for (i = 0; i < 8; i++) + for (i = 0; i < csa->csa_keylen; i++) if (even[i]) { j++; - tvhcsa_set_key_even(td->td_csa, even); + tvhcsa_set_key_even(csa, even); dr->dr_key_valid |= 0x40; dr->dr_key_timestamp[0] = dispatch_clock; break; } - for (i = 0; i < 8; i++) + for (i = 0; i < csa->csa_keylen; i++) if (odd[i]) { j++; - tvhcsa_set_key_odd(td->td_csa, odd); + tvhcsa_set_key_odd(csa, odd); dr->dr_key_valid |= 0x80; dr->dr_key_timestamp[1] = dispatch_clock; break; @@ -204,13 +208,29 @@ descrambler_keys ( th_descrambler_t *td, "Obtained keys from %s for service \"%s\"", td->td_nicename, ((mpegts_service_t *)t)->s_dvb_svcname); - tvhtrace("descrambler", "Obtained keys " - "%02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X" - " from %s for service \"%s\"", - even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7], - odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7], - td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname); + if (csa->csa_keylen == 8) { + tvhtrace("descrambler", "Obtained keys " + "%02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X" + " from %s for service \"%s\"", + even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7], + odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7], + td->td_nicename, + ((mpegts_service_t *)t)->s_dvb_svcname); + } else if (csa->csa_keylen == 16) { + tvhtrace("descrambler", "Obtained keys " + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X:" + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" + " from %s for service \"%s\"", + even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7], + even[8], even[9], even[10], even[11], even[12], even[13], even[14], even[15], + odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7], + odd[8], odd[9], odd[10], odd[11], odd[12], odd[13], odd[14], odd[15], + td->td_nicename, + ((mpegts_service_t *)t)->s_dvb_svcname); + } else { + tvhtrace("descrambler", "Unknown keys from %s for for service \"%s\"", + td->td_nicename, ((mpegts_service_t *)t)->s_dvb_svcname); + } dr->dr_ecm_key_time = dispatch_clock; td->td_keystate = DS_RESOLVED; } else { @@ -309,9 +329,9 @@ descrambler_descramble ( service_t *t, key_update(dr, ki); } } - tvhcsa_descramble(td->td_csa, - (mpegts_service_t *)td->td_service, - tsb2); + td->td_csa->csa_descramble(td->td_csa, + (mpegts_service_t *)td->td_service, + tsb2); dr->dr_last_descramble = dispatch_clock; } sbuf_free(&dr->dr_buf); @@ -346,9 +366,9 @@ descrambler_descramble ( service_t *t, key_update(dr, ki); } } - tvhcsa_descramble(td->td_csa, - (mpegts_service_t *)td->td_service, - tsb); + td->td_csa->csa_descramble(td->td_csa, + (mpegts_service_t *)td->td_service, + tsb); dr->dr_last_descramble = dispatch_clock; return 1; next: diff --git a/src/descrambler/tvhcsa.c b/src/descrambler/tvhcsa.c index 3649795d..75e65e39 100644 --- a/src/descrambler/tvhcsa.c +++ b/src/descrambler/tvhcsa.c @@ -24,8 +24,15 @@ #include #include -void -tvhcsa_descramble +static void +tvhcsa_aes_descramble + ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb ) +{ + /* Not Implemented Yet */ +} + +static void +tvhcsa_des_descramble ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb ) { #if ENABLE_DVBCSA @@ -141,9 +148,72 @@ tvhcsa_descramble #endif } +int +tvhcsa_set_type( tvhcsa_t *csa, int type ) +{ + if (csa->csa_type == type) + return 0; + if (csa->csa_descramble) + return -1; + switch (type) { + case DESCRAMBLER_DES: + csa->csa_descramble = tvhcsa_des_descramble; + csa->csa_keylen = 8; + break; + case DESCRAMBLER_AES: + csa->csa_descramble = tvhcsa_aes_descramble; + csa->csa_keylen = 16; + break; + default: + assert(0); + } + csa->csa_type = type; + return 0; +} + + +void tvhcsa_set_key_even( tvhcsa_t *csa, const uint8_t *even ) +{ + switch (csa->csa_type) { + case DESCRAMBLER_DES: +#if ENABLE_DVBCSA + dvbcsa_bs_key_set(even, csa->csa_key_even); +#else + set_even_control_word((csa)->csa_keys, even); +#endif + break; + case DESCRAMBLER_AES: + /* Not Yet Implemented */ + break; + default: + assert(0); + } +} + +void tvhcsa_set_key_odd( tvhcsa_t *csa, const uint8_t *odd ) +{ + assert(csa->csa_type); + switch (csa->csa_type) { + case DESCRAMBLER_DES: +#if ENABLE_DVBCSA + dvbcsa_bs_key_set(odd, csa->csa_key_odd); +#else + set_odd_control_word((csa)->csa_keys, odd); +#endif + break; + case DESCRAMBLER_AES: + /* Not Yet Implemented */ + break; + default: + assert(0); + } +} + void tvhcsa_init ( tvhcsa_t *csa ) { + csa->csa_type = 0; + csa->csa_keylen = 0; #if ENABLE_DVBCSA csa->csa_cluster_size = dvbcsa_bs_batch_size(); #else diff --git a/src/descrambler/tvhcsa.h b/src/descrambler/tvhcsa.h index b14acf0f..cc58231e 100644 --- a/src/descrambler/tvhcsa.h +++ b/src/descrambler/tvhcsa.h @@ -23,6 +23,7 @@ struct mpegts_service; struct elementary_stream; #include "tvheadend.h" +#include "descrambler.h" #include #if ENABLE_DVBCSA @@ -37,6 +38,11 @@ typedef struct tvhcsa /** * CSA */ + int csa_type; /*< see DESCRAMBLER_* defines */ + int csa_keylen; + void (*csa_descramble) + ( struct tvhcsa *csa, struct mpegts_service *s, const uint8_t *tsb ); + int csa_cluster_size; uint8_t *csa_tsbcluster; int csa_fill; @@ -52,30 +58,14 @@ typedef struct tvhcsa #else void *csa_keys; #endif + void *csa_aes_keys; } tvhcsa_t; -#if ENABLE_DVBCSA +int tvhcsa_set_type( tvhcsa_t *csa, int type ); -#define tvhcsa_set_key_even(csa, cw)\ - dvbcsa_bs_key_set(cw, (csa)->csa_key_even) - -#define tvhcsa_set_key_odd(csa, cw)\ - dvbcsa_bs_key_set(cw, (csa)->csa_key_odd) - -#else - -#define tvhcsa_set_key_even(csa, cw)\ - set_even_control_word((csa)->csa_keys, cw) - -#define tvhcsa_set_key_odd(csa, cw)\ - set_odd_control_word((csa)->csa_keys, cw) - -#endif - -void -tvhcsa_descramble - ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb ); +void tvhcsa_set_key_even( tvhcsa_t *csa, const uint8_t *even ); +void tvhcsa_set_key_odd ( tvhcsa_t *csa, const uint8_t *odd ); void tvhcsa_init ( tvhcsa_t *csa ); void tvhcsa_destroy ( tvhcsa_t *csa );