|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cSmartCardVideoGuard2:Public Member Functions | |
| void | ReadTiers (void) |
| void | RevDateCalc (const unsigned char *Date, int &year, int &mon, int &day, int &hh, int &mm, int &ss) |
| void | Datecalc (int year, int mon, int day, int hh, int mm, int ss, unsigned char *Date) |
| int | DoCmd (const unsigned char *ins, const unsigned char *txbuff=0, unsigned char *rxbuff=0) |
| int | ReadCmdLen (const unsigned char *cmd) |
| cSmartCardVideoGuard2 (void) | |
| ~cSmartCardVideoGuard2 () | |
| virtual bool | Init (void) |
| virtual bool | Decode (const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw) |
| virtual bool | Update (int pid, int caid, const unsigned char *data) |
| virtual bool | CanHandle (unsigned short SysId) |
Definition at line 460 of file sc-videoguard2.c.
| cSmartCardVideoGuard2::cSmartCardVideoGuard2 | ( | void | ) |
Definition at line 510 of file sc-videoguard2.c.
:cSmartCard(&cardCfg,msgs) { cmdList=0; CAID=0; }
| cSmartCardVideoGuard2::~cSmartCardVideoGuard2 | ( | void | ) |
Definition at line 516 of file sc-videoguard2.c.
{
delete cmdList;
}
| bool cSmartCardVideoGuard2::CanHandle | ( | unsigned short | SysId | ) | [virtual] |
Reimplemented from cSmartCard.
Definition at line 521 of file sc-videoguard2.c.
{
return SysId==CAID;
}
| void cSmartCardVideoGuard2::Datecalc | ( | int | year, |
| int | mon, | ||
| int | day, | ||
| int | hh, | ||
| int | mm, | ||
| int | ss, | ||
| unsigned char * | Date | ||
| ) |
Definition at line 757 of file sc-videoguard2.c.
References BASEYEAR.
{
Date[0]=((year-BASEYEAR)*12 + (mon-1));
Date[1]=day;
Date[2]=hh*8+mm/8;
Date[3]=ss/2+mm*32;
}
| bool cSmartCardVideoGuard2::Decode | ( | const cEcmInfo * | ecm, |
| const unsigned char * | data, | ||
| unsigned char * | cw | ||
| ) | [virtual] |
Implements cSmartCard.
Definition at line 653 of file sc-videoguard2.c.
References DoCmd(), and cSmartCard::Status().
{
static unsigned char ins40[5] = { 0xD1,0x40,0x40,0x80,0xFF };
static const unsigned char ins54[5] = { 0xD3,0x54,0x00,0x00,0x00 };
int posECMpart2=data[6]+7;
int lenECMpart2=data[posECMpart2]+1;
unsigned char tbuff[264];
tbuff[0]=0;
memcpy(&tbuff[1],&data[posECMpart2+1],lenECMpart2);
ins40[4]=lenECMpart2;
if(DoCmd(ins40,tbuff)>0 && Status()) {
if(DoCmd(ins54)>0 && Status()) {
if(data[0]&1) memcpy(cw+8,CW1,8);
else memcpy(cw+0,CW1,8);
return true;
}
}
return false;
}
| int cSmartCardVideoGuard2::DoCmd | ( | const unsigned char * | ins, |
| const unsigned char * | txbuff = 0, |
||
| unsigned char * | rxbuff = 0 |
||
| ) |
Definition at line 765 of file sc-videoguard2.c.
References b, CmdTable::GetInfo(), cSmartCard::IsoRead(), cSmartCard::IsoWrite(), cCamCryptVG2::PostProcess_Decrypt(), ReadCmdLen(), cSmartCard::sb, and cSmartCard::Status().
Referenced by Decode(), Init(), ReadTiers(), and Update().
{
unsigned char ins2[5];
memcpy(ins2,ins,5);
unsigned char len=0, mode=0;
if(cmdList->GetInfo(ins2,len,mode)) {
if(len==0xFF && mode==2) {
if(ins2[4]==0) ins2[4]=len=ReadCmdLen(ins2);
}
else if(mode!=0) ins2[4]=len;
}
if(ins2[0]==0xd3) ins2[4]=len+16;
len=ins2[4];
unsigned char b[256], tmp[264];
if(!rxbuff) rxbuff=tmp;
if(mode>1) {
if(!IsoRead(ins2,b) || !Status()) return -1;
memcpy(rxbuff,ins2,5);
memcpy(rxbuff+5,b,len);
memcpy(rxbuff+5+len,sb,2);
}
else {
if(!IsoWrite(ins2,txbuff) || !Status()) return -1;
memcpy(rxbuff,ins2,5);
memcpy(rxbuff+5,txbuff,len);
memcpy(rxbuff+5+len,sb,2);
}
state.PostProcess_Decrypt(rxbuff,len,CW1,CW2);
return len;
}
| bool cSmartCardVideoGuard2::Init | ( | void | ) | [virtual] |
Implements cSmartCard.
Definition at line 526 of file sc-videoguard2.c.
References cProviders::AddProv(), cSmartCard::atr, cInfoStr::Begin(), cSmartCardDataVideoGuard2::boxid, cSmartCard::CaidsChanged(), DoCmd(), dtBoxId, dtSeed, cSmartCards::FindCardData(), cCamCryptVG2::GetCamKey(), HexStr(), Atr::hist, Atr::histLen, i, cSmartCard::idStr, cSmartCard::infoStr, cSmartCard::IsoRead(), L_SC_ERROR, L_SC_INIT, cSmartCard::NewCardConfig(), cLineBuff::Printf(), PRINTF, ReadCmdLen(), ReadTiers(), cIdSet::ResetIdSet(), SC_NAME, cSmartCardDataVideoGuard2::seed0, cSmartCardDataVideoGuard2::seed1, cIdSet::SetCard(), cCamCryptVG2::SetSeed(), smartcards, cSmartCard::Status(), cLineBuff::Strcat(), and WORD.
{
static const unsigned char vg2Hist[] = { 'i',0xff,'J','P' };
if(atr->histLen<4 || memcmp(&atr->hist[3],vg2Hist,4)) {
PRINTF(L_SC_INIT,"doesn't look like a VideoGuard2 card");
return false;
}
infoStr.Begin();
infoStr.Strcat("VideoGuard2 smartcard\n");
snprintf(idStr,sizeof(idStr),"%s (%c%c.%d)",SC_NAME,atr->hist[10],atr->hist[11],atr->hist[12]);
ResetIdSet();
delete cmdList; cmdList=0;
static unsigned char ins7401[] = { 0xD0,0x74,0x01,0x00,0x00 };
int l;
if((l=ReadCmdLen(ins7401))<0) {
PRINTF(L_SC_ERROR,"bogus answer. Now try delayed mode");
NewCardConfig(&cardCfgDelay);
if((l=ReadCmdLen(ins7401))<0) return false;
}
ins7401[4]=l;
unsigned char buff[256];
if(!IsoRead(ins7401,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to read cmd list");
return false;
}
cmdList=new CmdTable(buff,l);
static const unsigned char ins7416[5] = { 0xD0,0x74,0x16,0x00,0x00 };
if(DoCmd(ins7416)<0 || !Status()) {
PRINTF(L_SC_ERROR,"cmd 7416 failed");
return false;
}
static const unsigned char ins36[5] = { 0xD0,0x36,0x00,0x00,0x00 };
bool boxidOK=false;
if((l=DoCmd(ins36,0,buff))>0 && Status())
for(int i=0; i<l ;i++) {
if(buff[i]==0x00 && buff[i+1]==0xF3) {
memcpy(&boxID,&buff[i+2],sizeof(boxID));
boxidOK=true;
break;
}
}
if(!boxidOK) {
cSmartCardDataVideoGuard2 cd(dtBoxId);
cSmartCardDataVideoGuard2 *entry=(cSmartCardDataVideoGuard2 *)smartcards.FindCardData(&cd);
if(entry) {
memcpy(&boxID,entry->boxid,sizeof(boxID));
boxidOK=true;
}
}
if(!boxidOK) {
PRINTF(L_SC_ERROR,"no boxID available");
return false;
}
static const unsigned char ins4C[5] = { 0xD0,0x4C,0x00,0x00,0x00 };
static unsigned char payload4C[9] = { 0,0,0,0, 3,0,0,2,4 };
memcpy(payload4C,boxID,4);
if(DoCmd(ins4C,payload4C)<0 || !Status()) {
PRINTF(L_SC_ERROR,"sending boxid failed");
return false;
}
static const unsigned char ins58[5] = { 0xD0,0x58,0x00,0x00,0x00 };
if(DoCmd(ins58,0,buff)<0 || !Status()) {
PRINTF(L_SC_ERROR,"failed to read card details");
return false;
}
unsigned int c=WORD(buff,0x1D,0xFFFF);
if(c!=CAID) CaidsChanged();
CAID=c;
memcpy(&cardID,&buff[8],4);
memcpy(&groupID,&buff[8],4); groupID[3]=0;
SetCard(new cCardNDS(cardID));
AddProv(new cProviderNDS(groupID));
char str[20], str2[20];
infoStr.Printf("Cardtype: %c%c.%d\n"
"BoxID %s Caid %04x CardID %s\n",
atr->hist[10],atr->hist[11],atr->hist[12],HexStr(str,boxID,4),CAID,HexStr(str2,cardID,4));
PRINTF(L_SC_INIT,"cardtype: %c%c.%d boxID %s caid %04x cardID %s",atr->hist[10],atr->hist[11],atr->hist[12],HexStr(str,boxID,4),CAID,HexStr(str2,cardID,4));
cSmartCardDataVideoGuard2 cd(dtSeed);
cSmartCardDataVideoGuard2 *entry=(cSmartCardDataVideoGuard2 *)smartcards.FindCardData(&cd);
if(!entry) {
PRINTF(L_SC_ERROR,"no NDS seed available");
return false;
}
state.SetSeed(entry->seed0,entry->seed1);
unsigned char tbuff[64];
state.GetCamKey(tbuff);
static const unsigned char insB4[5] = { 0xD0,0xB4,0x00,0x00,0x00 };
if(DoCmd(insB4,tbuff)<0 || !Status()) {
PRINTF(L_SC_ERROR,"cmd D0B4 failed");
return false;
}
static const unsigned char insBC[5] = { 0xD0,0xBC,0x00,0x00,0x00 };
if(DoCmd(insBC)<0 || !Status()) {
PRINTF(L_SC_ERROR,"cmd D0BC failed");
return false;
}
static const unsigned char insBE[5] = { 0xD3,0xBE,0x00,0x00,0x00 };
if(DoCmd(insBE)<0 || !Status()) {
PRINTF(L_SC_ERROR,"cmd D3BE failed");
return false;
}
static const unsigned char ins58a[5] = { 0xD1,0x58,0x00,0x00,0x00 };
if(DoCmd(ins58a)<0 || !Status()) {
PRINTF(L_SC_ERROR,"cmd D158 failed");
return false;
}
static const unsigned char ins4Ca[5] = { 0xD1,0x4C,0x00,0x00,0x00 };
if(DoCmd(ins4Ca,payload4C)<0 || !Status()) {
PRINTF(L_SC_ERROR,"cmd D14C failed");
return false;
}
ReadTiers();
return true;
}
| int cSmartCardVideoGuard2::ReadCmdLen | ( | const unsigned char * | cmd | ) |
Definition at line 797 of file sc-videoguard2.c.
References cSmartCard::IsoRead(), L_SC_ERROR, PRINTF, and cSmartCard::Status().
| void cSmartCardVideoGuard2::ReadTiers | ( | void | ) |
Definition at line 720 of file sc-videoguard2.c.
References DoCmd(), i, cSmartCard::infoStr, cSmartCard::IsoRead(), L_SC_INIT, PRINTF, RevDateCalc(), cSmartCard::Status(), and cLineBuff::Strcat().
Referenced by Init().
{
static const unsigned char ins2a[5] = { 0xd0,0x2a,0x00,0x00,0x00 };
if(DoCmd(ins2a)<0 || !Status()) return;
static unsigned char ins76[5] = { 0xd0,0x76,0x00,0x00,0x00 };
ins76[3]=0x7f; ins76[4]=2;
unsigned char buff[270];
if(!IsoRead(ins76,buff) || !Status()) return;
ins76[3]=0; ins76[4]=0;
int num=buff[1];
if(num>0) {
infoStr.Strcat("Tier\tExpiry Date\n");
infoStr.Strcat("----\t-----------\n");
}
for(int i=0; i<num; i++) {
ins76[2]=i;
if(DoCmd(ins76,0,buff)<0 || !Status()) return;
if(buff[5+2]==0 && buff[5+3]==0) break;
int y,m,d,H,M,S;
RevDateCalc(&buff[5+4],y,m,d,H,M,S);
char str[100];
snprintf(str,sizeof(str),"%02x%02x\t%04d/%02d/%02d-%02d:%02d:%02d\n",buff[5+2],buff[5+3],y,m,d,H,M,S);
infoStr.Strcat(str);
PRINTF(L_SC_INIT,"Tier %02x%02x expires %04d/%02d/%02d-%02d:%02d:%02d",buff[5+2],buff[5+3],y,m,d,H,M,S);
}
}
| void cSmartCardVideoGuard2::RevDateCalc | ( | const unsigned char * | Date, |
| int & | year, | ||
| int & | mon, | ||
| int & | day, | ||
| int & | hh, | ||
| int & | mm, | ||
| int & | ss | ||
| ) |
Definition at line 747 of file sc-videoguard2.c.
References BASEYEAR.
Referenced by ReadTiers().
{
year=(Date[0]/12)+BASEYEAR;
mon=(Date[0]%12)+1;
day=Date[1];
hh=Date[2]/8;
mm=(0x100*(Date[2]-hh*8)+Date[3])/32;
ss=(Date[3]-mm*32)*2;
}
| bool cSmartCardVideoGuard2::Update | ( | int | pid, |
| int | caid, | ||
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cSmartCard.
Definition at line 673 of file sc-videoguard2.c.
References DoCmd(), cIdSet::MatchEMM(), cParseNDS::PayloadStart(), and cSmartCard::Status().
{
static unsigned char ins42[5] = { 0xD1,0x42,0x00,0x00,0xFF };
if(MatchEMM(data)) {
const unsigned char *payloaddata=cParseNDS::PayloadStart(data,cardID); //points to 02 xx yy
int lenEMM;
switch(payloaddata[0]) {
case 2:
lenEMM=payloaddata[payloaddata[1]+2];
payloaddata+=3+payloaddata[1]; // skip len specifier
break;
default:
// di(printf("scvg2: ***ERROR***: EMM: bad payload type byte %02x\n",payloaddata[0]));
// DUMP3("VG2EMM",data,32);
return false;
}
// di(printf("scvg2: EMM: pid %d (%x) caid %d (%x) len %d (%x)\n",pid,pid,caid,caid,lenEMM,lenEMM));
// DUMP3("VG2EMM",data,32);
if(lenEMM<=8 || lenEMM>188) {
// di(printf("scvg2: ***ERROR***: EMM: len %d bad\n",lenEMM));
return false;
}
ins42[4]=lenEMM;
if(DoCmd(ins42,payloaddata)>0 && Status())
return true;
}
return false;
}