⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viaccess.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
bool cViaccess::Decrypt(const unsigned char *work_key, const unsigned char *data, int len, unsigned char *des_data1, unsigned char *des_data2){  int pos=0, encStart=0;  unsigned char signatur[8];  while(pos<len) {    switch(data[pos]) {      case 0xea:                 // encrypted bytes        encStart = pos + 2;        memcpy(des_data1,&data[pos+2],8);        memcpy(des_data2,&data[pos+2+8],8);        break;      case 0xf0:                 // signature        memcpy(signatur,&data[pos+2],8);        break;      }    pos += data[pos+1]+2;    }  HashClear();  SetHashKey(work_key);  // key preparation  unsigned char prepared_key[8];  if(work_key[7]==0) {    // 8th key-byte = 0 then like Eurocrypt-M but with viaccess mods    HashNanos(data,encStart+16);    memcpy(prepared_key,work_key,sizeof(prepared_key));    }  else { // key8 not zero    // rotate the key 2x left    prepared_key[0]=work_key[2];    prepared_key[1]=work_key[3];    prepared_key[2]=work_key[4];    prepared_key[3]=work_key[5];    prepared_key[4]=work_key[6];    prepared_key[5]=work_key[0];    prepared_key[6]=work_key[1];    prepared_key[7]=work_key[7];    // test if key8 odd    if(work_key[7]&1) {      HashNanos(data,encStart);      // test if low nibble zero      unsigned char k = ((work_key[7] & 0xf0) == 0) ? 0x5a : 0xa5;      for(int i=0; i<8; i++) {        unsigned char tmp=des_data1[i];        des_data1[i]=(k & hbuff[pH]) ^ tmp;        HashByte(tmp);        }      for(int i=0; i<8; i++) {        unsigned char tmp=des_data2[i];        des_data2[i]=(k & hbuff[pH]) ^ tmp;        HashByte(tmp);        }      }    else {      HashNanos(data,encStart+16);      }    }  Decode(des_data1,prepared_key);  Decode(des_data2,prepared_key);  Hash();  return (memcmp(signatur,hbuff,8)==0);}// -- cSystemViaccess ----------------------------------------------------------#define MAX_NEW_KEYS 5class cSystemViaccess : public cSystem, private cViaccess {private:  cTPS tps;public:  cSystemViaccess(void);  virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *data);  virtual void ProcessEMM(int pid, int caid, unsigned char *data);  virtual void ParseCADescriptor(cSimpleList<cEcmInfo> *ecms, unsigned short sysId, const unsigned char *data, int len);  };cSystemViaccess::cSystemViaccess(void):cSystem(SYSTEM_NAME,SYSTEM_PRI){  hasLogger=true;}void cSystemViaccess::ParseCADescriptor(cSimpleList<cEcmInfo> *ecms, unsigned short sysId, const unsigned char *data, int len){  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,data,len);}bool cSystemViaccess::ProcessECM(const cEcmInfo *ecm, unsigned char *data){  unsigned char *nanos=(unsigned char *)cParseViaccess::NanoStart(data);  int len=SCT_LEN(data)-(nanos-data);  bool mayHaveTps=false;  if(ecm->provId==0x007c00) { // TPS    maxEcmTry=4;    mayHaveTps=true;    int num=tps.Decrypt(CardNum(),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, unsigned char *data){  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,"%d: key length mismatch %d!=%d",CardNum(),plen,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();                    }                  cLoaders::SaveCache();                  }                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;                }              }            }          }        }      }    }}// -- cSystemLinkViaccess ------------------------------------------------------class cSystemLinkViaccess : public cSystemLink {public:  cSystemLinkViaccess(void);  virtual bool CanHandle(unsigned short SysId);  virtual cSystem *Create(void) { return new cSystemViaccess; }  virtual bool Init(const char *cfgdir);  };static cSystemLinkViaccess staticInit;cSystemLinkViaccess::cSystemLinkViaccess(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){  Feature.NeedsKeyFile();}bool cSystemLinkViaccess::CanHandle(unsigned short SysId){  SysId&=SYSTEM_MASK;  return SYSTEM_CAN_HANDLE(SysId);}bool cSystemLinkViaccess::Init(const char *cfgdir){  Vcards.Load(cfgdir,SYSTEM_NAME,"Viaccess.KID");  return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -