|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cSystemViaccess:Public Member Functions | |
| cSystemViaccess (void) | |
| virtual bool | ProcessECM (const cEcmInfo *ecm, unsigned char *data) |
| virtual void | ProcessEMM (int pid, int caid, const unsigned char *data) |
| virtual void | ParseCADescriptor (cSimpleList< cEcmInfo > *ecms, unsigned short sysId, int source, const unsigned char *data, int len) |
Definition at line 353 of file viaccess.c.
| cSystemViaccess::cSystemViaccess | ( | void | ) |
Definition at line 363 of file viaccess.c.
References cSystem::hasLogger.
:cSystem(SYSTEM_NAME,SYSTEM_PRI) { hasLogger=true; }
| void cSystemViaccess::ParseCADescriptor | ( | cSimpleList< cEcmInfo > * | ecms, |
| unsigned short | sysId, | ||
| int | source, | ||
| const unsigned char * | data, | ||
| int | len | ||
| ) | [virtual] |
Reimplemented from cSystem.
Definition at line 369 of file viaccess.c.
References L_CORE_ECMPROC, PRINTF, and WORD.
{
const int pid=WORD(data,2,0x1FFF);
if(pid>=0xAA && pid<=0xCF) {
PRINTF(L_CORE_ECMPROC,"viaccess: dropped \"fake\" ecm pid 0x%04x",pid);
return;
}
cSystem::ParseCADescriptor(ecms,sysId,source,data,len);
}
| bool cSystemViaccess::ProcessECM | ( | const cEcmInfo * | ecm, |
| unsigned char * | data | ||
| ) | [virtual] |
Implements cSystem.
Definition at line 379 of file viaccess.c.
References cParseViaccess::CheckNano90FromNano(), cSystem::cw, data, cViaccess::Decrypt(), cTPS::Decrypt(), cPlainKeys::FindKey(), cPlainKey::Get(), cParseViaccess::KeyNrFromNano(), keys, cSystem::maxEcmTry, cKeySnoop::OK(), cParseViaccess::PayloadStart(), cTPS::PostProc(), cEcmInfo::provId, SCT_LEN, cViaccess::SetV2Mode(), cPlainKey::Size(), cEcmInfo::source, cEcmInfo::transponder, VIA1_KEYLEN, and VIA2_KEYLEN.
{
unsigned char *nanos=(unsigned char *)cParseViaccess::PayloadStart(data);
int len=SCT_LEN(data)-(nanos-data);
bool mayHaveTps=false;
if(ecm->provId==0x007c00) { // TPS
maxEcmTry=4;
mayHaveTps=true;
int num=tps.Decrypt(this,ecm->source,ecm->transponder,nanos,len);
if(num<0) return false;
nanos+=num; len-=num;
}
if(cParseViaccess::CheckNano90FromNano(nanos)) {
int keynr=cParseViaccess::KeyNrFromNano(nanos);
cKeySnoop ks(this,'V',ecm->provId,keynr);
cPlainKey *pk=0;
while((pk=keys.FindKey('V',ecm->provId,keynr,-1,pk))) {
unsigned char key[16];
if(pk->Size()<=(int)sizeof(key)) {
pk->Get(key);
SetV2Mode(pk->Size()==VIA2_KEYLEN ? &key[VIA1_KEYLEN] : 0);
if(cViaccess::Decrypt(key,&nanos[5],len-5,&cw[0],&cw[8])) {
if(mayHaveTps) tps.PostProc(cw);
ks.OK(pk);
return true;
}
}
}
}
return false;
}
| void cSystemViaccess::ProcessEMM | ( | int | pid, |
| int | caid, | ||
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cSystem.
Definition at line 413 of file viaccess.c.
References cAssembleData::Assembled(), b, cViaccess::Decode(), cStructList< T >::First(), cSystem::FoundKey(), cViaccess::Hash(), cViaccess::HashByte(), cViaccess::HashClear(), cViaccess::hbuff, HexStr(), k7, cParseViaccess::KeyNrFromNano(), keys, L_SYS_EMM, MAX_NEW_KEYS, cParseViaccess::NanoStart(), cSystem::NewKey(), cPlainKeys::NewKey(), cStructList< T >::Next(), cViaccess::pH, PRINTF, SCT_LEN, and cViaccess::SetHashKey().
{
for(cViaccessCardInfo *mkey=Vcards.First(); mkey; mkey=Vcards.Next(mkey)) {
int updtype;
cAssembleData ad(data);
if(mkey->cCardViaccess::MatchEMM(data)) {
updtype=3;
HashClear();
memcpy(hbuff+3,mkey->ua,sizeof(mkey->ua));
}
else if(mkey->cProviderViaccess::MatchEMM(data)) {
if(mkey->cProviderViaccess::Assemble(&ad)<0) continue;
updtype=2;
HashClear();
memcpy(hbuff+5,mkey->sa,sizeof(mkey->sa)-1);
}
else continue;
const unsigned char *buff;
if((buff=ad.Assembled())) {
const unsigned char *scan=cParseViaccess::NanoStart(buff);
unsigned int scanlen=SCT_LEN(buff)-(scan-buff);
if(scanlen>=5 && mkey->cProviderViaccess::MatchID(buff) &&
cParseViaccess::KeyNrFromNano(scan)==mkey->keyno) {
scan+=5; scanlen-=5;
SetHashKey(mkey->key);
Hash();
unsigned int n;
if(scan[0]==0x9e && scanlen>=(n=scan[1]+2)) {
for(unsigned int i=0; i<n; i++) HashByte(scan[i]);
Hash(); pH=0;
scan+=n; scanlen-=5;
}
if(scanlen>0) {
unsigned char newKey[MAX_NEW_KEYS][8];
int numKeys=0, updPrv[MAX_NEW_KEYS]={}, updKey[MAX_NEW_KEYS]={};
for(unsigned int cnt=0; cnt<scanlen && numKeys<MAX_NEW_KEYS;) {
const unsigned int parm=scan[cnt++];
unsigned int plen=scan[cnt++];
switch(parm) {
case 0x90:
case 0x9E:
cnt+=plen;
break;
case 0xA1: // keyupdate
updPrv[numKeys]=(scan[cnt]<<16)+(scan[cnt+1]<<8)+(scan[cnt+2]&0xF0);
updKey[numKeys]=scan[cnt+2]&0x0F;
// fall through
default:
HashByte(parm); HashByte(plen);
while(plen--) HashByte(scan[cnt++]);
break;
case 0xEF: // crypted key(s)
HashByte(parm); HashByte(plen);
if(plen==sizeof(newKey[0])) {
const unsigned char k7=mkey->key[7];
for(unsigned int kc=0 ; kc<sizeof(newKey[0]) ; kc++) {
const unsigned char b=scan[cnt++];
if(k7&1) newKey[numKeys][kc]=b^(hbuff[pH]&(k7<0x10 ? 0x5a : 0xa5));
else newKey[numKeys][kc]=b;
HashByte(b);
}
numKeys++;
}
else {
PRINTF(L_SYS_EMM,"key length mismatch %d!=%d",plen,(int)sizeof(newKey[0]));
cnt=scanlen;
}
break;
case 0xF0: // signature
{
char str[20], str2[20];
static const char *ptext[] = { 0,0,"SHARED","UNIQUE" };
const char *addr = (updtype==2) ? HexStr(str,mkey->sa,sizeof(mkey->sa)) : HexStr(str,mkey->ua,sizeof(mkey->ua));
Hash();
if(!memcmp(&scan[cnt],hbuff,sizeof(hbuff))) {
unsigned char key[8];
memcpy(key,mkey->key,sizeof(key));
if(key[7]) { // Rotate key
const unsigned char t1=key[0], t2=key[1];
key[0]=key[2]; key[1]=key[3]; key[2]=key[4]; key[3]=key[5]; key[4]=key[6];
key[5]=t1; key[6]=t2;
}
while(numKeys--) {
Decode(newKey[numKeys],key);
PRINTF(L_SYS_EMM,"%02X%02X %02X %s %s - KEY %06X.%02X -> %s",
mkey->ident[0],mkey->ident[1],mkey->keyno,addr,
ptext[updtype],updPrv[numKeys],updKey[numKeys],
HexStr(str2,newKey[numKeys],sizeof(newKey[numKeys])));
FoundKey();
if(keys.NewKey('V',updPrv[numKeys],updKey[numKeys],newKey[numKeys],8)) NewKey();
}
}
else
PRINTF(L_SYS_EMM,"%02X%02X %02X %s %s - FAIL",mkey->ident[0],mkey->ident[1],mkey->keyno,addr,ptext[updtype]);
cnt=scanlen;
break;
}
}
}
}
}
}
}
}