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

📄 seca.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 4 页
字号:
  data[beforeSig+6]=buf[7];  data[beforeSig+7]=buf[2];  data[afterSig +0]=buf[3];  data[afterSig +1]=buf[1];  data[afterSig +2]=buf[0];  data[afterSig +3]=buf[6];}void cSeca2ProvFR::PostSSECore4(unsigned char *data, int pos){  data[afterSig+0]=data[beforeSig+3]^0x3e;  data[afterSig+1]=data[beforeSig+1]^0x5e;  data[afterSig+2]=data[beforeSig+5]^0x2f;  data[afterSig+3]=data[beforeSig+0]^0x77;  data[afterSig+4]=data[beforeSig+6]^-(0x4b);  data[afterSig+5]=data[beforeSig+2]^-(0x38);  data[afterSig+6]=data[beforeSig+7]^0x29;  data[afterSig+7]=data[beforeSig+4]^0x2b;}void cSeca2ProvFR::PostCW(unsigned char *data){  const unsigned char *T1=SSET1(), *T2=SSET2(), *T3=SSEPT2(), *T4=CWT1();  unsigned int idx;  unsigned char key[8];  idx=((data[0]<<8)|data[1]);     key[0]=T3[idx & 0x3FF];  idx=(idx + key[0]);             key[1]=T3[idx & 0x3FF];  idx=((data[2]<<8)|data[3]);     key[2]=T4[idx & 0x1FF];  idx=idx + key[2];               key[3]=T4[idx & 0x1FF];  idx=((data[8+4]<<8)|data[8+5]); key[4]=T2[idx & 0x7FF];  idx=idx + key[4];               key[5]=T2[idx & 0x7FF];  idx=((data[8+6]<<8)|data[8+7]); key[6]=T1[idx & 0xBFF];  idx=idx + key[6];               key[7]=T1[idx & 0xBFF];  des.Des(data+4,key,SECA_DES_ENCR);}void cSeca2ProvFR::ChainTableXor(unsigned char *data, unsigned short index){  static const unsigned char tabIdx[] = { 0x00, 0x08, 0x03, 0x1F, 0x06, 0x32, 0x12, 0x0C };  static const unsigned char tabXor[] = { 0x77, 0x2B, 0xC8, 0xEE, 0x2F, 0xD3, 0x22, 0x29 };  static const unsigned char tabPos[] = {    0,    2,    1,    6,    4,    5,    7,    3 };  unsigned int idx1, idx2;  unsigned char xorVal=0;  const unsigned char *T1=MT(), *T2=SSET1();  idx1 = (index^0x17AC) & 0x3FFF;  idx2 = idx1 & 0xBFF;  for(int i=0; i<8; i++) {    idx1 = (idx1 + tabIdx[i]) & 0x3FFF;    idx2 = (idx2 + xorVal) & 0xBFF;    xorVal ^= T1[idx1] ^ tabXor[i];    data[tabPos[i]] ^= xorVal ^ T2[idx2];    }}void cSeca2ProvFR::SignatureMod(unsigned char *MD, const unsigned char *PK){  const unsigned char *T1=SSEPT2();  unsigned int idx;  idx = ((MD[18] << 8) | MD[19]) & 0x3FF;  MD[10]  = T1[idx];  MD[13] ^= PK[6];  idx = ((MD[15] << 8) | MD[13]) & 0x3FF;  MD[16]  = T1[idx];  des.Des(MD,MD+10,SECA_DES_ENCR);}// -- Netherlands --------------------------------------------------------------class cSeca2ProvNL : public cSeca2ProvSSE {private:  virtual void PreSSECore(unsigned char *buf, const unsigned char *data, int i);  virtual void PostSSECore1(unsigned char *data, int pos);  virtual void PostSSECore2(unsigned char *buf, const unsigned char *data, int pos);  virtual void PostSSECore3(unsigned char *data, const unsigned char *buf, int pos);  virtual void PostSSECore4(unsigned char *data, int pos);protected:  virtual bool InitSSE(void);  virtual void PostCW(unsigned char *data);  virtual void ChainTableXor(unsigned char *data, unsigned short index);  virtual bool DoSigCheck(void) { return false; }public:  cSeca2ProvNL(unsigned short Id);  };static const unsigned short IdsNL[] = { 0x6a,0 };static cSeca2ProvLinkReg<cSeca2ProvNL> staticLinkNL(IdsNL);static const struct ProvData provDataNL = {  0x6a,16895,16895,0xa3,0x3a, { 3, 0, 0, 0, 2, 4, 3, 0 }  };cSeca2ProvNL::cSeca2ProvNL(unsigned short Id):cSeca2ProvSSE(Id){  pData=&provDataNL;}bool cSeca2ProvNL::InitSSE(void){  sse=GetMap("sse",5120,true);  sseP=GetMap("sse",336,false);  cw=GetMap("cw",512,false);  return sse && sseP && cw;}void cSeca2ProvNL::PreSSECore(unsigned char *buf, const unsigned char *data, int i){  const unsigned char *T1=SSET1(), *T2=SSET2();  buf[0] =data[7] ^T1[i+0x17];  buf[1] =data[1] ^T2[i+0x07];  buf[2] =data[2] ^T1[i+0x03];  buf[3] =data[3] ^T2[i+0x0C];  buf[4] =~data[4];  buf[5] =data[5] ^T1[i+0x1E];  buf[6] =data[6] ^T1[i+0x11];  buf[7] =data[0] ^T2[i+0x0F];  buf[8] =data[9] ^T1[i+0x15];  buf[9] =data[8] ^T2[i+0x04];  buf[10]=data[12]^T2[i+0x07];  buf[11]=data[11]^T1[i+0x16];  buf[12]=data[10]^T1[i+0x01];  buf[13]=data[13]^T1[i+0x0F];  buf[14]=~data[14];  buf[15]=data[15]^T2[i+0x0B];}void cSeca2ProvNL::PostSSECore1(unsigned char *data, int pos){  // modify 8 bytes before signature byte (0x82)  data[beforeSig+0] ^= 0xd6; data[beforeSig+1] ^= 0x96;  data[beforeSig+2] -= 0x51; data[beforeSig+3] ^= 0x3a;  data[beforeSig+4] -= 0x8d; data[beforeSig+5] ^= 0xf1;  data[beforeSig+6] -= 0xc2; data[beforeSig+7] ^= 0xb1;  data[afterSig+0] ^= 0x84; data[afterSig+1] ^= 0xf8;  data[afterSig+2] -= 0x7d; data[afterSig+3] = ~(data[afterSig+3]);  data[afterSig+4] ^= 0xfd; data[afterSig+5] ^= 0xd0;  data[afterSig+6] ^= 0x77; data[afterSig+7] ^= 0x25;}void cSeca2ProvNL::PostSSECore2(unsigned char *buf, const unsigned char *data, int pos){  const unsigned char *T1=SSEPT2();  memcpy(buf,&T1[(data[afterSig+6]+0x19)&0x7F],56);}void cSeca2ProvNL::PostSSECore3(unsigned char *data, const unsigned char *buf, int pos){  data[beforeSig+4]=buf[7];  data[beforeSig+5]=buf[0];  data[beforeSig+6]=buf[3];  data[beforeSig+7]=buf[5];  data[afterSig+0]=buf[6];  data[afterSig+1]=buf[2];  data[afterSig+2]=buf[1];  data[afterSig+3]=buf[4];}void cSeca2ProvNL::PostSSECore4(unsigned char *data, int pos){  data[afterSig+0]=data[beforeSig+1] ^ 0x65; data[afterSig+1]=data[beforeSig+0] ^ 0x75;  data[afterSig+2]=data[beforeSig+5] ^ 0x35; data[afterSig+3]=data[beforeSig+3] ^ 0xd9;  data[afterSig+4]=data[beforeSig+6] ^ 0xb7; data[afterSig+5]=data[beforeSig+7] ^ 0x9a;  data[afterSig+6]=data[beforeSig+4] ^ 0xc7; data[afterSig+7]=data[beforeSig+2] ^ 0x1f;}void cSeca2ProvNL::PostCW(unsigned char *data){  const unsigned char *T1=SSET1(), *T2=SSET2(), *T3=CWT1(), *T4=SSEPT2();  unsigned char key[8];  unsigned int off2;  off2=data[2]^data[8+6];  key[2]=T4[off2]; key[5]=T4[(off2+key[2])&0xff];  off2=(data[3]<<8)|data[8+4]; key[0]=T3[off2&0x1ff];  off2+=key[2]; key[4]=T3[off2&0x1ff];  off2=(data[0]<<8)|data[8+7]; key[7]=T2[off2&0x7ff];  off2+=key[0]; key[1]=T2[off2&0x7ff];  off2=(data[1]<<8)|data[8+5]; key[3]=T1[off2&0xbff];  off2+=key[4]; key[6]=T1[off2&0xbff];  des.Des(data+4,key,SECA_DES_ENCR);}void cSeca2ProvNL::ChainTableXor(unsigned char *data, unsigned short index){  static const unsigned short tabIdx[] = { 0x000, 0x4C3, 0x5D8, 0x63A, 0x471, 0x639, 0x417, 0x6CD };  static const unsigned char  tabXor[] = {  0x84,  0xD6,  0x3A,  0x1F,  0x25,  0xB1,  0x7D,  0xF7 };  static const unsigned char tabPos1[] = {     2,     4,     3,     4,     5,     7,     6,     7 };  static const unsigned char tabPos2[] = {     3,     1,     5,     6,     0,     1,     0,     2 };  unsigned int idx1, idx2;  unsigned char xorVal=0;  const unsigned char *T1=MT(), *T2=SSET1();  idx1=(index^0x2B36) & 0x3FFF;  idx2=idx1 & 0xBFF;  for(int i=0; i<8; i++) {    idx1=(idx1 + tabIdx[i]) & 0x3FFF;    idx2=(idx2 + xorVal) & 0xBFF;    xorVal ^= T1[idx1] ^ tabXor[i];    data[tabPos1[i]]^=xorVal;    data[tabPos2[i]]^=T2[idx2];    }}#undef beforeSig#undef afterSig// -- Poland -------------------------------------------------------------------class cSeca2ProvPL : public cSeca2Prov {protected:  virtual void PreCW(unsigned char *data);  virtual void ChainTableXor(unsigned char *data, unsigned short index);public:  cSeca2ProvPL(unsigned short Id);  };static const unsigned short IdsPL[] = { 0x65,0 };static cSeca2ProvLinkReg<cSeca2ProvPL> staticLinkPL(IdsPL);static const struct ProvData provDataPL = {  0x65,16895,16895,0x96,0x69, { 3, 0, 0, 0, 2, 4, 3, 0 }  };static const struct Perm ptPL[MAX_PERMS] = {    { // 1    { 2, 4, 4, 3, 2, 2, 4, 4 },    { 3, 2, 4, 3, 4, 4, 2, 3 },    { 0, 0, 0, 0, 0, 0, 0, 0 },    { 0, 0, 0, 0, 0, 0, 0, 0 }  },{ // 2    { 4, 4, 3, 2, 2, 3, 3, 4 },    { 4, 2, 3, 4, 3, 2, 4, 2 },    { 0, 0, 0, 0, 0, 0, 0, 0 },    { 0, 0, 0, 0, 0, 0, 0, 0 }  },{ // 3  },{ // 4  },{ // 5  },{ // 6  },{ // 7  },{ // 8  },{ // 9    { 4, 4, 3, 2, 3, 4, 3, 2 },    { 2, 4, 3, 2, 2, 4, 4, 3 },    { 2, 3, 4, 1, 0, 0, 0, 0 },    { 0, 0, 0, 0, 0, 0, 0, 0 },  },{ // 10  } };cSeca2ProvPL::cSeca2ProvPL(unsigned short Id):cSeca2Prov(Id){  pData=&provDataPL; perm=ptPL;}void cSeca2ProvPL::PreCW(unsigned char *data){  static const unsigned char XT[]={ 0xA0,0x12,0x23,0x35,0x46,0xB0,0xDF,0xCA, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };  static const unsigned char PT[]={ 0x05,0x04,0x06,0x07,0x03,0x00,0x01,0x02, 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F };  unsigned char temp[16];  xxor(temp,16,data,XT);  for(int i=15; i>=0; i--) data[i]=temp[PT[i]];}void cSeca2ProvPL::ChainTableXor(unsigned char *data, unsigned short index){  const unsigned char *T1=MT();  for(int i=0; i<8; i++) data[i]^=T1[index++];}// -- cSystemSeca ---------------------------------------------------------------class cSystemSeca : public cSystem, private cSeca {private:  cSeca2Prov *sp, *spL;  int emmLenCnt;  cDes des;  cRSA rsa;  //  bool GetSeca2Prov(int provId, cSeca2Prov * &sp);  bool Process0FNano(int count, unsigned char *hashDW, unsigned char *PK, const unsigned char *T1, const unsigned char *T2);  bool Process51Nano(unsigned char *CW, const unsigned char *PermData, const unsigned char *hashDW, const unsigned char *T1, const unsigned char *T2, int provId);  void Crypto51Nano(unsigned char *data, const unsigned char *key, const unsigned char crypto, const unsigned char mode);  void Permute(unsigned char *data, const unsigned char *pdata, const unsigned char *P);public:  cSystemSeca(void);  virtual ~cSystemSeca();  virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *data);  virtual void ProcessEMM(int pid, int caid, unsigned char *buffer);  };cSystemSeca::cSystemSeca(void):cSystem(SYSTEM_NAME,SYSTEM_PRI),des(secaPC1,secaPC2){  sp=spL=0; emmLenCnt=0;  hasLogger=true;}cSystemSeca::~cSystemSeca(){  delete sp;  delete spL;}bool cSystemSeca::GetSeca2Prov(int provId, cSeca2Prov * &sp){  if(!sp || !sp->Matches(provId)) {    delete sp;    sp=cSeca2Providers::GetProv(provId);    }  return sp!=0;}bool cSystemSeca::ProcessECM(const cEcmInfo *ecmD, unsigned char *data){  bool SE=false;  unsigned char *ecm;  const int msgLen=cParseSeca::Payload(data,(const unsigned char **)&ecm);  const int keyNr=cParseSeca::KeyNr(data);  if(keyNr&0x80) {    PRINTF(L_SYS_VERBOSE,"Super Encryption enabled");    SE=true;    if(!GetSeca2Prov(ecmD->provId,sp)) {      if(doLog) PRINTF(L_SYS_ECM,"Seca2 provider %04x not supported",ecmD->provId);      return false;      }    }  HEXDUMP(L_SYS_VERBOSE,data,SCT_LEN(data),"ECM:");  if(ecm[0]==0x10) {    if(msgLen<0x5c) {      if(doLog) PRINTF(L_SYS_ECM,"ECM length too small (%d)",msgLen);      return false;      }    if(SE) {      HEXDUMP(L_SYS_VERBOSE,ecm+(msgLen-0x5a),0x5a,"ECM before SSE data modification :");      sp->PreSSE(ecm,msgLen-0x5a);      HEXDUMP(L_SYS_VERBOSE,ecm+(msgLen-0x5a),0x5a,"ECM after SSE data modification :");      }    const int rsaKeynr=(ecm[1]&0x0F)+'0';    cBN exp, mod;    cPlainKey *rsaKey;    if(!(rsaKey=keys.FindKey('S',ecmD->provId,MBC('E',rsaKeynr),-1))) {      if(doLog) PRINTF(L_SYS_KEY,"missing %04x E%c key",ecmD->provId,rsaKeynr);      return false;      }    rsaKey->Get(exp);    if(!(rsaKey=keys.FindKey('S',ecmD->provId,MBC('M',rsaKeynr),-1))) {      if(doLog) PRINTF(L_SYS_KEY,"missing %04x M%c key",ecmD->provId,rsaKeynr);      return false;      }    rsaKey->Get(mod);    HEXDUMP(L_SYS_VERBOSE,ecm+(msgLen-0x5a),0x5a,"ECM before RSA decrypt :");    if(rsa.RSA(ecm+(msgLen-0x5a),ecm+(msgLen-0x5a),0x5a,exp,mod)!=0x5a) {      PRINTF(L_SYS_CRYPTO,"RSA decrypt failed (ECM)");      return false;      }    HEXDUMP(L_SYS_VERBOSE,ecm+(msgLen-0x5a),0x5a,"ECM after RSA decrypt :");    if(SE) { // PostSSE needed      const int hashPtr=msgLen-ecm[msgLen-1]-9;      if(hashPtr>=msgLen-9 || ecm[hashPtr]!=0x82) {        PRINTF(L_SYS_CRYPTO,"RSA decrypt failed, signature pointer not found");        return false;        }      HEXDUMP(L_SYS_VERBOSE,ecm+(msgLen-0x5a),0x5a,"ECM before SSE result modification :");      sp->PostSSE(ecm,hashPtr);      HEXDUMP(L_SYS_VERBOSE,ecm+(msgLen-0x5a),0x5a,"ECM after SSE result modification :");      }    }  const unsigned char *T1=T1_S1, *T2=T2_S1;  int decrLen=msgLen;  if(SE) {    if(!(T1=sp->T1(KEY2INDEX(keyNr))) ||       !(T2=sp->T2(KEY2INDEX(keyNr)))) return false;    decrLen-=ecm[msgLen-1]; if(decrLen<8) return false;    }  bool key8=!(cParseSeca::SysMode(data)&0x10);  cPlainKey *pk=0;  cKeySnoop ks(this,'S',ecmD->provId,keyNr&0x0F);  while((pk=keys.FindKey('S',ecmD->provId,keyNr&0x0F,key8?8:16,pk))) {    unsigned char buff[msgLen];    memcpy(buff,ecm,sizeof(buff)); // if decoding fails we need the original data        unsigned char PK[16], signature[20];    pk->Get(PK);    if(key8) memcpy(&PK[8],&PK[0],8); // duplicate key    if(SE) {      sp->CalcSHASignature(buff,decrLen-8,signature);      LDUMP(L_SYS_VERBOSE,signature,8,"signature before encrypt :");      sp->SignatureMod(signature,PK);      Encrypt(signature,PK,T1,T2);      LDUMP(L_SYS_VERBOSE,signature,8,"signature after encrypt :");      if(sp->DoSigCheck() && memcmp(signature,&buff[decrLen-8],8)) {        PRINTF(L_SYS_VERBOSE,"signature check failed before SE decrypt");        continue;

⌨️ 快捷键说明

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