descrambler/csa: prepare for AES keys...

This commit is contained in:
Jaroslav Kysela 2014-08-01 18:32:04 +02:00
parent 5ee5475067
commit 4bf8754ef3
6 changed files with 127 additions and 43 deletions

View file

@ -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,

View file

@ -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);
}

View file

@ -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++) {

View file

@ -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:

View file

@ -24,8 +24,15 @@
#include <unistd.h>
#include <assert.h>
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

View file

@ -23,6 +23,7 @@ struct mpegts_service;
struct elementary_stream;
#include "tvheadend.h"
#include "descrambler.h"
#include <stdint.h>
#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 );