Skip to content

Commit

Permalink
Support icam ecm with a patched libdvbcsa #1003
Browse files Browse the repository at this point in the history
  • Loading branch information
Catalin Toda committed Jan 4, 2023
1 parent 6bdd0e4 commit 6d624cc
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 27 deletions.
11 changes: 6 additions & 5 deletions src/ca.c
Expand Up @@ -253,11 +253,11 @@ void send_cw_to_all_pmts(ca_device_t *d, int parity) {
for (i = 0; i < d->max_ca_pmt; i++) {
if (PMT_ID_IS_VALID(d->capmt[i].pmt_id)) {
send_cw(d->capmt[i].pmt_id, CA_ALGO_AES128_CBC, parity,
d->key[parity], d->iv[parity], 3720);
d->key[parity], d->iv[parity], 3720, NULL);
}
if (PMT_ID_IS_VALID(d->capmt[i].other_id)) {
send_cw(d->capmt[i].other_id, CA_ALGO_AES128_CBC, parity,
d->key[parity], d->iv[parity], 3720);
d->key[parity], d->iv[parity], 3720, NULL);
}
}
}
Expand Down Expand Up @@ -522,10 +522,11 @@ int dvbca_process_pmt(adapter *ad, SPMT *spmt) {
LOG_AND_RETURN(TABLES_RESULT_ERROR_NORETRY, "send_capmt failed");

if (d->key[0][0])
send_cw(spmt->id, CA_ALGO_AES128_CBC, 0, d->key[0], d->iv[0],
3600); // 1 hour
send_cw(spmt->id, CA_ALGO_AES128_CBC, 0, d->key[0], d->iv[0], 3600,
NULL); // 1 hour
if (d->key[1][0])
send_cw(spmt->id, CA_ALGO_AES128_CBC, 1, d->key[1], d->iv[1], 3600);
send_cw(spmt->id, CA_ALGO_AES128_CBC, 1, d->key[1], d->iv[1], 3600,
NULL);

return 0;
}
Expand Down
13 changes: 12 additions & 1 deletion src/csa.c
Expand Up @@ -47,12 +47,23 @@

#define DEFAULT_LOG LOG_DVBCA

void dvbcsa_bs_key_set_ecm(unsigned char ecm, const dvbcsa_cw_t cw,
struct dvbcsa_bs_key_s *key) __attribute__((weak));
void dvbcsa_create_key(SCW *cw) { cw->key = dvbcsa_bs_key_alloc(); }

void dvbcsa_delete_key(SCW *cw) { dvbcsa_key_free(cw->key); }

void dvbcsa_set_cw(SCW *cw, SPMT *pmt) {
dvbcsa_bs_key_set((unsigned char *)cw->cw, cw->key);
unsigned char ecm = *(unsigned char *)cw->opaque;
if (!dvbcsa_bs_key_set_ecm) {
dvbcsa_bs_key_set((unsigned char *)cw->cw, cw->key);
if (ecm)
LOGL(1, "minisatip required libdvbcsa with ICAM support. Please "
"see https://github.com/catalinii/minisatip/issues/1003 "
"for more details");
} else {
dvbcsa_bs_key_set_ecm(ecm, (unsigned char *)cw->cw, cw->key);
}
}

void copy_batch(struct dvbcsa_bs_batch_s *d, SPMT_batch *s, int len) {
Expand Down
20 changes: 11 additions & 9 deletions src/dvbapi.c
Expand Up @@ -20,14 +20,14 @@

#include "dvbapi.h"
#include "adapter.h"
#include "api/symbols.h"
#include "api/variables.h"
#include "dvb.h"
#include "minisatip.h"
#include "pmt.h"
#include "socketworks.h"
#include "tables.h"
#include "utils.h"
#include "api/symbols.h"
#include "api/variables.h"
#include "utils/ticks.h"

#include <arpa/inet.h>
Expand Down Expand Up @@ -318,7 +318,7 @@ int dvbapi_reply(sockets *s) {
k_id, parity, index, correct ? "OK" : "NOK", cw[0], cw[1],
cw[2], cw[3], cw[4], cw[5], cw[6], cw[7]);

send_cw(k->pmt_id, k->algo, parity, cw, NULL, 0);
send_cw(k->pmt_id, k->algo, parity, cw, NULL, 0, &k->icam_ecm);

mutex_unlock(&k->mutex);
} else
Expand Down Expand Up @@ -651,12 +651,14 @@ int send_ecm(int filter_id, unsigned char *b, int len, void *opaque) {
len = ((b[1] & 0xF) << 8) + b[2];
len += 3;
k->last_ecm = getTick();
LOG("dvbapi: sending ECM key %d for pid %04X (%d), current ecm_parity = "
"%d, "
"previous parity %d, demux = %d, filter = %d, len = %d [%02X %02X %02X "
if (b[2] - b[4] == 4)
k->icam_ecm = b[0x15];
LOG("dvbapi: sending ECM key %d for pid %04X (%d), ecm_parity = %d, "
"previous parity %d, demux = %d, filter = %d, icam_ecm %d, len = %d "
"[%02X %02X %02X "
"%02X]",
k->id, pid, pid, k->ecm_parity[i], old_parity, demux, filter, len, b[0],
b[1], b[2], b[3]);
k->id, pid, pid, k->ecm_parity[i], old_parity, demux, filter,
k->icam_ecm, len, b[0], b[1], b[2], b[3]);

if (demux < 0)
return 0;
Expand All @@ -677,7 +679,6 @@ int send_ecm(int filter_id, unsigned char *b, int len, void *opaque) {
int set_algo(SKey *k, int algo, int mode) {
if (algo == CA_ALGO_AES128 && mode == CA_MODE_CBC)
algo = CA_ALGO_AES128_CBC;

k->algo = algo;

return 0;
Expand Down Expand Up @@ -724,6 +725,7 @@ int keys_add(int i, int adapter, int pmt_id) {
k->last_dmx_stop = 0;
k->onid = 0;
k->tsid = 0;
k->icam_ecm = 0;
memset(k->cw[0], 0, 16);
memset(k->cw[1], 0, 16);
memset(k->filter_id, -1, sizeof(k->filter_id));
Expand Down
1 change: 1 addition & 0 deletions src/dvbapi.h
Expand Up @@ -77,6 +77,7 @@ typedef struct struct_key {
demux[MAX_KEY_FILTERS], pid[MAX_KEY_FILTERS],
ecm_parity[MAX_KEY_FILTERS];
int64_t last_parity_change;
unsigned char icam_ecm;
} SKey;

void init_dvbapi();
Expand Down
13 changes: 8 additions & 5 deletions src/pmt.c
Expand Up @@ -625,11 +625,13 @@ char *cw_to_string(SCW *cw, char *buf) {
}
int64_t ctime = getTick();
sprintf(buf,
"id %d, parity %d, pmt %d, time %jd ms ago, expiry in %jd ms, "
"id %d, parity %d, pmt %d,%s time %jd ms ago, expiry in "
"%jd ms, "
"CW: %02X %02X %02X %02X %02X %02X %02X %02X",
cw->id, cw->parity, cw->pmt, ctime - cw->time, cw->expiry - ctime,
cw->cw[0], cw->cw[1], cw->cw[2], cw->cw[3], cw->cw[4], cw->cw[5],
cw->cw[6], cw->cw[7]);
cw->id, cw->parity, cw->pmt,
cw->opaque && *(uint8_t *)cw->opaque ? " ICAM," : "",
ctime - cw->time, cw->expiry - ctime, cw->cw[0], cw->cw[1],
cw->cw[2], cw->cw[3], cw->cw[4], cw->cw[5], cw->cw[6], cw->cw[7]);
if (cw->iv[0])
sprintf(buf + strlen(buf),
", IV: %02X %02X %02X %02X %02X %02X %02X %02X", cw->iv[0],
Expand Down Expand Up @@ -871,7 +873,7 @@ void update_cw(SPMT *pmt) {
}

int send_cw(int pmt_id, int algo, int parity, uint8_t *cw, uint8_t *iv,
int64_t expiry) {
int64_t expiry, void *opaque) {
char buf[300];
int i, master_pmt;
SCW_op *op = get_op_for_algo(algo);
Expand Down Expand Up @@ -933,6 +935,7 @@ int send_cw(int pmt_id, int algo, int parity, uint8_t *cw, uint8_t *iv,
c->cw_len = 16;
c->time = getTick();
c->set_time = 0;
c->opaque = opaque;
if (expiry == 0)
c->expiry = c->time + MAX_CW_TIME;
else
Expand Down
4 changes: 2 additions & 2 deletions src/pmt.h
Expand Up @@ -93,7 +93,7 @@ typedef struct struct_cw {
char cw_len;
int16_t id;
int64_t expiry, set_time;

void *opaque;
} SCW;

typedef struct struct_stream_pid {
Expand Down Expand Up @@ -176,7 +176,7 @@ typedef struct struct_filter {

int register_algo(SCW_op *o);
int send_cw(int pmt_id, int algo, int parity, uint8_t *cw, uint8_t *iv,
int64_t expiry);
int64_t expiry, void *opaque);

extern int npmts;
static inline SPMT *get_pmt(int id) {
Expand Down
5 changes: 4 additions & 1 deletion src/tables.c
Expand Up @@ -20,7 +20,6 @@

#include "tables.h"
#include "adapter.h"
#include "ca.h"
#include "dvb.h"
#include "dvbapi.h"
#include "minisatip.h"
Expand All @@ -47,6 +46,10 @@
#include "ddci.h"
#endif

#ifndef DISABLE_DVBCA
#include "ca.h"
#endif

#define DEFAULT_LOG LOG_TABLES

SCA ca[MAX_CA];
Expand Down
9 changes: 5 additions & 4 deletions tests/test_pmt.c
Expand Up @@ -179,10 +179,11 @@ int test_decrypt() {
}
a[0]->rlen = max_len * sizeof(packet);
init_algo();
send_cw(0, CA_ALGO_DVBCSA, 0, cw_invalid, NULL, 25);
send_cw(0, CA_ALGO_DVBCSA, 0, cw0, NULL, 25);
send_cw(0, CA_ALGO_DVBCSA, 1, cw1, NULL, 25);
send_cw(0, CA_ALGO_DVBCSA, 0, cw_invalid, NULL, 25);
uint8_t ecm = 0;
send_cw(0, CA_ALGO_DVBCSA, 0, cw_invalid, NULL, 25, &ecm);
send_cw(0, CA_ALGO_DVBCSA, 0, cw0, NULL, 25, &ecm);
send_cw(0, CA_ALGO_DVBCSA, 1, cw1, NULL, 25, &ecm);
send_cw(0, CA_ALGO_DVBCSA, 0, cw_invalid, NULL, 25, &ecm);

SPMT_batch batch[1] = {{.data = packet, .len = sizeof(packet)}};
ASSERT(0 != test_decrypt_packet(cws[0], batch, 1),
Expand Down

0 comments on commit 6d624cc

Please sign in to comment.