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

📄 seca.cpp

📁 DVB-S的softcam源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  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)
    ds(printf("seca-prov: no filemap for %s\n",name))
  else if(!map->Map()) {
    ds(printf("seca-prov: mapping failed for %s\n",name))
    map=0;
    }
  else if(map->Size()<size) {
    ds(printf("seca-prov: %s file %s has wrong size (has=%d wanted=%d)\n",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);
    }
  ds(printf("seca-prov: bad T1 table index %d\n",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;
    }
  ds(printf("seca-prov: bad T2 table index %d\n",index))
  return 0;
}

const struct Perm *cSeca2Prov::P(int index) const
{
  if(index>=0 && index<MAX_PERMS && perm) {
    return &perm[index];
    }
  ds(printf("seca-prov: no perm table or bad index %d\n",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)
{
  dyn(printf("seca2prov: registering Seca2 provider"))
  for(int i=0; spl->ids[i]; i++) dyn(printf(" %.4x",spl->ids[i]))
  dyn(printf("\n"))
  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];
  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;

⌨️ 快捷键说明

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