📄 irdeto.c
字号:
unsigned char lastKey;public: cSystemIrd(void); virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *source); virtual void ProcessEMM(int pid, int caid, unsigned char *buffer); };cSystemIrd::cSystemIrd(void):cSystem(SYSTEM_NAME,SYSTEM_PRI){ lastKey=0; hasLogger=true;}bool cSystemIrd::ProcessECM(const cEcmInfo *ecm, unsigned char *source){ unsigned char *data=0; int date=-1, keynr=0; source+=6; int length=source[5]+6-5; // 6 header bytes - 5 signature bytes for(int index=6 ; index<length && (data==0 || date==-1) ;) { int param=source[index++]; int len =source[index++] & 0x3f; switch(param) { case 0x78: keynr = source[index]; data = &source[index+2]; break; case 0x00: case 0x40: date = (source[index]<<8) | source[index+1]; break; } index+=len; } if(data==0 || date==-1) { PRINTF(L_SYS_ECM,"incomplete ECM structure"); return false; } cKeySnoop ks(this,'I',source[2],keynr); cPlainKey *pk=0; unsigned char key[8]; while((pk=keys.FindKey('I',source[2],keynr,sizeof(key),pk))) { unsigned char save[16]; memcpy(save,data,16); // save the encrypted data pk->Get(key); SessionKeyCrypt(&data[0],key,date); SessionKeyCrypt(&data[8],key,date); if(SignatureCheck(source,length,key,date,&source[length],8)) { memcpy(cw,&data[0],16); ks.OK(pk); return true; } memcpy(data,save,16); // put back the encrypted data if it didn't works } return false;}void cSystemIrd::ProcessEMM(int pid, int caid, unsigned char *buffer){ int i, numKeys=0, date=0; unsigned char adr[10], id[4], *pk[4], prov, *mk=0, prvId[3]={0,0,0}; int n=SCT_LEN(buffer); unsigned char savebuf[4096]; if(n>(int)sizeof(savebuf)) { PRINTF(L_SYS_EMM,"%d: paket size %d to big for savebuffer in IrdetoLog",CardNum(),n); return; } int index=cParseIrdeto::AddrLen(buffer); memset(adr,0,sizeof(adr)); memcpy(adr,&buffer[3],index+1); index+=4+4; // 3 header + adr type + 4 {0x01 0x00 0x00 len} int sindex=index; // save index for sig. check int slen=buffer[index-1]-5; // save packet length, 5 signature bytes int maxIndex=index+slen; if(maxIndex>n-5) { PRINTF(L_SYS_EMM,"%d: bad packet length (%d > %d)",CardNum(),maxIndex,n-5); maxIndex=n-5; } bool badnano=false; while(!badnano && index<maxIndex) { unsigned char nlen=buffer[index+1] & 0x3F; //unsigned char prio=buffer[index] & 0x40; unsigned char nano=buffer[index] & ~0x40; switch(nano) { case 0x10: // key update { int k=(buffer[index+1]>>6)+1; // key counter if(nlen!=k*9) { badnano=true; break; } for(i=0 ; i<k ; i++) { id[i]= buffer[index+2+0+i*9]; pk[i]=&buffer[index+2+1+i*9]; numKeys++; } } break; case 0x00: // date if(nlen<2) { badnano=true; break; } date=WORD(buffer,index+2,0xFFFF); break; case 0x28: // pmk & provid update if(nlen!=13) { badnano=true; break; } prov= buffer[index+2+0]; mk= &buffer[index+2+2]; prvId[0]=buffer[index+2+10]; prvId[1]=buffer[index+2+11]; prvId[2]=buffer[index+2+12]; break; case 0x29: // pmk update if(nlen!=10) { badnano=true; break; } prov= buffer[index+2+0]; mk= &buffer[index+2+2]; break; case 0x11: // channel id if(nlen!=6) { badnano=true; break; } //chId[0]=buffer[index+2+0]; //chId[1]=buffer[index+2+1]; break; case 0x91: // erase channel id if(nlen!=6) { badnano=true; break; } //eraseChId[0]=buffer[index+2+0]; //eraseChId[1]=buffer[index+2+1]; break; case 0x8B: // CB20-matrix if(nlen!=0x20) { badnano=true; break; } //cb20ptr=&buffer[index+2]; break; case 0x22: // set country code if(nlen!=3) { badnano=true; break; } // break; case 0x95: // unknown if(nlen!=2) { badnano=true; break; } // break; case 0x1E: // unknown if(nlen!=15) { badnano=true; break; } // break; case 0x1F: // unknown if(nlen!=3) { badnano=true; break; } // break; case 0x16: // unknown if(nlen!=2) { badnano=true; break; } // break; case 0x12: // unknown if(nlen!=6) { badnano=true; break; } // break; default: PRINTF(L_SYS_EMM,"%d: unhandled nano 0x%02x",CardNum(),nano); break; } index+=nlen+2; } if(badnano || index!=maxIndex) { PRINTF(L_SYS_EMM,"%d: bad nano/bad paket",CardNum()); return; } // lastKey: save cpu time if we get bursts of the same key if((numKeys>0 && (id[0]!=lastKey || numKeys>1)) || mk) { memcpy(savebuf,buffer,n); // save the buffer cIrdCardInfo *ci=Icards.First(); while(ci) { ci->hexBase=cParseIrdeto::AddrBase(buffer); if((numKeys>0 && (ci->cProviderIrdeto::MatchEMM(buffer) || CheckNull(ci->provId,sizeof(ci->provId)) )) || (mk && ci->haveHMK && (ci->cCardIrdeto::MatchEMM(buffer)))) { LBSTARTF(L_SYS_EMM); LBPUT("%02x %02x%02x%02x",buffer[3],buffer[4],buffer[5],buffer[6]); for(i=0 ; i<numKeys ; i++) { lastKey=id[i]; SessionKeyCrypt(pk[i],ci->PMK,date); } unsigned char chkkey[max(sizeof(ci->PMK),sizeof(ci->HMK))]; int keylen; if(mk) { memcpy(chkkey,ci->HMK,sizeof(ci->HMK)); // key is modified in decryptIrd() DecryptIrd(mk,chkkey,128,16); keylen=sizeof(ci->HMK); memcpy(chkkey,ci->HMK,sizeof(ci->HMK)); // signature check with HMK } else { keylen=sizeof(ci->PMK); memcpy(chkkey,ci->PMK,sizeof(ci->PMK)); // signature check with PMK } memcpy(&buffer[sindex-6],adr,5); if(SignatureCheck(&buffer[sindex-6],slen+6,chkkey,date,&buffer[sindex+slen],keylen)) { char str[20]; LBPUT(" - OK"); for(i=0 ; i<numKeys ; i++) LBPUT(" - PK %02x %s",id[i],KeyStr(str,pk[i])); if(mk) LBPUT(" - PMK %s",KeyStr(str,mk)); for(i=0 ; i<numKeys ; i++) { FoundKey(); if(keys.NewKey('I',ci->provBase,id[i],pk[i],8)) NewKey(); } if(mk) { FoundKey(); if(Icards.Update(ci,mk,prvId[0]?prvId:0)) NewKey(); } cLoaders::SaveCache(); break; } else { LBPUT(" - FAIL"); } LBEND(); memcpy(buffer,savebuf,n); // restore the buffer } ci=Icards.Next(ci); } }}// -- cSystemLinkIrd -----------------------------------------------------------class cSystemLinkIrd : public cSystemLink {public: cSystemLinkIrd(void); virtual bool CanHandle(unsigned short SysId); virtual cSystem *Create(void) { return new cSystemIrd; } virtual bool Init(const char *cfgdir); };static cSystemLinkIrd staticInit;cSystemLinkIrd::cSystemLinkIrd(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){ Feature.NeedsKeyFile();}bool cSystemLinkIrd::CanHandle(unsigned short SysId){ SysId&=SYSTEM_MASK; return SYSTEM_CAN_HANDLE(SysId);}bool cSystemLinkIrd::Init(const char *cfgdir){ Icards.Load(cfgdir,SYSTEM_NAME,"Ird-Beta.KID"); return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -