SASC-NG
DVBSoftCAM

cSmartCardVideoGuard2 Class Reference

Inheritance diagram for cSmartCardVideoGuard2:

List of all members.

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)

Detailed Description

Definition at line 460 of file sc-videoguard2.c.


Constructor & Destructor Documentation

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;
}

Member Function Documentation

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().

Referenced by DoCmd(), and Init().

{
  unsigned char cmd2[5], resp[16];
  memcpy(cmd2,cmd,5);
  cmd2[3]=0x80;
  cmd2[4]=1;
  if(!IsoRead(cmd2,resp) || !Status()) {
    PRINTF(L_SC_ERROR,"failed to read %02x%02x cmd length",cmd[1],cmd[2]);
    return -1;
    }
  return resp[0];  
}
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;
}

The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines