Skip to content
This repository has been archived by the owner on Apr 14, 2024. It is now read-only.

Commit

Permalink
[omnicrypt] Add ecm support (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
nautilus7 authored Apr 3, 2024
1 parent 6550776 commit b2a8ce7
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 7 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ SRC-$(CONFIG_WITH_EMU) += module-emulator-cryptoworks.c
SRC-$(CONFIG_WITH_EMU) += module-emulator-director.c
SRC-$(CONFIG_WITH_EMU) += module-emulator-irdeto.c
SRC-$(CONFIG_WITH_EMU) += module-emulator-nagravision.c
SRC-$(CONFIG_WITH_EMU) += module-emulator-omnicrypt.c
SRC-$(CONFIG_WITH_EMU) += module-emulator-powervu.c
SRC-$(CONFIG_WITH_EMU) += module-emulator-viaccess.c
ifeq "$(CONFIG_WITH_EMU)" "y"
Expand Down
72 changes: 72 additions & 0 deletions module-emulator-omnicrypt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#define MODULE_LOG_PREFIX "emu"

#include "globals.h"

#ifdef WITH_EMU

#include "module-emulator-osemu.h"
#include "module-emulator-omnicrypt.h"
#include "oscam-aes.h"
#include "oscam-string.h"


static inline int8_t get_ecm_key(uint16_t provider, uint8_t parity, uint8_t *key)
{
return emu_find_key('O', provider, 0, parity == 0 ? "00" : "01", key, 16, 1, 0, 0, NULL);
}

int8_t omnicrypt_ecm(uint8_t *ecm, uint8_t *dw)
{
uint8_t section_syntax_indicator, session_key[16], session_key_parity, position;
uint16_t private_section_length, session_key_id, payload_length;
struct aes_keys aes;

section_syntax_indicator = ecm[1] >> 7;
if (section_syntax_indicator != 0) // The private_data_bytes immediately follow the private_section_length field
{
cs_log("ECM section syntax indicator %d not supported", section_syntax_indicator);
return EMU_NOT_SUPPORTED;
}

private_section_length = b2i(2, ecm + 1) & 0x0FFF;
if (private_section_length != 0x2D)
{
cs_log("ECM has an unsupported private section length of %d", private_section_length);
return EMU_NOT_SUPPORTED;
}

session_key_parity = ecm[3] & 0x01;
session_key_id = b2i(2, ecm + 4);

if (!get_ecm_key(session_key_id, session_key_parity, session_key))
{
return EMU_KEY_NOT_FOUND;
}
aes_set_key(&aes, (char *)session_key);

payload_length = b2i(2, ecm + 6) & 0x0FFF;
if (payload_length != 0x28)
{
cs_log("ECM has an unsupported payload length of %d", payload_length);
return EMU_NOT_SUPPORTED;
}

for (position = 8; position + 1 < payload_length; position += 4 + 16) // Run twice for odd, even CW
{
uint8_t parity = ecm[position + 1] & 0x01;
uint8_t length = ecm[position + 3];

if (length != 16)
{
cs_log("CW %d has an unsupported length of %d", parity, length);
return EMU_NOT_SUPPORTED;
}

aes_decrypt(&aes, ecm + position + 4, 16);
memcpy(dw + parity * 8, ecm + position + 4, 8); // Copy the first 8 bytes (rest are zeros)
}

return EMU_OK;
}

#endif // WITH_EMU
10 changes: 10 additions & 0 deletions module-emulator-omnicrypt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef MODULE_EMULATOR_OMNICRYPT_H
#define MODULE_EMULATOR_OMNICRYPT_H

#ifdef WITH_EMU

int8_t omnicrypt_ecm(uint8_t *ecm, uint8_t *dw);

#endif // WITH_EMU

#endif // MODULE_EMULATOR_OMNICRYPT_H
15 changes: 11 additions & 4 deletions module-emulator-osemu.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "module-emulator-director.h"
#include "module-emulator-irdeto.h"
#include "module-emulator-nagravision.h"
#include "module-emulator-omnicrypt.h"
#include "module-emulator-powervu.h"
#include "module-emulator-viaccess.h"

Expand Down Expand Up @@ -127,6 +128,7 @@ KeyDataContainer NagraKeys = { NULL, 0, 0 };
KeyDataContainer IrdetoKeys = { NULL, 0, 0 };
KeyDataContainer BissSWs = { NULL, 0, 0 };
KeyDataContainer Biss2Keys = { NULL, 0, 0 };
KeyDataContainer OmnicryptKeys = { NULL, 0, 0 };
KeyDataContainer PowervuKeys = { NULL, 0, 0 };
KeyDataContainer TandbergKeys = { NULL, 0, 0 };
KeyDataContainer StreamKeys = { NULL, 0, 0 };
Expand All @@ -147,6 +149,8 @@ KeyDataContainer *emu_get_key_container(char identifier)
return &BissSWs;
case 'G':
return &Biss2Keys;
case 'O':
return &OmnicryptKeys;
case 'P':
return &PowervuKeys;
case 'T':
Expand Down Expand Up @@ -664,15 +668,16 @@ void emu_clear_keydata(void)
total += IrdetoKeys.keyCount;
total += BissSWs.keyCount;
total += Biss2Keys.keyCount;
total += OmnicryptKeys.keyCount;
total += PowervuKeys.keyCount;
total += TandbergKeys.keyCount;
total += StreamKeys.keyCount;

if (total != 0)
{
cs_log("Freeing keys in memory: W:%d V:%d N:%d I:%d F:%d G:%d P:%d T:%d A:%d",
CwKeys.keyCount, ViKeys.keyCount, NagraKeys.keyCount, IrdetoKeys.keyCount,
BissSWs.keyCount, Biss2Keys.keyCount, PowervuKeys.keyCount, TandbergKeys.keyCount,
cs_log("Freeing keys in memory: W:%d V:%d N:%d I:%d F:%d G:%d O:%d P:%d T:%d A:%d",
CwKeys.keyCount, ViKeys.keyCount, NagraKeys.keyCount, IrdetoKeys.keyCount, BissSWs.keyCount,
Biss2Keys.keyCount, OmnicryptKeys.keyCount, PowervuKeys.keyCount, TandbergKeys.keyCount,
StreamKeys.keyCount);

delete_keys_in_container('W');
Expand All @@ -681,6 +686,7 @@ void emu_clear_keydata(void)
delete_keys_in_container('I');
delete_keys_in_container('F');
delete_keys_in_container('G');
delete_keys_in_container('O');
delete_keys_in_container('P');
delete_keys_in_container('T');
delete_keys_in_container('A');
Expand Down Expand Up @@ -926,7 +932,7 @@ int8_t emu_process_ecm(struct s_reader *rdr, const ECM_REQUEST *er, uint8_t *cw,

memcpy(ecmCopy, er->ecm, ecmLen);

if (caid_is_viaccess(er->caid)) result = viaccess_ecm(ecmCopy, cw);
if (caid_is_viaccess(er->caid)) result = viaccess_ecm(ecmCopy, cw);
else if (caid_is_irdeto(er->caid)) result = irdeto2_ecm(er->caid, ecmCopy, cw);
else if (caid_is_cryptoworks(er->caid)) result = cryptoworks_ecm(er->caid, ecmCopy, cw);
else if (caid_is_powervu(er->caid))
Expand All @@ -940,6 +946,7 @@ int8_t emu_process_ecm(struct s_reader *rdr, const ECM_REQUEST *er, uint8_t *cw,
else if (caid_is_director(er->caid)) result = director_ecm(ecmCopy, cw);
else if (caid_is_nagra(er->caid)) result = nagra2_ecm(ecmCopy, cw);
else if (caid_is_biss(er->caid)) result = biss_ecm(rdr, er->ecm, er->caid, er->pid, cw, cw_ex);
else if (er->caid == 0x00FF) result = omnicrypt_ecm(ecmCopy, cw); // temp caid

if (result != 0)
{
Expand Down
1 change: 1 addition & 0 deletions module-emulator-osemu.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ extern KeyDataContainer NagraKeys;
extern KeyDataContainer IrdetoKeys;
extern KeyDataContainer BissSWs; // 'F' identifier - BISS1 and BISS2 mode 1/E session words
extern KeyDataContainer Biss2Keys; // 'G' identifier - BISS2 mode CA session keys (ECM keys)
extern KeyDataContainer OmnicryptKeys;
extern KeyDataContainer PowervuKeys;
extern KeyDataContainer TandbergKeys;
extern KeyDataContainer StreamKeys;
Expand Down
12 changes: 9 additions & 3 deletions module-emulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ static void refresh_entitlements(struct s_reader *rdr)
{
emu_add_entitlement(rdr, 0x2610, 0, item->ekid, "RSAPRI", 8, 0);
}

for (i = 0; i < OmnicryptKeys.keyCount; i++)
{
emu_add_entitlement(rdr, 0x00FF, OmnicryptKeys.EmuKeys[i].provider, OmnicryptKeys.EmuKeys[i].key,
OmnicryptKeys.EmuKeys[i].keyName, OmnicryptKeys.EmuKeys[i].keyLength, 0);
}
}

static int32_t emu_do_ecm(struct s_reader *rdr, const ECM_REQUEST *er, struct s_ecm_answer *ea)
Expand Down Expand Up @@ -247,9 +253,9 @@ static int32_t emu_card_info(struct s_reader *rdr)
// Read BISS2 mode CA RSA keys from PEM files
biss_read_pem(rdr, BISS2_MAX_RSA_KEYS);

cs_log("Total keys in memory: W:%d V:%d N:%d I:%d F:%d G:%d P:%d T:%d A:%d",
CwKeys.keyCount, ViKeys.keyCount, NagraKeys.keyCount, IrdetoKeys.keyCount,
BissSWs.keyCount, Biss2Keys.keyCount, PowervuKeys.keyCount, TandbergKeys.keyCount,
cs_log("Total keys in memory: W:%d V:%d N:%d I:%d F:%d G:%d O:%d P:%d T:%d A:%d",
CwKeys.keyCount, ViKeys.keyCount, NagraKeys.keyCount, IrdetoKeys.keyCount, BissSWs.keyCount,
Biss2Keys.keyCount, OmnicryptKeys.keyCount, PowervuKeys.keyCount, TandbergKeys.keyCount,
StreamKeys.keyCount);

// Inform OSCam about all available keys.
Expand Down

0 comments on commit b2a8ce7

Please sign in to comment.