|
SASC
DVBSoftCAM
|
Inheritance diagram for cSystemIrd2:Public Member Functions | |
| cSystemIrd2 (void) | |
| virtual bool | ProcessECM (const cEcmInfo *ecm, unsigned char *data) |
| virtual void | ProcessEMM (int pid, int caid, const unsigned char *data) |
| cSystemIrd2 (void) | |
| virtual bool | ProcessECM (const cEcmInfo *ecm, unsigned char *data) |
| virtual void | ProcessEMM (int pid, int caid, const unsigned char *data) |
| cSystemIrd2::cSystemIrd2 | ( | void | ) |
Definition at line 129 of file irdeto2.c.
References cSystem::hasLogger.
:cSystem(SYSTEM_NAME2,SYSTEM_PRI2) { hasLogger=true; }
| cSystemIrd2::cSystemIrd2 | ( | void | ) |
| bool cSystemIrd2::ProcessECM | ( | const cEcmInfo * | ecm, |
| unsigned char * | data | ||
| ) | [virtual] |
Implements cSystem.
Definition at line 155 of file irdeto2.c.
References cEcmInfo::caId, cIrdeto2::CalculateHash(), cSystem::cw, cIrdeto2::Decrypt(), cSystem::doLog, cPlainKeys::FindKey(), cPlainKey::Get(), HEXDUMP, keys, KEYSET, L_SYS_ECM, L_SYS_KEY, L_SYS_RAWECM, NANOLEN, cKeySnoop::OK(), PRINTF, prov, SCT_LEN, TYPE_IV, TYPE_OP, and TYPE_SEED.
{
int len=data[11];
if(len!=0x28 || SCT_LEN(data)<len+12) {
if(doLog) PRINTF(L_SYS_ECM,"bad ECM length");
return false;
}
int prov=data[8];
cPlainKey *pk;
unsigned char ECM_IV[16];
if(!(pk=keys.FindKey('I',ecm->caId,KEYSET(prov,TYPE_IV,0),16))) {
if(doLog) PRINTF(L_SYS_KEY,"missing %04x %02x IV key",ecm->caId,prov);
return false;
}
pk->Get(ECM_IV);
unsigned char ECM_Seed[16];
if(!(pk=keys.FindKey('I',ecm->caId,KEYSET(prov,TYPE_SEED,0),16))) {
if(doLog) PRINTF(L_SYS_KEY,"missing %04x %02x ECM key",ecm->caId,prov);
return false;
}
pk->Get(ECM_Seed);
cKeySnoop ks(this,'I',ecm->caId,KEYSET(prov,TYPE_OP,data[9]));
unsigned char key[16];
if(!(pk=keys.FindKey('I',ecm->caId,KEYSET(prov,TYPE_OP,data[9]),16))) return false;
pk->Get(key);
PrepareSeed(ECM_Seed,key);
data+=12;
Decrypt(data,ECM_IV,ECM_Seed,len);
int i=(data[0]&7)+1;
NanoDecrypt(data,i,len-8,key,ECM_IV);
if(CalculateHash(ECM_Seed,ECM_IV,data-6,len+6)) {
HEXDUMP(L_SYS_RAWECM,data-12,len+12,"Irdeto2 RAWECM");
while(i<len-8) {
int l=NANOLEN(data[i+1]);
switch(data[i]) {
case 0x78:
memcpy(cw,&data[i+4],16);
ks.OK(pk);
return true;
}
i+=l;
}
}
else {
if(doLog) PRINTF(L_SYS_ECM,"hash failed");
}
return false;
}
| virtual bool cSystemIrd2::ProcessECM | ( | const cEcmInfo * | ecm, |
| unsigned char * | data | ||
| ) | [virtual] |
Implements cSystem.
| virtual void cSystemIrd2::ProcessEMM | ( | int | pid, |
| int | caid, | ||
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cSystem.
| void cSystemIrd2::ProcessEMM | ( | int | pid, |
| int | caid, | ||
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cSystem.
Definition at line 207 of file irdeto2.c.
References AUTOMEM, cIrdeto2::CalculateHash(), cIrdeto2::Decrypt(), cPlainKeys::FindKey(), cSystem::FoundKey(), cPlainKey::Get(), HEXDUMP, keys, KEYSET, L_SYS_EMM, L_SYS_RAWEMM, NANOLEN, cSystem::NewKey(), cPlainKeys::NewKey(), PRINTF, prov, SCT_LEN, TYPE_IV, TYPE_OP, TYPE_PMK, and TYPE_SEED.
{
int prov=0; //XXX how to get provider here??
int len=SCT_LEN(data);
unsigned char *emm=AUTOMEM(len);
cPlainKey *pk;
if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_IV,0),16))) {
PRINTF(L_SYS_EMM,"missing %04x %02x IV key",caid,prov);
return;
}
unsigned char EMM_IV[16];
pk->Get(EMM_IV);
for(int keyno=0; keyno<2; keyno++) {
if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_PMK,keyno),16))) {
PRINTF(L_SYS_EMM,"missing %04x %02x MK%d key",caid,prov,keyno);
continue;
}
unsigned char PMK[16];
pk->Get(PMK);
if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_SEED,1),16))) {
PRINTF(L_SYS_EMM,"missing %04x %02x EMM key",caid,prov);
return;
}
unsigned char EMM_Seed[16];
pk->Get(EMM_Seed);
PrepareSeed(EMM_Seed,PMK);
memcpy(emm,data,len);
Decrypt(&emm[10],EMM_IV,EMM_Seed,len-10);
NanoDecrypt(emm,16,len-8,PMK,EMM_IV);
memmove(emm+6,emm+7,len-7); // removing padding byte
if(CalculateHash(EMM_Seed,EMM_IV,emm+3,len-4)) {
HEXDUMP(L_SYS_RAWEMM,emm,len,"Irdeto2 RAWEMM");
for(int i=15; i<len-9;) {
int l=NANOLEN(emm[i+1]);
switch(emm[i]) {
case 0x10:
case 0x50:
if(l==0x13 && i+l<=len-9) {
FoundKey();
if(keys.NewKey('I',caid,KEYSET(prov,TYPE_OP,emm[i+2]>>2),&emm[i+3],16)) NewKey();
}
break;
}
i+=l;
}
break;
}
else
PRINTF(L_SYS_EMM,"hash failed MK%d",keyno);
}
}