SASC-NG
DVBSoftCAM

cSystemIrd2 Class Reference

Inheritance diagram for cSystemIrd2:

List of all members.

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)

Detailed Description

Definition at line 119 of file irdeto2.c.


Constructor & Destructor Documentation

cSystemIrd2::cSystemIrd2 ( void  )

Definition at line 129 of file irdeto2.c.

References cSystem::hasLogger.


Member Function Documentation

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;
}
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);
    }
}

The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines