SASC-NG
DVBSoftCAM

cSystemViaccess Class Reference

Inheritance diagram for cSystemViaccess:

List of all members.

Public Member Functions

 cSystemViaccess (void)
virtual bool ProcessECM (const cEcmInfo *ecm, unsigned char *data)
virtual void ProcessEMM (int pid, int caid, const unsigned char *data)
virtual void ParseCADescriptor (cSimpleList< cEcmInfo > *ecms, unsigned short sysId, int source, const unsigned char *data, int len)

Detailed Description

Definition at line 353 of file viaccess.c.


Constructor & Destructor Documentation

cSystemViaccess::cSystemViaccess ( void  )

Definition at line 363 of file viaccess.c.

References cSystem::hasLogger.


Member Function Documentation

void cSystemViaccess::ParseCADescriptor ( cSimpleList< cEcmInfo > *  ecms,
unsigned short  sysId,
int  source,
const unsigned char *  data,
int  len 
) [virtual]

Reimplemented from cSystem.

Definition at line 369 of file viaccess.c.

References L_CORE_ECMPROC, PRINTF, and WORD.

{
  const int pid=WORD(data,2,0x1FFF);
  if(pid>=0xAA && pid<=0xCF) {
    PRINTF(L_CORE_ECMPROC,"viaccess: dropped \"fake\" ecm pid 0x%04x",pid);
    return;
    }
  cSystem::ParseCADescriptor(ecms,sysId,source,data,len);
}
bool cSystemViaccess::ProcessECM ( const cEcmInfo *  ecm,
unsigned char *  data 
) [virtual]

Implements cSystem.

Definition at line 379 of file viaccess.c.

References cParseViaccess::CheckNano90FromNano(), cSystem::cw, data, cViaccess::Decrypt(), cTPS::Decrypt(), cPlainKeys::FindKey(), cPlainKey::Get(), cParseViaccess::KeyNrFromNano(), keys, cSystem::maxEcmTry, cKeySnoop::OK(), cParseViaccess::PayloadStart(), cTPS::PostProc(), cEcmInfo::provId, SCT_LEN, cViaccess::SetV2Mode(), cPlainKey::Size(), cEcmInfo::source, cEcmInfo::transponder, VIA1_KEYLEN, and VIA2_KEYLEN.

{
  unsigned char *nanos=(unsigned char *)cParseViaccess::PayloadStart(data);
  int len=SCT_LEN(data)-(nanos-data);

  bool mayHaveTps=false;
  if(ecm->provId==0x007c00) { // TPS
    maxEcmTry=4;
    mayHaveTps=true;
    int num=tps.Decrypt(this,ecm->source,ecm->transponder,nanos,len);
    if(num<0) return false;
    nanos+=num; len-=num;
    }

  if(cParseViaccess::CheckNano90FromNano(nanos)) {
    int keynr=cParseViaccess::KeyNrFromNano(nanos);
    cKeySnoop ks(this,'V',ecm->provId,keynr);
    cPlainKey *pk=0;
    while((pk=keys.FindKey('V',ecm->provId,keynr,-1,pk))) {
      unsigned char key[16];
      if(pk->Size()<=(int)sizeof(key)) {
        pk->Get(key);
        SetV2Mode(pk->Size()==VIA2_KEYLEN ? &key[VIA1_KEYLEN] : 0);
        if(cViaccess::Decrypt(key,&nanos[5],len-5,&cw[0],&cw[8])) {
          if(mayHaveTps) tps.PostProc(cw);
          ks.OK(pk);
          return true;
          }
        }
      }
    }
  return false;
}
void cSystemViaccess::ProcessEMM ( int  pid,
int  caid,
const unsigned char *  data 
) [virtual]

Reimplemented from cSystem.

Definition at line 413 of file viaccess.c.

References cAssembleData::Assembled(), b, cViaccess::Decode(), cStructList< T >::First(), cSystem::FoundKey(), cViaccess::Hash(), cViaccess::HashByte(), cViaccess::HashClear(), cViaccess::hbuff, HexStr(), k7, cParseViaccess::KeyNrFromNano(), keys, L_SYS_EMM, MAX_NEW_KEYS, cParseViaccess::NanoStart(), cSystem::NewKey(), cPlainKeys::NewKey(), cStructList< T >::Next(), cViaccess::pH, PRINTF, SCT_LEN, and cViaccess::SetHashKey().

{
  for(cViaccessCardInfo *mkey=Vcards.First(); mkey; mkey=Vcards.Next(mkey)) {
    int updtype;
    cAssembleData ad(data);
    if(mkey->cCardViaccess::MatchEMM(data)) {
      updtype=3;
      HashClear();
      memcpy(hbuff+3,mkey->ua,sizeof(mkey->ua));
      }
    else if(mkey->cProviderViaccess::MatchEMM(data)) {
      if(mkey->cProviderViaccess::Assemble(&ad)<0) continue;
      updtype=2;
      HashClear();
      memcpy(hbuff+5,mkey->sa,sizeof(mkey->sa)-1);
      }
    else continue;

    const unsigned char *buff;
    if((buff=ad.Assembled())) {
      const unsigned char *scan=cParseViaccess::NanoStart(buff);
      unsigned int scanlen=SCT_LEN(buff)-(scan-buff);

      if(scanlen>=5 && mkey->cProviderViaccess::MatchID(buff) &&
         cParseViaccess::KeyNrFromNano(scan)==mkey->keyno) {
        scan+=5; scanlen-=5;
        SetHashKey(mkey->key);
        Hash();

        unsigned int n;
        if(scan[0]==0x9e && scanlen>=(n=scan[1]+2)) {
          for(unsigned int i=0; i<n; i++) HashByte(scan[i]);
          Hash(); pH=0;
          scan+=n; scanlen-=5;
          }
        if(scanlen>0) {
          unsigned char newKey[MAX_NEW_KEYS][8];
          int numKeys=0, updPrv[MAX_NEW_KEYS]={}, updKey[MAX_NEW_KEYS]={};

          for(unsigned int cnt=0; cnt<scanlen && numKeys<MAX_NEW_KEYS;) {
            const unsigned int parm=scan[cnt++];
            unsigned int plen=scan[cnt++];

            switch(parm) {
              case 0x90:
              case 0x9E:
                cnt+=plen;
                break;
              case 0xA1: // keyupdate
                updPrv[numKeys]=(scan[cnt]<<16)+(scan[cnt+1]<<8)+(scan[cnt+2]&0xF0);
                updKey[numKeys]=scan[cnt+2]&0x0F;
                // fall through
              default:
                HashByte(parm); HashByte(plen);
                while(plen--) HashByte(scan[cnt++]);
                break;
              case 0xEF: // crypted key(s)
                HashByte(parm); HashByte(plen);
                if(plen==sizeof(newKey[0])) {
                  const unsigned char k7=mkey->key[7];
                  for(unsigned int kc=0 ; kc<sizeof(newKey[0]) ; kc++) {
                    const unsigned char b=scan[cnt++];
                    if(k7&1) newKey[numKeys][kc]=b^(hbuff[pH]&(k7<0x10 ? 0x5a : 0xa5));
                    else     newKey[numKeys][kc]=b;
                    HashByte(b);
                    }
                  numKeys++;
                  }
                else {
                  PRINTF(L_SYS_EMM,"key length mismatch %d!=%d",plen,(int)sizeof(newKey[0]));
                  cnt=scanlen;
                  }
                break;
              case 0xF0: // signature
                {
                char str[20], str2[20];
                static const char *ptext[] = { 0,0,"SHARED","UNIQUE" };
                const char *addr = (updtype==2) ? HexStr(str,mkey->sa,sizeof(mkey->sa)) : HexStr(str,mkey->ua,sizeof(mkey->ua));

                Hash();
                if(!memcmp(&scan[cnt],hbuff,sizeof(hbuff))) {
                  unsigned char key[8];
                  memcpy(key,mkey->key,sizeof(key));
                  if(key[7]) { // Rotate key
                    const unsigned char t1=key[0], t2=key[1];
                    key[0]=key[2]; key[1]=key[3]; key[2]=key[4]; key[3]=key[5]; key[4]=key[6];
                    key[5]=t1; key[6]=t2;
                    }

                  while(numKeys--) {
                    Decode(newKey[numKeys],key);
                    PRINTF(L_SYS_EMM,"%02X%02X %02X %s %s - KEY %06X.%02X -> %s",
                        mkey->ident[0],mkey->ident[1],mkey->keyno,addr,
                        ptext[updtype],updPrv[numKeys],updKey[numKeys],
                        HexStr(str2,newKey[numKeys],sizeof(newKey[numKeys])));
                    FoundKey();
                    if(keys.NewKey('V',updPrv[numKeys],updKey[numKeys],newKey[numKeys],8)) NewKey();
                    }
                  }
                else
                  PRINTF(L_SYS_EMM,"%02X%02X %02X %s %s - FAIL",mkey->ident[0],mkey->ident[1],mkey->keyno,addr,ptext[updtype]);
                cnt=scanlen;
                break;
                }
              }
            }
          }
        }
      }
    }
}

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