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

📄 seca.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 4 页
字号:
  virtual void PreSSE(unsigned char *data, int pos) {}  virtual void PostSSE(unsigned char *data, int pos) {}  virtual void SignatureMod(unsigned char *MD, const unsigned char *PK) {}  virtual void PreCW(unsigned char *data) {}  virtual void PostCW(unsigned char *data) {}  virtual void ChainTableXor(unsigned char *data, unsigned short index)=0;  virtual bool DoSigCheck(void) { return true; }  //  virtual bool Init(void);  void CalcSHASignature(const unsigned char *data, int n, unsigned char *signature, bool PadMode=true);  bool DecryptSE(unsigned char *data, const unsigned char *key, int n, int start, const unsigned char *T1, const unsigned char *T2);  bool Matches(unsigned short Id) const { return Id==id; }  //  const unsigned char *T1(int index) const;  const unsigned char *T2(int index) const;  const struct Perm *P(int index) const;  inline const unsigned char *MT(void) const { return mask->Addr(); }  inline int MTSize(void) const { return pData->MTSize; }  inline const unsigned char *FP(void) const { return pData->FP; }  };cSeca2Prov::cSeca2Prov(unsigned short Id){  id=Id;  pData=0; perm=0; hash=0; mask=0;}cSeca2Prov::~cSeca2Prov(){  if(hash) hash->Unmap();  if(mask) mask->Unmap();}bool cSeca2Prov::Init(void){  hash=GetMap("hash",1536,false);  mask=GetMap("mt",pData->MTLoadSize,false);  if(!hash || !mask) return false;  return true;}cFileMap *cSeca2Prov::GetMap(const char *type, int size, bool generic) const{  char name[32];  snprintf(name,sizeof(name),generic ? "s2_%s.bin" : "s2_%s_%04x.bin",type,pData->LoadId);  cFileMap *map=filemaps.GetFileMap(name,FILEMAP_DOMAIN,false);  if(!map)    PRINTF(L_SYS_CRYPTO,"no filemap for %s",name);  else if(!map->Map()) {    PRINTF(L_SYS_CRYPTO,"mapping failed for %s",name);    map=0;    }  else if(map->Size()<size) {    PRINTF(L_SYS_CRYPTO,"%s file %s has wrong size (has=%d wanted=%d)",type,name,map->Size(),size);    map->Unmap();    map=0;    }  return map;}// Hash file layout is (Yankse style)://  Table T1 for 9x, //  Table T1 for Bx,//  Table T1 for FX,//  Table T2 for 9x, //  Table T2 for Bx,//  Table T2 for FX  (total: 1536 bytes)const unsigned char *cSeca2Prov::T1(int index) const{  static int idxTrans[] = { 0,1,2,2 };  if(index>=0 && index<=3) {    return hash->Addr()+(idxTrans[index]*256);    }  PRINTF(L_SYS_CRYPTO,"bad T1 table index %d",index);  return 0;}const unsigned char *cSeca2Prov::T2(int index) const{  static int idxTrans[] = { 0,1,2,2 };  if(index>=0 && index<=3) {    return hash->Addr()+(idxTrans[index]*256)+768;    }  PRINTF(L_SYS_CRYPTO,"bad T2 table index %d",index);  return 0;}const struct Perm *cSeca2Prov::P(int index) const{  if(index>=0 && index<MAX_PERMS && perm) {    return &perm[index];    }  PRINTF(L_SYS_CRYPTO,"no perm table or bad index %d",index);  return 0;}unsigned short cSeca2Prov::Sum(const unsigned char *data, int n) const{  unsigned int sum=0;  for(int i=1; i<n; i+=2) sum+=((data[i-1]<<8)+data[i]);  if(n&1) sum+=(data[n-1]<<4);  return sum&0x3FFF;}bool cSeca2Prov::DecryptSE(unsigned char *data, const unsigned char *key, int n, int start, const unsigned char *T1, const unsigned char *T2){  const int sigStart=n-data[n-1]-9; // 82 <8 bytes> P5(sigStart)  const int encrLen=sigStart-16;#ifdef DEBUG_SECA_EXTRA  if(encrLen>=n || encrLen<0) printf("encrLen error in SE\n");  if(sigStart<16) printf("sigStart error in SE\n");#endif  if(encrLen>=n || encrLen<0 || sigStart<16) return false;  Decrypt(data+sigStart-8,key,T1,T2);  ChainTableXor(data+sigStart-8,Sum(data+start,sigStart-8-start));  int i;  for(i=start; i<encrLen; i+=8) {    Decrypt(data+i,key,T1,T2);    ChainTableXor(data+i,Sum(&data[i+8],8));    }  int restBytes=sigStart&0x07;  if(!restBytes) restBytes=8;  // Last Block  unsigned char lastBlock[8];  memset(lastBlock,0,sizeof(lastBlock));  memcpy(lastBlock,data+sigStart-restBytes,restBytes);  Decrypt(lastBlock,key,T1,T2);  Decrypt(data+i,key,T1,T2);  ChainTableXor(data+i,Sum(lastBlock,sizeof(lastBlock)));  return true;}void cSeca2Prov::CalcSHASignature(const unsigned char *data, int n, unsigned char *signature, bool PadMode){  SHA_CTX ctx;  SHA1_Init(&ctx);  SHA1_Update(&ctx,data,n);  unsigned char Pad=0;  if(PadMode) {    unsigned char End=pData->SHA1End;    SHA1_Update(&ctx,&End,1);    int l=(n&63)+1;    Pad=pData->SHA1Pad;    if(l>62) {      for(; l<64; l++) SHA1_Update(&ctx,&Pad,1);      l=0;      }    for(; l<62; l++) SHA1_Update(&ctx,&Pad,1);    unsigned short s=bswap_16(n);    SHA1_Update(&ctx,&s,2);    }  else for(; n&63; n++) SHA1_Update(&ctx,&Pad,1);  *((unsigned int *)(signature   ))=bswap_32(ctx.h0);  *((unsigned int *)(signature+ 4))=bswap_32(ctx.h1);  *((unsigned int *)(signature+ 8))=bswap_32(ctx.h2);  *((unsigned int *)(signature+12))=bswap_32(ctx.h3);  *((unsigned int *)(signature+16))=bswap_32(ctx.h4);}// -- cSecaProviders & cSecaProviderLink ---------------------------------------class cSeca2ProvLink {friend class cSeca2Providers;private:  cSeca2ProvLink *next;  const unsigned short *ids;public:  cSeca2ProvLink(const unsigned short *Ids);  bool CanHandle(unsigned short Id);  virtual cSeca2Prov *Create(unsigned short Id)=0;  virtual ~cSeca2ProvLink() {};  };template<class CC> class cSeca2ProvLinkReg : public cSeca2ProvLink {public:  cSeca2ProvLinkReg(const unsigned short *Ids):cSeca2ProvLink(Ids) {}  virtual cSeca2Prov *Create(unsigned short Id) { return new CC(Id); }  };class cSeca2Providers {friend class cSeca2ProvLink;private:  static cSeca2ProvLink *first;  //  static void Register(cSeca2ProvLink *spl);public:  static cSeca2Prov *GetProv(unsigned short id);  };cSeca2ProvLink *cSeca2Providers::first=0;void cSeca2Providers::Register(cSeca2ProvLink *spl){  LBSTART(L_CORE_DYN);  LBPUT("seca2prov: registering Seca2 provider");  for(int i=0; spl->ids[i]; i++) LBPUT(" %.4x",spl->ids[i]);  LBEND();  spl->next=first;  first=spl;}cSeca2Prov *cSeca2Providers::GetProv(unsigned short id){  cSeca2ProvLink *spl=first;  while(spl) {    if(spl->CanHandle(id)) {      cSeca2Prov *sp=spl->Create(id);      if(sp && sp->Init()) return sp;      delete sp;      }    spl=spl->next;    }  return 0;}cSeca2ProvLink::cSeca2ProvLink(const unsigned short *Ids){  ids=Ids;  cSeca2Providers::Register(this);}bool cSeca2ProvLink::CanHandle(unsigned short Id){  for(int i=0; ids[i]; i++) if(ids[i]==Id) return true;  return false;}// -- cSeca2ProvSSE ------------------------------------------------------------#define beforeSig (pos-8)#define afterSig  (pos+1)class cSeca2ProvSSE : public cSeca2Prov {private:  virtual void PreSSECore(unsigned char *buf, const unsigned char *data, int i)=0;  virtual void PostSSECore1(unsigned char *data, int pos)=0;  virtual void PostSSECore2(unsigned char *buf, const unsigned char *data, int pos)=0;  virtual void PostSSECore3(unsigned char *data, const unsigned char *buf, int pos)=0;  virtual void PostSSECore4(unsigned char *data, int pos)=0;protected:  cDes des;  cFileMap *sse, *sseP, *cw;  //  virtual bool InitSSE(void)=0;  virtual void PreSSE(unsigned char *data, int pos);  virtual void PostSSE(unsigned char *data, int pos);  //  inline const unsigned char *SSET1(void) const { return sse->Addr(); }  inline const unsigned char *SSET2(void) const { return sse->Addr()+3072; }  inline const unsigned char *SSEPT1(void) const { return sseP->Addr(); }  inline const unsigned char *SSEPT2(void) const { return sseP->Addr()+80; }  inline const unsigned char *CWT1(void) const { return cw->Addr(); }public:  cSeca2ProvSSE(unsigned short Id);  virtual ~cSeca2ProvSSE();  virtual bool Init(void);  };cSeca2ProvSSE::cSeca2ProvSSE(unsigned short Id):cSeca2Prov(Id),des(secaPC1,secaPC2){  sse=0; sseP=0; cw=0;}cSeca2ProvSSE::~cSeca2ProvSSE(){  if(sse)  sse->Unmap();  if(sseP) sseP->Unmap();  if(cw)   cw->Unmap();}bool cSeca2ProvSSE::Init(void){  return InitSSE() && cSeca2Prov::Init();}void cSeca2ProvSSE::PreSSE(unsigned char *data, int pos){  const unsigned char *T1=SSEPT1();  unsigned char tmpBuf[80];  data+=pos+5; // Start at offset 5  for(int i=4; i>=0; i--) {    int j=i*16;    PreSSECore(&tmpBuf[j],&data[j],i);    }  for(int i=79; i>=0; i--) data[i]=tmpBuf[i]^T1[i];}void cSeca2ProvSSE::PostSSE(unsigned char *data, int pos){  PostSSECore1(data,pos);  // create the SHA hash buffer  unsigned char tmpBuf[64];  memcpy(tmpBuf+0,&data[beforeSig+0],4);  memcpy(tmpBuf+4,&data[afterSig +4],4);  PostSSECore2(tmpBuf+8,data,pos);  // Calc Signature of the generated buffer here  unsigned char MD[20];  CalcSHASignature(tmpBuf,sizeof(tmpBuf),MD,false);  // Prepare DES data  memcpy(tmpBuf+0,&data[beforeSig+4],4);  memcpy(tmpBuf+4,&data[afterSig +0],4);  // DES Enrypt  des.Des(tmpBuf,MD,SECA_DES_ENCR);  // modify data with encrypted DES data  PostSSECore3(data,tmpBuf,pos);  // save the signature  memcpy(tmpBuf,data+afterSig,8);  PostSSECore4(data,pos);  // put the signature in the data  memcpy(data+beforeSig,tmpBuf,8);}// -- France -------------------------------------------------------------------class cSeca2ProvFR : 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 void SignatureMod(unsigned char *MD, const unsigned char *PK);public:  cSeca2ProvFR(unsigned short Id);  };static const unsigned short IdsFR[] = { 0x80,0x81,0 };static cSeca2ProvLinkReg<cSeca2ProvFR> staticLinkFR(IdsFR);static const struct ProvData provDataFR = {  0x80,16895,16895,0x7F,0xF7, { 3, 0, 0, 0, 2, 4, 3, 0 }  };cSeca2ProvFR::cSeca2ProvFR(unsigned short Id):cSeca2ProvSSE(Id){  pData=&provDataFR;}bool cSeca2ProvFR::InitSSE(void){  sse=GetMap("sse",5120,true);  sseP=GetMap("sse",1104,false);  cw=GetMap("cw",512,false);  return sse && sseP && cw;}void cSeca2ProvFR::PreSSECore(unsigned char *buf, const unsigned char *data, int i){  const unsigned char *T1=SSET1(), *T2=SSET2();  buf[ 0]=data[0x06]^T2[i+0x0a];  buf[ 1]=data[0x01]^T2[i+0x00];  buf[ 2]=data[0x02]^T1[i+0x00];  buf[ 3]=data[0x03]^T2[i+0x04];  buf[ 4]=~data[0x04];  buf[ 5]=data[0x05]^T1[i+0x01];  buf[ 6]=data[0x00]^T2[i+0x0f];  buf[ 7]=data[0x07]^T1[i+0x02];  buf[ 8]=data[0x08]^T1[i+0x00];  buf[ 9]=data[0x0d]^T2[i+0x14];  buf[10]=data[0x0f]^T2[i+0x07];  buf[11]=~data[0x0b];  buf[12]=data[0x0c]^T1[i+0x00];  buf[13]=data[0x09]^T2[i+0x19];  buf[14]=data[0x0e]^T2[i+0x1e];  buf[15]=data[0x0a]^T1[i+0x01];}void cSeca2ProvFR::PostSSECore1(unsigned char *data, int pos){  data[beforeSig+0]^=-(0x2d);  data[beforeSig+1]-=0x22;  data[beforeSig+2]^=0x1d;  data[beforeSig+3]^=-(0x68);  data[beforeSig+4] =~data[beforeSig + 4];  data[beforeSig+5]^=0x26;  data[beforeSig+6]^=0x09;  data[beforeSig+7]-=0x3e;  data[afterSig +0]^=-(0x5d);  data[afterSig +1]-=0x74;  data[afterSig +2]^=0x2d;  data[afterSig +3]^=-(0x2a);  data[afterSig +4]+=0x0d;  data[afterSig +5]^=-(0x6c);  data[afterSig +6]^=-(0x76);  data[afterSig +7]+=0x31;}void cSeca2ProvFR::PostSSECore2(unsigned char *buf, const unsigned char *data, int pos){  const unsigned char *T1=SSEPT2();  memcpy(buf, &T1[data[afterSig+4]+0x48], 56);}void cSeca2ProvFR::PostSSECore3(unsigned char *data, const unsigned char *buf, int pos){  data[beforeSig+4]=buf[5];  data[beforeSig+5]=buf[4];

⌨️ 快捷键说明

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