📄 cryptoworks.c
字号:
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 + -