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