Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
capmt: add the preliminary AES support
  • Loading branch information
perexg committed Aug 7, 2014
1 parent 6c8908c commit d1c62ee
Showing 1 changed file with 51 additions and 20 deletions.
71 changes: 51 additions & 20 deletions src/descrambler/capmt.c
Expand Up @@ -72,22 +72,24 @@ typedef struct dmx_filter {
uint8_t mode[DMX_FILTER_SIZE];
} dmx_filter_t;

#define CA_SET_DESCR 0x40106f86
#define CA_SET_DESCR_X 0x866f1040
#define CA_SET_PID 0x40086f87
#define CA_SET_PID_X 0x876f0840
#define DMX_STOP 0x00006f2a
#define DMX_STOP_X 0x2a6f0000
#define DMX_SET_FILTER 0x403c6f2b
#define DMX_SET_FILTER_X 0x2b6f3c40
#define CA_SET_DESCR 0x40106f86
#define CA_SET_DESCR_X 0x866f1040
#define CA_SET_DESCR_AES 0x40106f87
#define CA_SET_DESCR_AES_X 0x876f1040
#define CA_SET_PID 0x40086f87
#define CA_SET_PID_X 0x876f0840
#define DMX_STOP 0x00006f2a
#define DMX_STOP_X 0x2a6f0000
#define DMX_SET_FILTER 0x403c6f2b
#define DMX_SET_FILTER_X 0x2b6f3c40

// ca_pmt_list_management values:
#define CAPMT_LIST_MORE 0x00 // append a 'MORE' CAPMT object the list and start receiving the next object
#define CAPMT_LIST_FIRST 0x01 // clear the list when a 'FIRST' CAPMT object is received, and start receiving the next object
#define CAPMT_LIST_LAST 0x02 // append a 'LAST' CAPMT object to the list and start working with the list
#define CAPMT_LIST_ONLY 0x03 // clear the list when an 'ONLY' CAPMT object is received, and start working with the object
#define CAPMT_LIST_ADD 0x04 // append an 'ADD' CAPMT object to the current list and start working with the updated list
#define CAPMT_LIST_UPDATE 0x05 // replace an entry in the list with an 'UPDATE' CAPMT object, and start working with the updated list
#define CAPMT_LIST_MORE 0x00 // append a 'MORE' CAPMT object the list and start receiving the next object
#define CAPMT_LIST_FIRST 0x01 // clear the list when a 'FIRST' CAPMT object is received, and start receiving the next object
#define CAPMT_LIST_LAST 0x02 // append a 'LAST' CAPMT object to the list and start working with the list
#define CAPMT_LIST_ONLY 0x03 // clear the list when an 'ONLY' CAPMT object is received, and start working with the object
#define CAPMT_LIST_ADD 0x04 // append an 'ADD' CAPMT object to the current list and start working with the updated list
#define CAPMT_LIST_UPDATE 0x05 // replace an entry in the list with an 'UPDATE' CAPMT object, and start working with the updated list

// ca_pmt_cmd_id values:
#define CAPMT_CMD_OK_DESCRAMBLING 0x01 // start descrambling the service in this CAPMT object as soon as the list of CAPMT objects is complete
Expand Down Expand Up @@ -947,7 +949,7 @@ capmt_ecm_reset(th_descrambler_t *th)

static void
capmt_process_key(capmt_t *capmt, uint8_t adapter, uint16_t seq,
const uint8_t *even, const uint8_t *odd,
int type, const uint8_t *even, const uint8_t *odd,
int ok)
{
mpegts_service_t *t;
Expand All @@ -972,7 +974,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, DESCRAMBLER_DES, even, odd);
descrambler_keys((th_descrambler_t *)ct, type, even, odd);
}
pthread_mutex_unlock(&capmt->capmt_mutex);
}
Expand All @@ -989,6 +991,7 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset)
if (!sb->sb_bswap && !sb->sb_err) {
if (cmd == CA_SET_PID_X ||
cmd == CA_SET_DESCR_X ||
cmd == CA_SET_DESCR_AES_X ||
cmd == DMX_SET_FILTER_X ||
cmd == DMX_STOP_X) {
sb->sb_bswap = 1;
Expand All @@ -1000,6 +1003,8 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset)
return 4 + 8;
else if (cmd == CA_SET_DESCR)
return 4 + 16;
else if (cmd == CA_SET_DESCR_AES)
return 4 + 32;
else if (oscam_new && cmd == DMX_SET_FILTER)
return 4 + 2 + 60;
else if (oscam_new && cmd == DMX_STOP)
Expand All @@ -1013,6 +1018,7 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset)
static void
capmt_analyze_cmd(capmt_t *capmt, int adapter, sbuf_t *sb, int offset)
{
static uint8_t empty[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint32_t cmd;

cmd = sbuf_peek_u32(sb, offset);
Expand Down Expand Up @@ -1041,25 +1047,49 @@ capmt_analyze_cmd(capmt_t *capmt, int adapter, sbuf_t *sb, int offset)

} else if (cmd == CA_SET_DESCR) {

static uint8_t empty[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int32_t index = sbuf_peek_s32(sb, offset + 4);
int32_t parity = sbuf_peek_s32(sb, offset + 8);
uint8_t *cw = sbuf_peek (sb, offset + 12);
ca_info_t *cai;

tvhlog(LOG_DEBUG, "capmt", "CA_SET_DESCR adapter %d par %d idx %d %02x%02x%02x%02x%02x%02x%02x%02x", adapter, parity, index, cw[0], cw[1], cw[2], cw[3], cw[4], cw[5], cw[6], cw[7]);
tvhlog(LOG_DEBUG, "capmt", "CA_SET_DESCR adapter %d par %d idx %d %02x%02x%02x%02x%02x%02x%02x%02x",
adapter, parity, index, cw[0], cw[1], cw[2], cw[3], cw[4], cw[5], cw[6], cw[7]);
if (index == -1) // skipping removal request
return;
if (adapter >= MAX_CA || index >= MAX_INDEX)
return;
cai = &capmt->capmt_adapters[adapter].ca_info[index];
if (parity == 0) {
capmt_process_key(capmt, adapter, cai->seq, cw, empty, 1);
capmt_process_key(capmt, adapter, cai->seq, DESCRAMBLER_DES, cw, empty, 1);
} else if (parity == 1) {
capmt_process_key(capmt, adapter, cai->seq, empty, cw, 1);
capmt_process_key(capmt, adapter, cai->seq, DESCRAMBLER_DES, empty, cw, 1);
} else
tvhlog(LOG_ERR, "capmt", "Invalid parity %d in CA_SET_DESCR for adapter%d", parity, adapter);

} else if (cmd == CA_SET_DESCR_AES) {

int32_t index = sbuf_peek_s32(sb, offset + 4);
int32_t parity = sbuf_peek_s32(sb, offset + 8);
uint8_t *cw = sbuf_peek (sb, offset + 12);
ca_info_t *cai;

tvhlog(LOG_DEBUG, "capmt", "CA_SET_DESCR_AES adapter %d par %d idx %d "
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
adapter, parity, index,
cw[0], cw[1], cw[2], cw[3], cw[4], cw[5], cw[6], cw[7],
cw[8], cw[9], cw[10], cw[11], cw[12], cw[13], cw[14], cw[15]);
if (index == -1) // skipping removal request
return;
if (adapter >= MAX_CA || index >= MAX_INDEX)
return;
cai = &capmt->capmt_adapters[adapter].ca_info[index];
if (parity == 0) {
capmt_process_key(capmt, adapter, cai->seq, DESCRAMBLER_AES, cw, empty, 1);
} else if (parity == 1) {
capmt_process_key(capmt, adapter, cai->seq, DESCRAMBLER_AES, empty, cw, 1);
} else
tvhlog(LOG_ERR, "capmt", "Invalid parity %d in CA_SET_DESCR_AES for adapter%d", parity, adapter);

} else if (cmd == DMX_SET_FILTER) {

capmt_set_filter(capmt, adapter, sb, offset);
Expand Down Expand Up @@ -1317,6 +1347,7 @@ handle_ca0_wrapper(capmt_t *capmt)

capmt_process_key(capmt, 0,
buffer[0] | ((uint16_t)buffer[1] << 8),
DESCRAMBLER_DES,
buffer + 2, buffer + 10,
ret == 18);
}
Expand Down

4 comments on commit d1c62ee

@piotrasd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for what is support AES ? maybe for use Intel AES-IN in CPU ?

@mielleman
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some CAM implementations (mostly IPTV based) use AES keys instead of DES3.

@piotrasd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh ok thanks, for accelerate this could we use AES-IN instruction in CPU ? almost all new AMD and Intel have this

@perexg
Copy link
Contributor Author

@perexg perexg commented on d1c62ee Aug 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The descrambler uses openssl libraries, so I guess, that this instruction is used on modern CPUs.

Please sign in to comment.