diff --git a/src/cwc.c b/src/cwc.c index 431596a4..44f0c3b0 100644 --- a/src/cwc.c +++ b/src/cwc.c @@ -61,6 +61,7 @@ typedef enum { CARD_VIACCESS, CARD_NAGRA, CARD_NDS, + CARD_CRYPTOWORKS, CARD_UNKNOWN } card_type_t; @@ -243,6 +244,7 @@ typedef struct cwc { int shared_len; uint8_t * shared_emm; } cwc_viaccess_emm; +#define cwc_cryptoworks_emm cwc_viaccess_emm /* Card type */ card_type_t cwc_card_type; @@ -280,6 +282,7 @@ void cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_nagra(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len); +void cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len); /** @@ -696,6 +699,11 @@ cwc_detect_card_type(cwc_t *cwc) tvhlog(LOG_INFO, "cwc", "%s: nds card", cwc->cwc_hostname); break; + case 0x0d: + cwc->cwc_card_type = CARD_CRYPTOWORKS; + tvhlog(LOG_INFO, "cwc", "%s: cryptoworks card", + cwc->cwc_hostname); + break; default: cwc->cwc_card_type = CARD_UNKNOWN; break; @@ -1210,6 +1218,9 @@ cwc_emm(uint8_t *data, int len) case CARD_NDS: cwc_emm_nds(cwc, data, len); break; + case CARD_CRYPTOWORKS: + cwc_emm_cryptoworks(cwc, data, len); + break; case CARD_UNKNOWN: break; } @@ -1654,6 +1665,63 @@ cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len) cwc_send_msg(cwc, data, len, 0, 1); } +void +cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len) +{ + int match = 0; + + switch (data[0]) { + case 0x82: /* unique */ + match = len >= 10 && memcmp(data + 5, cwc->cwc_ua + 3, 5) == 0; + break; + case 0x84: /* emm-sh */ + if (len >= 9 && memcmp(data + 5, cwc->cwc_ua + 3, 4) == 0) { + if (cwc->cwc_cryptoworks_emm.shared_emm) { + free(cwc->cwc_cryptoworks_emm.shared_emm); + cwc->cwc_cryptoworks_emm.shared_len = 0; + cwc->cwc_cryptoworks_emm.shared_emm = (uint8_t *)malloc(len); + } + cwc->cwc_cryptoworks_emm.shared_emm = malloc(len); + if (cwc->cwc_cryptoworks_emm.shared_emm) { + cwc->cwc_cryptoworks_emm.shared_len = len; + memcpy(cwc->cwc_cryptoworks_emm.shared_emm, data, len); + } + } + break; + case 0x86: /* emm-sb */ + if (cwc->cwc_cryptoworks_emm.shared_emm) { + /* python: EMM_SH[0:12] + EMM_SB[5:-1] + EMM_SH[12:-1] */ + uint32_t elen = len - 5 + cwc->cwc_cryptoworks_emm.shared_len - 12; + uint8_t *tmp = malloc(elen); + uint8_t *composed = tmp ? malloc(elen + 12) : NULL; + if (composed) { + memcpy(tmp, data + 5, len - 5); + memcpy(tmp + len - 5, cwc->cwc_cryptoworks_emm.shared_emm + 12, + cwc->cwc_cryptoworks_emm.shared_len - 12); + memcpy(composed, cwc->cwc_cryptoworks_emm.shared_emm, 12); + sort_nanos(composed + 12, tmp, elen); + composed[1] = ((elen + 9) >> 8) | 0x70; + composed[2] = (elen + 9) & 0xff; + cwc_send_msg(cwc, composed, elen + 12, 0, 1); + free(composed); + free(tmp); + } + cwc->cwc_cryptoworks_emm.shared_emm = NULL; + cwc->cwc_cryptoworks_emm.shared_len = 0; + } + break; + case 0x88: /* global */ + case 0x89: /* global */ + match = 1; + break; + default: + break; + } + + if (match) + cwc_send_msg(cwc, data, len, 0, 1); +} + /** * */ diff --git a/src/psi.c b/src/psi.c index 116e0014..9dee140e 100644 --- a/src/psi.c +++ b/src/psi.c @@ -836,13 +836,23 @@ static struct strtab caidnametab[] = { { "Irdeto", 0x0600 }, { "Irdeto", 0x0602 }, { "Irdeto", 0x0604 }, + { "Irdeto", 0x0624 }, + { "Irdeto", 0x0666 }, { "Jerroldgi", 0x0700 }, { "Matra", 0x0800 }, { "NDS", 0x0900 }, { "Nokia", 0x0A00 }, { "Conax", 0x0B00 }, { "NTL", 0x0C00 }, - { "CryptoWorks", 0x0D00 }, + { "CryptoWorks", 0x0D00 }, + { "CryptoWorks", 0x0D01 }, + { "CryptoWorks", 0x0D02 }, + { "CryptoWorks", 0x0D03 }, + { "CryptoWorks", 0x0D05 }, + { "CryptoWorks", 0x0D0F }, + { "CryptoWorks", 0x0D70 }, + { "CryptoWorks ICE", 0x0D96 }, + { "CryptoWorks ICE", 0x0D97 }, { "PowerVu", 0x0E00 }, { "Sony", 0x0F00 }, { "Tandberg", 0x1000 },