]> www.vanbest.org Git - sasc-ng.git/commitdiff
smartcards: add dumb Nagra card emu
authorleslie <unknown>
Sat, 27 Mar 2010 03:16:43 +0000 (11:16 +0800)
committerleslie <unknown>
Sat, 27 Mar 2010 03:16:43 +0000 (11:16 +0800)
smartcard.c

index 696d1ea6352c287b522bcbe6716fa6047348a942..55e6d42f701f0281744f0445ad311af8a3f417b5 100644 (file)
@@ -1709,6 +1709,125 @@ void cSmartCardSlotEmuIrdeto::EmuPushAtr(void)
   else       PUSH(atr383,sizeof(atr383))
 }
 
+// -- cSmartCardSlotEmuNagra --------------------------------------------------
+
+class cSmartCardSlotEmuNagra : public cSmartCardSlotEmuGeneric {
+private:
+  int toggle;
+  int dt_count[16];
+protected:
+  virtual void DeviceToggleReset(void);
+  virtual int DeviceWrite(const unsigned char *mem, int len, int delay=0);
+  virtual void EmuPushAtr(void);
+public:
+  cSmartCardSlotEmuNagra(void);
+  };
+
+static cSmartCardSlotLinkReg<cSmartCardSlotEmuNagra> __scs_emunagra("emunagra");
+
+cSmartCardSlotEmuNagra::cSmartCardSlotEmuNagra(void)
+{
+  strcpy(devName,"emunagra");
+  toggle=0;
+  memset(dt_count,0,sizeof(dt_count));
+}
+
+void cSmartCardSlotEmuNagra::DeviceToggleReset(void)
+{
+  toggle=0;
+  memset(dt_count,0,sizeof(dt_count));
+  cSmartCardSlotEmuGeneric::DeviceToggleReset();
+}
+
+int cSmartCardSlotEmuNagra::DeviceWrite(const unsigned char *mem, int len, int delay)
+{
+  PRINTF(L_CORE_SERIAL,"%s: write len=%d delay=%d",devName,len,delay);
+  Flush();
+  cCondWait::SleepMs(100);
+  PUSH(mem,len); // echo back
+
+// for this sample data:
+// BOXKEY:  BB99FF99BB997788
+// CARDMOD: 9A2AE686F360A8F63B679E05443FE32969DE606A8521A48003A9C904F53FCE34D6D62B3DA6A9EF090556559068B4B127213A6EC310E629AEA7286D6B46AB6519
+// -> SESSKEY: 9d2cd4cbc4b22bdf65c5c2d8506a2927
+  static const struct Resp {
+    int cmd, cc;
+    unsigned int idata;
+    unsigned char data[MAX_LEN];
+    } resp[] = {
+/* status */  { 0xC0, 0,0x00000000, { 0x08,0xb0,0x04,0x00,0x13,0x00,0x20,0x90,0x00 } },
+/* datetim */ { 0xC8, 0,0x00000000, { 0x08,0xb8,0x04,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* card ID*/  { 0x12, 0,0x00000000, { 0x08,0x92,0x04,0x71,0x2A,0x3B,0x4C,0x90,0x00 } },
+/* IRDINFO */ { 0x22, 0,0x00000000, { 0x3b,0xA2,0x37,0x2A,0xFF,0x90,0x00,0x00,0x00,0x01,0x01,0xE9,0x01,0x01,0x01,0x12,0x3B,0x4F,0x5C,0x00,0x00,0x00,0x01,0x60,0x62,0x18,0x7A,0xA8,0xBE,0x10,0x5C,0x4F,0x3B,0x12,0x31,0x37,0x42,0x42,0x44,0x41,0x4C,0x44,0x50,0x34,0x35,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/*  */        { 0x22,-1,0x00000080, { 0x3b,0xa2,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* DT01 */    { 0x22, 0,0x00000001, { 0x10,0xa2,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* DT04 */    { 0x22, 0,0x00000004, { 0x46,0xa2,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/*  */        { 0x22,-1,0x00000084, { 0x46,0xa2,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* TIERS */   { 0x22, 0,0x00000005, { 0x59,0xa2,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/*  */        { 0x22,-1,0x00000085, { 0x59,0xa2,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* DT06 */    { 0x22, 0,0x00000006, { 0x18,0xa2,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* CAMDATA */ { 0x22, 0,0x00000008, { 0x57,0xa2,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/*  */        { 0x22,-1,0x00000088, { 0x57,0xa2,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* CMD 26 */  { 0x26, 0,0x123b4f5c, { 0x44,0xa6,0x40,0xa1,0x36,0x96,0xdc,0x3d,0x43,0x98,0xc9,0xd3,0xda,0x73,0xca,0x67,0x37,0x75,0xf0,0x29,0x33,0x6c,0xf9,0x2c,0xb4,0xdd,0x0e,0x18,0xaf,0x9e,0x24,0xb8,0x56,0xa2,0x04,0xd9,0xbf,0x7b,0xf5,0xc2,0x64,0xc4,0x61,0xd0,0xce,0x33,0xa7,0x13,0x56,0x68,0xcd,0xb2,0xa5,0x54,0x04,0xce,0x79,0x72,0x1a,0xde,0x9a,0xc4,0x92,0x2c,0x49,0x4f,0x85,0x90,0x00 } },
+/* CMD 27 */  { 0x27, 0,0xfecd819a, { 0x04,0xa7,0x00,0x90,0x00 } },
+// don't remove this one
+/* END */     { 0xFF, 0,0x00000000, { 0x0 }} };
+
+  unsigned char *rmem=AUTOMEM(len);
+  memcpy(rmem,mem,len);
+  Invert(rmem,len);
+
+  unsigned char buff[MAX_LEN+16];
+  int c=0;
+  if(rmem[0]==0x21 && rmem[1]==0xc1) { // IFS
+    buff[c++]=0x12;
+    buff[c++]=0x00;
+    buff[c++]=0x00;
+    buff[c++]=0x00;
+    }
+  else {
+    int cmd=rmem[8], ilen=rmem[9];
+    unsigned int idata=0;
+    if(ilen>0) {
+      if(ilen>4) ilen=4;
+      for(int i=0; i<ilen; i++) idata=(idata<<8) | rmem[10+i];
+      }
+    bool isdt = (cmd==0x22);
+    for(const struct Resp *r=&resp[0]; 1 ;r++) {
+      if(r->cmd==0xFF) {
+        static const unsigned char fail[] = { 0x12,0x82,0x00,0x90 };
+        c=sizeof(fail);
+        memcpy(buff,fail,c);
+        break;
+        }
+      if(cmd==r->cmd && idata==r->idata && (!isdt || dt_count[idata&0xF]==r->cc || r->cc<0)) {
+        buff[c++]=0x12;
+        buff[c++]=toggle; toggle^=0x40;
+        unsigned int l=r->data[0]+1;
+        memcpy(&buff[c],r->data,l);
+        c+=l;
+        if(isdt) {
+          dt_count[idata&0xF]++;
+          PRINTF(L_CORE_SERIAL,"%s: dt%02x count now %d",devName,idata&0xf,dt_count[idata&0xF]);
+          }
+        break;
+        }
+      }
+    }
+  if(c>0) {
+    buff[c]=XorSum(buff,c); c++;
+    Invert(buff,c);
+    PUSH(buff,c);
+    }
+  return len;
+}
+
+void cSmartCardSlotEmuNagra::EmuPushAtr(void)
+{
+  static const unsigned char atr[] = { 0x03,0x00,0x56,0xff,0x00,0x76,0x7e,0x71,0x80,0x1d,0xff,0xdd,0x8d,0x7d,0x35,0xf5,0xb3,0xd3,0x73,0xfb,0xdd,0x31,0xe9,0xed,0xf3,0x33,0x9f };
+  PUSH(atr,sizeof(atr))
+}
+
 #endif // CARD_EMU
 
 // -- cInfoStr -----------------------------------------------------------------