diff --git a/src/descrambler.h b/src/descrambler.h index 97af0811..8ce3e98e 100755 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -66,6 +66,7 @@ typedef struct th_descrambler_runtime { uint32_t dr_key_first:1; uint8_t dr_key_index; uint8_t dr_key_valid; + uint8_t dr_key_changed; time_t dr_key_start; time_t dr_key_timestamp[2]; time_t dr_ecm_start; @@ -73,6 +74,8 @@ typedef struct th_descrambler_runtime { time_t dr_last_err; sbuf_t dr_buf; tvhlog_limit_t dr_loglimit_key; + uint8_t dr_key_even[16]; + uint8_t dr_key_odd[16]; } th_descrambler_runtime_t; typedef void (*descrambler_section_callback_t) diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index a15aa647..6c690ffd 100755 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -166,10 +166,11 @@ void descrambler_keys ( th_descrambler_t *td, int type, const uint8_t *even, const uint8_t *odd ) { + static uint8_t empty[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; service_t *t = td->td_service; th_descrambler_runtime_t *dr; th_descrambler_t *td2; - int i, j = 0; + int j = 0; if (t == NULL || (dr = t->s_descramble) == NULL) { td->td_keystate = DS_FORBIDDEN; @@ -195,22 +196,20 @@ descrambler_keys ( th_descrambler_t *td, int type, goto fin; } - for (i = 0; i < dr->dr_csa.csa_keylen; i++) - if (even[i]) { - j++; - tvhcsa_set_key_even(&dr->dr_csa, even); - dr->dr_key_valid |= 0x40; - dr->dr_key_timestamp[0] = dispatch_clock; - break; - } - for (i = 0; i < dr->dr_csa.csa_keylen; i++) - if (odd[i]) { - j++; - tvhcsa_set_key_odd(&dr->dr_csa, odd); - dr->dr_key_valid |= 0x80; - dr->dr_key_timestamp[1] = dispatch_clock; - break; - } + if (memcmp(empty, even, dr->dr_csa.csa_keylen)) { + j++; + memcpy(dr->dr_key_even, even, dr->dr_csa.csa_keylen); + dr->dr_key_changed |= 1; + dr->dr_key_valid |= 0x40; + dr->dr_key_timestamp[0] = dispatch_clock; + } + if (memcmp(empty, odd, dr->dr_csa.csa_keylen)) { + j++; + memcpy(dr->dr_key_odd, odd, dr->dr_csa.csa_keylen); + dr->dr_key_changed |= 2; + dr->dr_key_valid |= 0x80; + dr->dr_key_timestamp[1] = dispatch_clock; + } if (j) { if (td->td_keystate != DS_RESOLVED) @@ -322,7 +321,7 @@ key_update( th_descrambler_runtime_t *dr, uint8_t key ) if (dr->dr_key_start) dr->dr_key_start = dispatch_clock; else - /* We don't knoe the exact start key switch time */ + /* We don't know the exact start key switch time */ dr->dr_key_start = dispatch_clock - 60; } @@ -362,6 +361,7 @@ descrambler_descramble ( service_t *t, if (dr == NULL) return -1; + count = failed = 0; LIST_FOREACH(td, &t->s_descramblers, td_service_link) { count++; @@ -403,6 +403,16 @@ descrambler_descramble ( service_t *t, service_reset_streaming_status_flags(t, TSS_NO_ACCESS); sbuf_free(&dr->dr_buf); } + + if (dr->dr_key_changed) { + dr->dr_csa.csa_flush(&dr->dr_csa, (mpegts_service_t *)td->td_service); + if (dr->dr_key_changed & 1) + tvhcsa_set_key_even(&dr->dr_csa, dr->dr_key_even); + if (dr->dr_key_changed & 2) + tvhcsa_set_key_odd(&dr->dr_csa, dr->dr_key_odd); + dr->dr_key_changed = 0; + } + ki = tsb[3]; if ((ki & 0x80) != 0x00) { if (key_valid(dr, ki) == 0) { diff --git a/src/descrambler/tvhcsa.c b/src/descrambler/tvhcsa.c index ee634c9e..ac4e1373 100644 --- a/src/descrambler/tvhcsa.c +++ b/src/descrambler/tvhcsa.c @@ -24,6 +24,13 @@ #include #include +static void +tvhcsa_aes_flush + ( tvhcsa_t *csa, struct mpegts_service *s ) +{ + /* empty - no queue */ +} + static void tvhcsa_aes_descramble ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb ) @@ -32,6 +39,70 @@ tvhcsa_aes_descramble ts_recv_packet2(s, tsb); } +static void +tvhcsa_des_flush + ( tvhcsa_t *csa, struct mpegts_service *s ) +{ +#if ENABLE_DVBCSA + + int i; + const uint8_t *t0; + + if(csa->csa_fill_even) { + csa->csa_tsbbatch_even[csa->csa_fill_even].data = NULL; + dvbcsa_bs_decrypt(csa->csa_key_even, csa->csa_tsbbatch_even, 184); + csa->csa_fill_even = 0; + } + if(csa->csa_fill_odd) { + csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = NULL; + dvbcsa_bs_decrypt(csa->csa_key_odd, csa->csa_tsbbatch_odd, 184); + csa->csa_fill_odd = 0; + } + + t0 = csa->csa_tsbcluster; + + for(i = 0; i < csa->csa_fill; i++) { + ts_recv_packet2(s, t0); + t0 += 188; + } + csa->csa_fill = 0; + +#else + + int r; + unsigned char *vec[3]; + + while(1) { + + vec[0] = csa->csa_tsbcluster; + vec[1] = csa->csa_tsbcluster + csa->csa_fill * 188; + vec[2] = NULL; + + r = decrypt_packets(csa->csa_keys, vec); + if(r > 0) { + int i; + const uint8_t *t0 = csa->csa_tsbcluster; + + for(i = 0; i < r; i++) { + ts_recv_packet2(s, t0); + t0 += 188; + } + + r = csa->csa_fill - r; + assert(r >= 0); + + if(r > 0) + memmove(csa->csa_tsbcluster, t0, r * 188); + csa->csa_fill = r; + } else { + csa->csa_fill = 0; + } + break; + } + +#endif +} + static void tvhcsa_des_descramble ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb ) @@ -43,8 +114,6 @@ tvhcsa_des_descramble int len; int offset; int n; - int i; - const uint8_t *t0; pkt = csa->csa_tsbcluster + csa->csa_fill * 188; memcpy(pkt, tsb, 188); @@ -90,28 +159,9 @@ tvhcsa_des_descramble if(csa->csa_fill != csa->csa_cluster_size) return; - if(csa->csa_fill_even) { - csa->csa_tsbbatch_even[csa->csa_fill_even].data = NULL; - dvbcsa_bs_decrypt(csa->csa_key_even, csa->csa_tsbbatch_even, 184); - csa->csa_fill_even = 0; - } - if(csa->csa_fill_odd) { - csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = NULL; - dvbcsa_bs_decrypt(csa->csa_key_odd, csa->csa_tsbbatch_odd, 184); - csa->csa_fill_odd = 0; - } - - t0 = csa->csa_tsbcluster; - - for(i = 0; i < csa->csa_fill; i++) { - ts_recv_packet2(s, t0); - t0 += 188; - } - csa->csa_fill = 0; + tvhcsa_des_flush(csa, s); #else - int r; - unsigned char *vec[3]; memcpy(csa->csa_tsbcluster + csa->csa_fill * 188, tsb, 188); csa->csa_fill++; @@ -119,33 +169,8 @@ tvhcsa_des_descramble if(csa->csa_fill != csa->csa_cluster_size) return; - while(1) { + tvhcsa_des_flush(csa, s); - vec[0] = csa->csa_tsbcluster; - vec[1] = csa->csa_tsbcluster + csa->csa_fill * 188; - vec[2] = NULL; - - r = decrypt_packets(csa->csa_keys, vec); - if(r > 0) { - int i; - const uint8_t *t0 = csa->csa_tsbcluster; - - for(i = 0; i < r; i++) { - ts_recv_packet2(s, t0); - t0 += 188; - } - - r = csa->csa_fill - r; - assert(r >= 0); - - if(r > 0) - memmove(csa->csa_tsbcluster, t0, r * 188); - csa->csa_fill = r; - } else { - csa->csa_fill = 0; - } - break; - } #endif } @@ -159,10 +184,12 @@ tvhcsa_set_type( tvhcsa_t *csa, int type ) switch (type) { case DESCRAMBLER_DES: csa->csa_descramble = tvhcsa_des_descramble; + csa->csa_flush = tvhcsa_des_flush; csa->csa_keylen = 8; break; case DESCRAMBLER_AES: csa->csa_descramble = tvhcsa_aes_descramble; + csa->csa_flush = tvhcsa_aes_flush; csa->csa_keylen = 16; break; default: diff --git a/src/descrambler/tvhcsa.h b/src/descrambler/tvhcsa.h index 0025f04a..e50ea3f7 100644 --- a/src/descrambler/tvhcsa.h +++ b/src/descrambler/tvhcsa.h @@ -42,6 +42,8 @@ typedef struct tvhcsa int csa_keylen; void (*csa_descramble) ( struct tvhcsa *csa, struct mpegts_service *s, const uint8_t *tsb ); + void (*csa_flush) + ( struct tvhcsa *csa, struct mpegts_service *s ); int csa_cluster_size; uint8_t *csa_tsbcluster;