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

📄 cryptoworks.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
bool cCryptoworks::DecryptRSA(unsigned char *data, int len, unsigned char algo, const unsigned char *key22, BIGNUM *mod){  unsigned char buf[64], mask[len];  LDUMP(L_SYS_VERBOSE,data+len,8,"rsa in:");  memcpy(buf,data+len,8);  EncDec(buf,key22,algo,DES_LEFT);  buf[0]|=0x80;  if((algo&0x18)<0x18) buf[0]=0xFF;  if(algo&8) buf[1]=0xFF;  LDUMP(L_SYS_VERBOSE,buf,8,"rsa seed:");    static const unsigned char t1[] = { 0xE,0x3,0x5,0x8,0x9,0x4,0x2,0xF,0x0,0xD,0xB,0x6,0x7,0xA,0xC,0x1 };  for(int k=0; k<len; k+=32) {    memcpy(buf+8,buf,8);    for(int i=0; i<8; i++) {      int n=i<<1;      buf[n+1]=buf[i+8];      buf[n  ]=(t1[buf[n+1]>>4]<<4) | t1[buf[i+8]&0xF];      LDUMP(L_SYS_VERBOSE,buf,16,"rsa buf:");      }    for(int i=16; i<64; i+=16) memcpy(&buf[i],buf,16);    buf[31]=((buf[15]<<4)&0xFF) | 6;    buf[16]=buf[0]^1;    buf[32]&=0x7F;    buf[32]|=0x40;    RotateBytes(buf,32);    RotateBytes(buf+32,32);    LDUMP(L_SYS_VERBOSE,buf,64,"rsa data:");    if(rsa.RSA(buf,buf,64,exp,mod,true)==0) {      PRINTF(L_SYS_CRYPTO,"RSA failed");      return false;      }    RotateBytes(buf,8);    RotateBytes(mask+k,buf+8,min(32,len-k));    }  LDUMP(L_SYS_VERBOSE,mask,len,"rsa out:");  xxor(data,len,data,mask);  return true;}// -- cPlainKeyCryptoworks -----------------------------------------------------#define PLAINLEN_CW_D  16#define PLAINLEN_CW_CC  6#define PLAINLEN_CW_R  64#define CCTYP               0x00#define CCID                0xFF#define PROV(keynr)         (((keynr)>>16)&0xFF)#define TYPE(keynr)         (((keynr)>> 8)&0xFF)#define ID(keynr)           (((keynr)   )&0xFF)#define KEYSET(prov,typ,id) ((((prov)&0xFF)<<16)|(((typ)&0xFF)<<8)|((id)&0xFF))class cPlainKeyCryptoworks : public cDualKey {protected:  virtual bool IsBNKey(void) const;  virtual int IdSize(void) { return 4; }  virtual cString PrintKeyNr(void);public:  cPlainKeyCryptoworks(bool Super);  virtual bool Parse(const char *line);  };static cPlainKeyTypeReg<cPlainKeyCryptoworks,'W'> KeyReg;cPlainKeyCryptoworks::cPlainKeyCryptoworks(bool Super):cDualKey(Super,true){}bool cPlainKeyCryptoworks::IsBNKey(void) const{  return TYPE(keynr)==0x10;}bool cPlainKeyCryptoworks::Parse(const char *line){  const char *sline=line;  unsigned char sid[2], sprov;  if(GetChar(line,&type,1) && GetHex(line,sid,2) && GetHex(line,&sprov,1)) {    int keylen, prov;    type=toupper(type); id=Bin2Int(sid,2); prov=sprov;    line=skipspace(line);    bool ok;    if(!strncasecmp(line,"CC",2)) { // cardkey      keynr=KEYSET(prov,CCTYP,CCID);      keylen=PLAINLEN_CW_CC;      line+=2;      ok=true;      }    else {      unsigned char sid, styp;      ok=GetHex(line,&styp,1) && GetHex(line,&sid,1);      keynr=KEYSET(prov,styp,sid);      keylen=IsBNKey() ? PLAINLEN_CW_R : PLAINLEN_CW_D;      }    if(ok) {      unsigned char skey[keylen];      if(GetHex(line,skey,keylen)) {        SetBinKey(skey,keylen);        return true;        }      }    }  FormatError("cryptoworks",sline);  return false;}cString cPlainKeyCryptoworks::PrintKeyNr(void){  int prov=PROV(keynr);  int keytyp=TYPE(keynr);  int keyid=ID(keynr);  return cString::sprintf(keytyp==CCTYP && keyid==CCID ? "%02X CC":"%02X %02X %02X",prov,keytyp,keyid);}// -- cSystemCryptoworks -------------------------------------------------------#define ECM_ALGO_TYP   5#define ECM_DATA_START ECM_ALGO_TYP#define ECM_NANO_LEN   7#define ECM_NANO_START 8class cSystemCryptoworks : public cSystem, private cCryptoworks {private:public:  cSystemCryptoworks(void);  virtual bool ProcessECM(const cEcmInfo *ecmInfo, unsigned char *data);//  virtual void ProcessEMM(int pid, int caid, unsigned char *data);  };cSystemCryptoworks::cSystemCryptoworks(void):cSystem(SYSTEM_NAME,SYSTEM_PRI){//  hasLogger=true;}bool cSystemCryptoworks::ProcessECM(const cEcmInfo *ecmInfo, unsigned char *data){  int len=SCT_LEN(data);  if(data[ECM_NANO_LEN]!=len-ECM_NANO_START) {    PRINTF(L_SYS_ECM,"invalid ECM structure");    return false;    }  int prov=-1, keyid=0;  for(int i=ECM_NANO_START; i<len; i+=data[i+1]+2) {    if(data[i]==0x83) {      prov =data[i+2]&0xFC;      keyid=data[i+2]&0x03;      break;      }    }  if(prov<0) {    PRINTF(L_SYS_ECM,"provider ID not located in ECM");    return false;    }  unsigned char key[22];  cPlainKey *pk;  if(!(pk=keys.FindKey('W',ecmInfo->caId,KEYSET(prov,CCTYP,CCID),6))) {    if(doLog) PRINTF(L_SYS_KEY,"missing %04X %02X CC key",ecmInfo->caId,prov);    return false;    }  pk->Get(key+16);  // RSA stage  DUMPNANO("pre-RSA",&data[ECM_NANO_START],len-ECM_NANO_START);  for(int i=ECM_NANO_START; i<len; i+=data[i+1]+2) {    int l=data[i+1]+2;    switch(data[i]) {      case 0x85:        {        if(!(pk=keys.FindKey('W',ecmInfo->caId,KEYSET(prov,0x31,keyid),16))) {          if(doLog) PRINTF(L_SYS_KEY,"missing %04X %02X 31 %02X key",ecmInfo->caId,prov,keyid);          return false;          }        pk->Get(key);        cBN mod;        if(!(pk=keys.FindKey('W',ecmInfo->caId,KEYSET(prov,0x10,0x00),64))) {          if(doLog) PRINTF(L_SYS_KEY,"missing %04X %02X 10 00 key",ecmInfo->caId,prov);          return false;          }        pk->Get(mod);        l-=10;        if(!DecryptRSA(&data[i+2],l,data[ECM_ALGO_TYP],key,mod))          return false;        memmove(&data[i],&data[i+2],l);        memmove(&data[i+l],&data[i+l+10],len-i-l);        len-=10;        break;        }      case 0x86:        memmove(&data[i],&data[i+l],len-i-l);        len-=l;        continue;      }    }  DUMPNANO("post-RSA",&data[ECM_NANO_START],len-ECM_NANO_START);  cKeySnoop ks(this,'W',ecmInfo->caId,KEYSET(prov,0x20,keyid));  if(!(pk=keys.FindKey('W',ecmInfo->caId,KEYSET(prov,0x20,keyid),16))) {    if(doLog) PRINTF(L_SYS_KEY,"missing %04X %02X 20 %02X key",ecmInfo->caId,prov,keyid);    return false;    }  pk->Get(key);  // DES stage  unsigned char sig[8];  LDUMP(L_SYS_VERBOSE,&data[len-8],8,"sig org:");  data[ECM_NANO_LEN]=len-ECM_NANO_START;  Signature(&data[ECM_DATA_START],len-ECM_DATA_START-10,key,sig);  for(int i=ECM_NANO_START; i<len; i+=data[i+1]+2) {    switch(data[i]) {      case 0xDA:      case 0xDB:      case 0xDC:        for(int j=0; j<data[i+1]; j+=8)          DecryptDES(&data[i+2+j],data[ECM_ALGO_TYP],key);        break;      case 0xDF:        if(memcmp(&data[i+2],sig,8)) {          PRINTF(L_SYS_ECM,"signature failed in ECM");          return false;          }        break;      }    }    // CW stage  for(int i=ECM_NANO_START; i<len; i+=data[i+1]+2) {    switch(data[i]) {      case 0xDB:        if(data[i+1]==0x10) {          memcpy(cw,&data[i+2],16);          LDUMP(L_SYS_VERBOSE,cw,16,"cw:");          ks.OK(pk);          return true;          }        break;      }    }  return false;}/*void cSystemCryptoworks::ProcessEMM(int pid, int caid, unsigned char *data){}*/// -- cSystemLinkCryptoworks ---------------------------------------------------class cSystemLinkCryptoworks : public cSystemLink {public:  cSystemLinkCryptoworks(void);  virtual bool CanHandle(unsigned short SysId);  virtual cSystem *Create(void) { return new cSystemCryptoworks; }  };static cSystemLinkCryptoworks staticInit;cSystemLinkCryptoworks::cSystemLinkCryptoworks(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){  Feature.NeedsKeyFile();}bool cSystemLinkCryptoworks::CanHandle(unsigned short SysId){  SysId&=SYSTEM_MASK;  return SYSTEM_CAN_HANDLE(SysId);}

⌨️ 快捷键说明

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