bool cDeCSA::SetDescr(ca_descr_t *ca_descr, bool initial) { cMutexLock lock(&mutex); int idx=ca_descr->index; if(idx<MAX_CSA_IDX && GetKeyStruct(idx)) { if(!initial && ca_descr->parity==(even_odd[idx]&0x40)>>6) { if(flags[idx] & (ca_descr->parity?FL_ODD_GOOD:FL_EVEN_GOOD)) { printf("adapter%d/demux%d idx %d: %s key in use (%d ms)", adapter, demux ,idx,ca_descr->parity?"odd":"even",MAX_REL_WAIT); if(wait.TimedWait(mutex,MAX_REL_WAIT)) printf("adapter%d/demux%d idx %d: successfully waited for release\n", adapter, demux, idx); else printf("adapter%d/demux%d idx %d: timed out. setting anyways\n", adapter, demux, idx); } else printf("adapter%d/demux%d idx %d: late key set...\n", adapter, demux, idx); } if(ca_descr->parity==0) { dvbcsa_bs_key_set(ca_descr->cw, csa_bs_key_even[idx]); if(!CheckNull(ca_descr->cw,8)) flags[idx] |= FL_EVEN_GOOD|FL_ACTIVITY; else printf("adapter%d/demux%d idx %d: zero even CW\n", adapter, demux, idx); wait.Broadcast(); } else { dvbcsa_bs_key_set(ca_descr->cw, csa_bs_key_odd[idx]); if(!CheckNull(ca_descr->cw,8)) flags[idx] |= FL_ODD_GOOD|FL_ACTIVITY; else printf("adapter%d/demux%d idx%d: zero odd CW\n", adapter, demux, idx); wait.Broadcast(); } } return true; }
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); #endif break; case DESCRAMBLER_DES_NCB: des_set_even_control_word(csa->csa_priv, even); break; case DESCRAMBLER_AES_ECB: aes_set_even_control_word(csa->csa_priv, even); break; case DESCRAMBLER_AES128_ECB: aes128_set_even_control_word(csa->csa_priv, even); break; assert(0); } }
/* The following routine is taken from benchbitslice in libdvbcsa */ void dvbcsa_benchmark(void) { struct timeval t0, t1; struct dvbcsa_bs_key_s *key = dvbcsa_bs_key_alloc(); unsigned int n, i, npackets = 0; unsigned int batch_size = dvbcsa_bs_batch_size(); uint8_t data[batch_size + 1][188]; struct dvbcsa_bs_batch_s pcks[batch_size + 1]; uint8_t cw[8] = { 0x12, 0x34, 0x56, 0x78, 0x89, 0xab, 0xcd, 0xef, }; dvbcsa_bs_key_set (cw, key); printf("Batch size %d packets.\n\n", batch_size); for (i = 0; i < batch_size; i++) { pcks[i].data = data[i]; pcks[i].len = 184; memset(data[i], rand(), pcks[i].len); } pcks[i].data = NULL; gettimeofday(&t0, NULL); for (n = (1 << 12) / batch_size; n < (1 << 19) / batch_size; n *= 2) { printf(" Decrypting %6u mpegts packets\r", n * batch_size); fflush(stdout); for (i = 0; i < n; i++) { dvbcsa_bs_decrypt(key, pcks, 184); } npackets += n * batch_size; } gettimeofday(&t1, NULL); unsigned long long usec = timeval_diff_usec(&t0, &t1); printf("DONE: %u packets (%u bytes) decrypted in %llu ms = %.1f Mbits/s\n\n", npackets, npackets * 188, usec / 1000, (double)(npackets * 188 * 8) / (double)usec ); dvbcsa_bs_key_free(key); }
void tvhcsa_set_key_odd( tvhcsa_t *csa, const uint8_t *odd ) { assert(csa->csa_type); switch (csa->csa_type) { case DESCRAMBLER_CSA_CBC: #if ENABLE_DVBCSA dvbcsa_bs_key_set(odd, csa->csa_key_odd); #endif break; case DESCRAMBLER_DES_NCB: des_set_odd_control_word(csa->csa_priv, odd); break; case DESCRAMBLER_AES_ECB: aes_set_odd_control_word(csa->csa_priv, odd); break; case DESCRAMBLER_AES128_ECB: aes128_set_odd_control_word(csa->csa_priv, odd); break; default: assert(0); } }
inline void csa_set_odd_cw(csakey_t *csakey, uint8_t *odd_cw) { struct csakey *key = (struct csakey *)csakey; dvbcsa_key_set(odd_cw, key->s_csakey[1]); dvbcsa_bs_key_set(odd_cw, key->bs_csakey[1]); ffdecsa_set_odd_cw(key->ff_csakey, odd_cw); }
inline void csa_set_even_cw(csakey_t *csakey, uint8_t *even_cw) { struct csakey *key = (struct csakey *)csakey; dvbcsa_key_set(even_cw, key->s_csakey[0]); dvbcsa_bs_key_set(even_cw, key->bs_csakey[0]); ffdecsa_set_even_cw(key->ff_csakey, even_cw); }