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

📄 smartcard.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 3 页
字号:
            if(mem[3]==1) {              nextSW[0]=0x94; nextSW[1]=0x02;              dataLen=0;              }            else {              dataLen=0x42;              static const unsigned char resp[0x42] = {                0x83,0x01,0x88,                0x8c,0x03,0xA0,0x30,0x40,                0x8d,0x04,0x16,0xac,0x16,0xba,                0xd5,0x10,'D','u','m','m','y',0,0,0,0,0,0,0,0x12,0x34,0x56,0x67,                0x92,0x20,0x00 // ...                };              memcpy(data,resp,sizeof(resp));              }                break;          case 0x80:            dataLen=0x07;            data[0]=0x80;            data[1]=0x05;            data[2]=0x5c;            data[3]=0x0c;            data[4]=0x00;            data[5]=0xec;            data[6]=0x0a;            break;          case 0xD1:            dataLen=0x04;            data[0]=0xd1;            data[1]=0x02;            data[2]=0x0d;            data[3]=0x22;            break;          case 0x9F:            dataLen=0x03;            data[0]=0x9f;            data[1]=0x01;            data[2]=0x88;            break;          case 0x9E:            {            dataLen=0x42;            static const unsigned char resp[0x42] = {              0x9E,0x40,              0x28,0xFE, /// ...              };            memcpy(data,resp,sizeof(resp));            flag=true;            break;            }          case 0xC0:          case 0xD6:            dataLen=0x12;            data[0]=record;            data[1]=0x10;            memset(data+2,0,16);            strcpy((char *)data+2,"Dum Issuer");            break;          }        break;      case 0xa4b8:        readcmd=true;        if(mem[2]==0) {          dataLen=0x0C;          memset(data,0,0x0c);          data[0]=0xDF;          data[1]=0x0A;          data[4]=0xDF;          data[5]=0x88;          }        else {          dataLen=0;          nextSW[0]=0x94; nextSW[1]=0x02;          }        break;      case 0xa44c:        nextSW[0]=0x9f; nextSW[1]=flag ? 0x42 : 0x1c;        break;      case 0xa4c0:        readcmd=true;        if(mem[4]==0x1c) {          data[0]=0xdb;          data[1]=0x10;          memset(&data[2],0x45,16);          data[18]=0xdf;          data[19]=0x08;          data[20]=0x50;          data[23]=0x80;          }        else if(mem[4]==0x11) {          memset(data,0,0x11);          data[0]=0xdf;          data[1]=0x0f;          data[6]=0x3f;          data[7]=0x6a;          }        else if(mem[4]==0x42) {          static const unsigned char resp[0x42] = {            0xdf,0x40,            0x6d,0xbb,0x81, // ...            };          memcpy(data,resp,sizeof(resp));          }        break;      }    if(readcmd) {      if(dataLen>0) {        PUSHB(mem[INS_IDX]); // ACK byte        PUSH(data,dataLen);        }      PUSH(nextSW,2);      cmdStart=true;      }    else {      PUSHB(mem[INS_IDX]); // ACK byte      }    }  else {    dataLen-=len;    if(dataLen<=0 && !cmdStart) {      PUSH(nextSW,2);      cmdStart=true;      }    }#elif defined(EMU_IRD)  static const struct Resp {    unsigned int cmd;    unsigned char data[MAX_LEN];    } resp[] = {#ifdef EMU_IRD_384  { 0x01020203,    {0x01,0x02,0x00,0x00,0x02,0x00,0x00,0x10,0x03,0x84,0x00,0x00,0x00,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x45,0x52} },  { 0x01020E02,    {0x01,0x02,0x00,0x00,0x0e,0x02,0x00,0x40,0xa9,0x6d,0x73,0x97,0x9e,0xfc,0x9b,0x8e,0x5b,0x8c,0xfa,0xb2,0x0c,0xb2,0x57,0x0f,0xb2,0xf7,0x29,0x4e,0xa2,0xcb,0xbd,0x5b,0x52,0x74,0xb1,0x2a,0xb7,0xc5,0xd9,0x62,0x6d,0x37,0x6d,0x9d,0xa3,0xe9,0x61,0xbb,0x1b,0x2b,0x56,0xb7,0x86,0x0c,0xe6,0xb1,0x07,0x6f,0xe0,0xf8,0x8a,0xd3,0x05,0x83,0xf6,0x53,0x0e,0xd2,0x72,0xd5,0xc1,0x50} },  { 0x01020E03,    {0x01,0x02,0x00,0x00,0x0e,0x03,0x00,0x40,0xb6,0xde,0xa8,0xce,0x86,0x1c,0x42,0x72,0xa8,0x16,0x4b,0xf9,0xce,0x33,0xb5,0x43,0xd0,0x50,0xe6,0xa7,0xf1,0xcb,0x55,0x25,0x97,0x13,0xee,0x62,0x98,0xe7,0x17,0x50,0xeb,0x3b,0x59,0x10,0x0a,0xb6,0x2e,0x93,0x61,0x71,0x3c,0xe6,0xe2,0x2c,0x1e,0x7d,0xbd,0x6a,0x49,0xbb,0x04,0x5b,0xdf,0x2f,0xb7,0xa7,0x93,0xe0,0x3d,0x40,0x4e,0xd1} },#else  { 0x01020203,    {0x01,0x02,0x00,0x00,0x02,0x00,0x00,0x10,0x03,0x83,0x00,0x00,0x00,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x45,0x52} },  { 0x01020E02,    {0x01,0x02,0x00,0x00,0x0E,0x02,0x00,0x40,0x65,0xEF,0xD0,0xA7,0xF3,0x80,0x48,0x0E,0xC1,0x4B,0x41,0x6C,0xDB,0x68,0x47,0xE4,0x23,0xAD,0x96,0x12,0x07,0x58,0x58,0x29,0xE9,0x14,0x27,0x7F,0x7D,0xF8,0xC2,0x65,0x76,0x4D,0x75,0x04,0x7C,0x9B,0xAA,0x99,0x58,0xEA,0xE2,0x43,0xB5,0x03,0x05,0xD6,0x62,0x99,0xF5,0x18,0x16,0x4E,0xCF,0x49,0x11,0xBD,0xF3,0xEE,0xC3,0xCD,0x90,0x3B} },  { 0x01020E03,    {0x01,0x02,0x00,0x00,0x0E,0x03,0x00,0x40,0x9B,0x06,0xB5,0x0A,0x98,0xC6,0x2E,0x1D,0x71,0xA1,0xE8,0x84,0xAE,0x98,0x57,0xE9,0xE6,0xC2,0x97,0x46,0x25,0x7A,0x2B,0xA1,0xD5,0x33,0x18,0xDE,0x16,0xC1,0xAB,0x22,0x2C,0xC2,0x11,0x24,0x81,0x11,0xA8,0x39,0xE3,0xB1,0xDB,0x33,0x1A,0x93,0x31,0xB0,0x61,0xD8,0xDE,0x92,0x1F,0x29,0x20,0xD0,0x9E,0x0F,0x6A,0xF0,0x7C,0xBA,0xCD,0xCC} },#endif  { 0x01020003,    {0x01,0x02,0x00,0x00,0x00,0x03,0x00,0x14,0x37,0x30,0x31,0x32,0x30,0x36,0x39,0x33,0x34,0x37,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },  { 0x01020103,    {0x01,0x02,0x00,0x00,0x01,0x00,0x00,0x10,0x00,0x17,0x00,0x00,0x01,0x00,0x17,0x00,0x00,0x01,0x04,0x00,0xF3,0x86,0x01,0x1A} },  { 0x01021100,    {0x01,0x02,0x58,0x00,0x11,0x00,0x00,0x00} },  { 0x01020903,    {0x01,0x02,0x55,0x00,0x09,0x03,0x00,0x00} },  { 0x01020303,    {0x01,0x02,0x00,0x00,0x03,0x03,0x02,0x18,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },  { 0x01020400,    {0x01,0x02,0x54,0x00,0x04,0x00,0x00,0x00} },  { 0x01050000,    {0x01,0x05,0x9D,0x00,0x38,0x00,0x02,0x16,0x00,0x01,0x00,0x13,0xFF,0xFF,0x22,0x88,0xBF,0x02,0x70,0xFA,0x5F,0x80,0xFD,0x1E,0xD4,0xD6,0xF0,0xF1,0x81,0xB3} },  { 0x01010000,    {0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xFF} },  { 0x00000000, // don't delete this one    {} }  };  const unsigned int cmd=(mem[0]<<24) + (mem[1]<<16) + (mem[2]<<8) + mem[3];  const struct Resp *r=&resp[0];  while(1) {    if(!r->cmd) {      static const unsigned char fail[] = { 0x01,0x99,0x6f };      PUSH(fail,sizeof(fail));      break;      }    if(cmd==r->cmd) {      const int len=r->data[7]+9-1;      int cs=0x3f;      for(int i=0 ; i<len ; i++) cs ^= r->data[i];      PUSH(r->data,len);      PUSHB(cs);      break;      }    r++;    }#else#error No serial emulation mode selected#endif  return len;}void cSerial::ToggleRTS(void){  rts=!rts;  if(!rts) { #if defined(EMU_SECA)    static const unsigned char atr[] = { 0x3b,0x77,0x12,0x00,0x00,                                         0x60,0x60,0x03,0x0E,0x6C,0xB6,0xD6 };#elif defined(EMU_IRD)    static const unsigned char atr[] = { 0x3B,0x9F,0x21,0x0E,#ifdef EMU_IRD_384                                         0x49,0x52,0x44,0x45,0x54,0x4f,0x20,0x41,0x43,0x53,0x03,0x84,0x55,0xff,0x80,0x6d };#else                                         0x49,0x52,0x44,0x45,0x54,0x4F,0x20,0x41,0x43,0x53,0x03,0x83,0x95,0x00,0x80,0x55 };#endif#elif defined(EMU_CRYPTO)    static const unsigned char atr[] = { 0x3B,0x78,0x12,0x00,0x00,                                         0x65,0xC4,0x05,0x05,0x8F,0xF1,0x90,0x00 };#else#error No serial emulation mode selected#endif    PUSH(atr,sizeof(atr));    PRINTF(L_CORE_SERIAL,"serial: toggle RTS, now off");    }  else { PRINTF(L_CORE_SERIAL,"serial: toggle RTS, now on"); }}bool cSerial::CheckCAR(void){#if 0  if(time(0)>=remTime+30) {    dsr=!dsr;    remTime=time(0);    }#endif  return dsr;}#endif //SER_EMU// -- cInfoStr -----------------------------------------------------------------cInfoStr::cInfoStr(void):cLineBuff(256){  current=0;}cInfoStr::~cInfoStr(){  free(current);}bool cInfoStr::Get(char *buff, int len){  cMutexLock lock(&mutex);  if(current && current[0]) {    strn0cpy(buff,current,len);    return true;    }  return false;}void cInfoStr::Begin(void){  Flush();}void cInfoStr::Finish(){  cMutexLock lock(&mutex);  free(current);  current=Grab();}// -- cSmartCard ---------------------------------------------------------------static const int Ftable[16] = {  372,372,558,744,1116,1488,1860,0,0,512,768,1024,1536,2048,0,0  };static const float Dtable[16] = {  0.0,1.0,2.0,4.0,8.0,16.0,0.0,0.0,  0.0,0.0,0.5,0.25,0.125,0.0625,0.03125,0.015625  };  cSmartCard::cSmartCard(const struct CardConfig *Cfg, const struct StatusMsg *Msg){  cfg=Cfg; msg=Msg;  ser=0; atr=0; idStr[0]=0; cardUp=false; needsReset=true;}bool cSmartCard::GetCardIdStr(char *str, int len){  strn0cpy(str,idStr,len);  return (str[0]!=0);}bool cSmartCard::GetCardInfoStr(char *str, int len){  return infoStr.Get(str,len);}bool cSmartCard::Setup(cSerial *Ser, const struct Atr *Atr, int Id){  ser=Ser; atr=Atr; id=Id;  if(cfg->SerMode==(ser->CurrentMode()&SM_MASK) && Init()) {    cardUp=true; needsReset=false;    return true;    }  return false;}#define NEED(x) { \                if(len+(x)>Atr->atrLen) { \                    LBPUT("SHORT ATR"); \                    return false; \                    } \                }bool cSmartCard::ParseAtr(struct Atr *Atr, int id, int clock){  // default values  Atr->histLen=0; Atr->T=0; Atr->F=372; Atr->D=1.0; Atr->N=0; Atr->WI=10;  Atr->BWI=4; Atr->CWI=0; Atr->Tspec=-1;  const unsigned char *atr=Atr->atr;  if(atr[0]==0x03) {    PRINTF(L_CORE_SC,"%d: indirect convention detected",id);    cSmartCard::Invert(Atr->atr,Atr->atrLen);    Atr->convention=SM_INDIRECT;    }  else if(atr[0]==0x3B) {    PRINTF(L_CORE_SC,"%d: direct convention detected",id);    Atr->convention=SM_DIRECT;    }  else {    PRINTF(L_CORE_SC,"%d: byte mode not supported 0x%02x",id,atr[0]);    return false;    }  // TS TO  Atr->histLen=atr[1]&0x0F;  int Y=atr[1]&0xF0, i=1, len=2;  LBSTARTF(L_CORE_SC);  LBPUT("%d: atr decoding TS=%02x hist=%d Y%d=%02x ",id,atr[0],Atr->histLen,i,Y);  do {    if(Y&0x10) { // TAi      NEED(1);      LBPUT("TA%d=%02x ",i,atr[len]);      if(i==1) {        Atr->TA1=atr[len];        Atr->F=Ftable[(atr[len]>>4)&0x0F];        Atr->D=Dtable[ atr[len]    &0x0F];        LBPUT("F=%d D=%f ",Atr->F,Atr->D);        }      else if(i==2) {        Atr->Tspec=atr[len]&0x0F;        LBPUT("Tspec=%d ",Atr->Tspec);        }      else if(i==3) {        LBPUT("IFSC=%d ",atr[len]);        }      len++;      }    if(Y&0x20) { // TBi      NEED(1);      LBPUT("TB%d=%02x ",i,atr[len]);      if(i==3) {        Atr->BWI=(atr[len]>>4)&0x0F;        Atr->CWI=atr[len]&0x0F;        LBPUT("BWI=%d CWI=%d ",Atr->BWI,Atr->CWI);        }      len++;      }    if(Y&0x40) { // TCi      NEED(1);      LBPUT("TC%d=%02x ",i,atr[len]);      if(i==1) {        Atr->N=atr[len];        LBPUT("N=%d ",Atr->N);        }      else if(i==2) {        Atr->WI=atr[len];        LBPUT("WI=%d ",Atr->WI);        }      else if(i==3) {        LBPUT("CHK=%s ",atr[len]&1 ? "CRC16":"LRC");        }      len++;      }    if(Y&0x80) { // TDi      NEED(1);      LBPUT("TD%d=%02x ",i,atr[len]);      if(i==1) {        Atr->T=atr[len]&0x0F;        LBPUT("T=%d ",Atr->T);        }      else {        LBPUT("Tn=%d ",atr[len]&0x0F);        }      Y=atr[len]&0xF0;      len++;      }    else Y=0;    i++;    LBPUT("Y%d=%02x ",i,Y);    } while(Y);  NEED(Atr->histLen);  LBEND();  LBSTART(L_CORE_SERIAL);  LBPUT("%d: historical:",id);  for(int i=0 ; i<Atr->histLen ; i++) LBPUT(" %02x",atr[len+i]);  LBFLUSH();  LBPUT("%d: historical: '",id);  for(int i=0 ; i<Atr->histLen ; i++) LBPUT("%c",isprint(atr[len+i]) ? atr[len+i] : '.');  LBEND();  memcpy(Atr->hist,&atr[len],Atr->histLen);  len+=Atr->histLen;  // TCK  if(Atr->T!=0 && len+1<=Atr->atrLen) {    len++;    unsigned char cs=XorSum(atr+1,len-1);    // according to the ISO the initial TS byte isn't checksumed, but    // some cards do so. In this case the checksum is equal TS.    if(cs==0) PRINTF(L_CORE_SC,"%d: atr checksum ok",id);    else if(cs==atr[0]) PRINTF(L_CORE_SC,"iso: %d: atr checksum is TS (not ISO compliant)",id);    else {      PRINTF(L_CORE_SC,"%d: atr checksum FAILED (cs:%02x)",id,cs);      return false;      }    }  else PRINTF(L_CORE_SC,"%d: atr checksum not given/not required",id);  if(Atr->atrLen>len) PRINTF(L_CORE_SC,"%d: long atr read=%d len=%d",id,Atr->atrLen,len);  Atr->wwt=960*Atr->WI*Atr->F/(clock/1000);  Atr->bwt=(int)(960*(float)(1<<Atr->BWI)*372/(clock/1000));  PRINTF(L_CORE_SC,"%d: indicated wwt(T0)=%d ms, bwt(T1)=%d ms (at %.4f MHz)",id,Atr->wwt,Atr->bwt,(float)clock/1000000);  return true;}void cSmartCard::Invert(unsigned char *data, int n){  static const unsigned char swaptab[] =  { 15,7,11,3,13,5,9,1,14,6,10,2,12,4,8,0 };  for(int i=n-1; i>=0; i--)    data[i]=(swaptab[data[i]&0x0f]<<4) | swaptab[data[i]>>4];}int cSmartCard::SerRead(unsigned char *data, int len, int to){  if(atr->T==1 || atr->T==14) {    int r=Read(data,len,to);    if(r<0) Test(false);    return r;    }  else {    PRINTF(L_CORE_SC,"%d: SerRead() not allowed for ISO compliant cards (T=%d)",id,atr->T);    return -1;    }}int cSmartCard::SerWrite(const unsigned char *data, int len){  if(atr->T==1 || atr->T==14) {    int r=Write(data,len);    if(r<0) Test(false);    return r;    }  else {    PRINTF(L_CORE_SC,"%d: SerWrite() not allowed for ISO compliant cards (T=%d)",id,atr->T);    return -1;    }}int cSmartCard::Read(unsigned char *data, int len, int to){  int r=ser->Read(data,len,cfg->serTO,to);  if(atr->convention==SM_INDIRECT && r>0) Invert(data,r);  return r;}int cSmartCard::Write(const unsigned char *data, int len){  unsigned char tmp[len];  if(atr->convention==SM_INDIRECT) {    memcpy(tmp,data,len);    Invert(tmp,len);    data=tmp;    }  int r=ser->Write(data,len);  if(r>0) {    unsigned char buff[r];    int rr=ser->Read(buff,r,cfg->serTO);    if(rr<0) r=rr;    }  return r;}int cSmartCard::Procedure(unsigned char ins, int restLen){  int r;  unsigned char buff;

⌨️ 快捷键说明

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