⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc-nagra.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
#define HAS_CW      ((status[1]&1)&&((status[3]&6)==6))class cSmartCardNagra : public cSmartCard, private cCamCryptNagra {private:  unsigned char buff[MAX_LEN+1], status[4], cardId[4], irdId[4], block;  unsigned short provId[MAX_REC], irdProvId;  //  bool GetCardStatus(void);  bool GetDataType(unsigned char dt, int len, int shots=MAX_REC);  bool ParseDataType(unsigned char dt);  bool DoCamExchange(const unsigned char *key);  void Date(const unsigned char *date, char *dt, char *ti);  bool DoBlkCmd(unsigned char cmd, int ilen, unsigned char res, int rlen, const unsigned char *data=0);  bool SetIFS(unsigned char len);public:  cSmartCardNagra(void);  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);  };static const struct StatusMsg msgs[] = {  { { 0x6F,0x00 }, "Instruction not supported", false },  { { 0x90,0x00 }, "Instruction executed without errors", true },  { { 0xFF,0xFF }, 0, false }  };static const struct CardConfig cardCfg = {  SM_8O2,500,800  };cSmartCardNagra::cSmartCardNagra(void):cSmartCard(&cardCfg,msgs){  block=0;}bool cSmartCardNagra::SetIFS(unsigned char size){  unsigned char buf[5];  // NAD, PCB, LEN  NAD(buf)=N2_NAD; PCB(buf)=SETIFS; LEN(buf)=1;  // Information Field size  buf[3]=size; buf[4]=XorSum(buf,4);  if(SerWrite(buf,5)!=5) {    PRINTF(L_SC_ERROR,"failed to write IFS command");    return false;    }  if(SerRead(buff,5,cardCfg.workTO)!=5 || XorSum(buff,5)) {    PRINTF(L_SC_ERROR,"setting IFS to %02x failed",size);    return false;    }  return true;}bool cSmartCardNagra::GetCardStatus(void){  if(!DoBlkCmd(0xC0,0x02,0xB0,0x06) || !Status()) {    PRINTF(L_SC_ERROR,"failed to read card status");    return false;    }  memcpy(status,buff+5,4);  return true;}bool cSmartCardNagra::Init(void){  static const unsigned char verifyBytes[] = { 'D','N','A','S','P','1' };  if(atr->T!=1 || (atr->histLen<8 && memcmp(atr->hist,verifyBytes,sizeof(verifyBytes)))) {    PRINTF(L_SC_INIT,"doesn't look like a nagra V2 card");    return false;    }  infoStr.Begin();  infoStr.Strcat("Nagra smartcard\n");  char rom[12], rev[12];  snprintf(rom,sizeof(rom),"%.3s",(char*)&atr->hist[5]);  snprintf(rev,sizeof(rev),"%.3s",(char*)&atr->hist[12]);  PRINTF(L_SC_INIT,"card version: %s revision: %s",rom,rev);  infoStr.Printf("Card v.%s Rev.%s\n",rom,rev);  if(!GetCardStatus() || !SetIFS(0x80)) return false;  // get UA/CardID here  if(!DoBlkCmd(0x12,0x02,0x92,0x06) || !Status()) return false;  memcpy(cardId,buff+5,4);  if(!GetDataType(IRDINFO,0x39) || !GetDataType(0x04,0x44)) return false;  infoStr.Printf("Tiers\n");  infoStr.Printf("|id  |tier low|tier high| dates    |\n");  infoStr.Printf("+----+--------+---------+----------+\n");  if(!GetDataType(TIERS,0x57))    PRINTF(L_SC_ERROR,"failed to get tiers");      if(!GetDataType(CAMDATA,0x55,1)) return false;  unsigned char key[16];  cSmartCardDataNagra *entry=0;  bool sessOk=false;  if(buff[5]!=0 && irdProvId==((buff[10]*256)|buff[11])) { // prepare DT08 data    cSmartCardDataNagra cd(irdProvId,true);    if(!(entry=(cSmartCardDataNagra *)smartcards.FindCardData(&cd))) {      PRINTF(L_GEN_WARN,"didn't find smartcard Nagra IRD modulus");      }    else {      InitCamKey(key,entry->bk,irdId);      if(DecryptCamMod(buff+3,key,cardId,entry->mod)) sessOk=true;      }    }  else {    cSmartCardDataNagra cd(irdProvId);    if(!(entry=(cSmartCardDataNagra *)smartcards.FindCardData(&cd))) {      PRINTF(L_GEN_WARN,"didn't find smartcard Nagra CAM modulus");      }    else {      InitCamKey(key,entry->bk,cardId);      SetCamMod(entry->mod);      if(GetDataType(0x08,0x03,1)) sessOk=true;;      }    }  if(sessOk) DoCamExchange(key);  infoStr.Finish();  return true;}bool cSmartCardNagra::GetDataType(unsigned char dt, int len, int shots){  for(int i=0; i<shots; i++) {    if(!DoBlkCmd(0x22,0x03,0xA2,len,&dt) || !Status()) {     PRINTF(L_SC_ERROR,"failed to get datatype %02X",dt);     return false;     }    if(buff[5]==0) return true;    if(!ParseDataType(dt&0x0F)) return false;    dt|=0x80; // get next item    }  return true;}bool cSmartCardNagra::ParseDataType(unsigned char dt){  switch(dt) {   case IRDINFO:     {     irdProvId=(buff[10]*256)|buff[11];     char id[12];     memcpy(irdId,buff+17,4);     LDUMP(L_SC_INIT,irdId,4,"IRD system-ID: %04X, IRD ID:",irdProvId);     HexStr(id,irdId,sizeof(irdId));     infoStr.Printf("IRD system-ID: %04X\nIRD ID: %s\n",irdProvId,id);     return true;     }   case TIERS:     if(buff[7]==0x88 || buff[7]==0x08  || buff[7]==0x0C) {       int id=(buff[10]*256)|buff[11];       int tLowId=(buff[20]*256)|buff[21];       int tHiId=(buff[31]*256)|buff[32];       char date1[12], time1[12], date2[12], time2[12];       Date(buff+23,date1,time1);       Date(buff+27,date2,time2);       infoStr.Printf("|%04X|%04X    |%04X     |%s|\n",id,tLowId,tHiId,date1);       infoStr.Printf("|    |        |         |%s|\n",date2);       PRINTF(L_SC_INIT,"|%04X|%04X|%04X|%s|%s|",id,tLowId,tHiId,date1,time1);       PRINTF(L_SC_INIT,"|    |    |    |%s|%s|",date2,time2);       }   default:     return true;   }  return false;}bool cSmartCardNagra::DoCamExchange(const unsigned char *key){  if(!GetCardStatus()) return false;  if(!DoBlkCmd(0x2A,0x02,0xAA,0x42) || !Status()) return false;  if(buff[4]!=64) {    PRINTF(L_SC_ERROR,"reading CAM 2A data failed");    return false;    }  unsigned char res[64];  if(!DecryptCamData(res,key,buff+5)) return false;  if(!DoBlkCmd(0x2B,0x42,0xAB,0x02,res) || !Status()) return false;  return true;}void cSmartCardNagra::Date(const unsigned char *data, char *dt, char *ti){  int date=(data[0]<<8)|data[1];  int time=(data[2]<<8)|data[3];  struct tm t;  memset(&t,0,sizeof(struct tm));  t.tm_min =0;//-300;  t.tm_year=92;  t.tm_mday=date + 1;  t.tm_sec =(time - 1) * 2;  mktime(&t);  snprintf(dt,11,"%.2d.%.2d.%.4d",t.tm_mon+1,t.tm_mday,t.tm_year+1900);  snprintf(ti,9,"%.2d:%.2d:%.2d",t.tm_hour,t.tm_min,t.tm_sec);}bool cSmartCardNagra::Decode(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw){  if(DoBlkCmd(data[3],data[4]+2,0x87,0x02,data+3+2) && Status()) {    cCondWait::SleepMs(100);    if(GetCardStatus() && HAS_CW &&       DoBlkCmd(0x1C,0x02,0x9C,0x36) && Status() &&       DecryptCW(cw,buff)) return true;    }  return false;}bool cSmartCardNagra::Update(int pid, int caid, const unsigned char *data){  if(DoBlkCmd(data[8],data[9]+2,0x84,0x02,data+8+2) && Status()) {    cCondWait::SleepMs(500);    if(GetCardStatus()) return true;    }  return false;}bool cSmartCardNagra::DoBlkCmd(unsigned char cmd, int ilen, unsigned char res, int rlen, const unsigned char *data){  unsigned char msg[MAX_LEN+3+1];  NAD(msg)=N2_NAD; PCB(msg)=0; PCB(msg)^=block; block^=0x40; LEN(msg)=ilen+6;  CLA(msg)=N2_CLA; INS(msg)=N2_INS; P1(msg)=N2_P1; P2(msg)=N2_P2; L(msg)=ilen;  int dlen=ilen-2;  if(dlen<0) {    PRINTF(L_SC_ERROR,"invalid data length encountered");    return false;    }  N2_CMD(msg)=cmd; N2_CLEN(msg)=dlen;  if(data && dlen>0) memcpy(&N2_DATA(msg),data,dlen);  int msglen=LEN(msg)+3;  msg[msglen-1]=rlen;  msg[msglen]=XorSum(msg,msglen);  msglen++;  if(SerWrite(msg,msglen)==msglen) {    LDUMP(L_CORE_SC,msg,msglen,"NAGRA: <-");    cCondWait::SleepMs(10);    if(SerRead(buff,3,cardCfg.workTO)!=3) {      PRINTF(L_SC_ERROR,"reading back reply failed");      return false;      }    int reslen=buff[2]+1;    if(SerRead(buff+3,reslen,cardCfg.workTO)!=reslen) {      PRINTF(L_SC_ERROR,"reading back information block failed");      return false;      }    if(XorSum(buff,reslen+3)) {      PRINTF(L_SC_ERROR,"checksum failed");      return false;      }    LDUMP(L_CORE_SC,buff,3+reslen,"NAGRA: ->");    if(buff[3]!=res) {      PRINTF(L_SC_ERROR,"result not expected (%02X != %02X)",buff[3],res);      return false;      }    memcpy(sb,&buff[3+rlen],2);    LDUMP(L_CORE_SC,sb,2,"NAGRA: ->");    cCondWait::SleepMs(10);    return true;    }  return false;}// -- cSmartCardLinkNagra -------------------------------------------------------------class cSmartCardLinkNagra : public cSmartCardLink {public:  cSmartCardLinkNagra(void):cSmartCardLink(SC_NAME,SC_ID) {}  virtual cSmartCard *Create(void) { return new cSmartCardNagra(); }  virtual cSmartCardData *CreateData(void) { return new cSmartCardDataNagra; }  };static cSmartCardLinkNagra staticScInit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -