|
SASC
DVBSoftCAM
|
Inheritance diagram for cSystemCryptoworks:Public Member Functions | |
| cSystemCryptoworks (void) | |
| virtual bool | ProcessECM (const cEcmInfo *ecmInfo, unsigned char *data) |
| cSystemCryptoworks (void) | |
| virtual bool | ProcessECM (const cEcmInfo *ecmInfo, unsigned char *data) |
Definition at line 409 of file cryptoworks.c.
| cSystemCryptoworks::cSystemCryptoworks | ( | void | ) |
Definition at line 417 of file cryptoworks.c.
:cSystem(SYSTEM_NAME,SYSTEM_PRI) { // hasLogger=true; }
| cSystemCryptoworks::cSystemCryptoworks | ( | void | ) |
| bool cSystemCryptoworks::ProcessECM | ( | const cEcmInfo * | ecmInfo, |
| unsigned char * | data | ||
| ) | [virtual] |
Implements cSystem.
Definition at line 423 of file cryptoworks.c.
References cEcmInfo::caId, CCID, CCTYP, cSystem::cw, cCryptoworks::DecryptDES(), cCryptoworks::DecryptRSA(), cSystem::doLog, DUMPNANO, ECM_ALGO_TYP, ECM_DATA_START, ECM_NANO_LEN, ECM_NANO_START, cPlainKeys::FindKey(), cPlainKey::Get(), i, j, keys, KEYSET, L_SYS_ECM, L_SYS_KEY, L_SYS_VERBOSE, LDUMP, mod, cKeySnoop::OK(), PRINTF, prov, SCT_LEN, and cCryptoworks::Signature().
{
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;
}
| virtual bool cSystemCryptoworks::ProcessECM | ( | const cEcmInfo * | ecmInfo, |
| unsigned char * | data | ||
| ) | [virtual] |
Implements cSystem.