Guest User

Emulator.cpp

a guest
Aug 9th, 2014
1,274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.09 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stddef.h>
  5. #include <stdlib.h>
  6. #include "Global.h"
  7. #include "Emulator.h"
  8. #include "Crypto_emu.h"
  9. #define reply SetTrailer
  10. extern CryptoState_t State;
  11.  
  12. typedef struct {
  13.     u8 len;
  14.     u8 pt1;
  15.     u8 pt2;
  16.     u8 dBuff[256];
  17. } b1_t;
  18.  
  19. static b1_t Input;
  20. static b1_t Output;
  21. static u8 CkSum;
  22. static u8 Flg;
  23. static u8 CardInfo[8][16];
  24. static Tier_t WkKey[32];
  25. static u8 BroadCastID;
  26.  
  27. static void chksum1(b1_t *pBuff)
  28. {
  29.     u8 i, tmp = 0;
  30.  
  31.     for (i = 0 ; i <= pBuff->len ; i++) {
  32.         tmp ^= pBuff->dBuff[i];
  33.     }
  34.  
  35.     CkSum = tmp ^ pBuff->len ^ pBuff->pt1 ^ pBuff->pt2;
  36. }
  37.  
  38. #if !defined(FAKE_WINSCARD)
  39. static void testptrn1(void)
  40. {
  41.     const u8 dt1[] = { 0x90, 0x30, 0x00, 0x00, 0x00 };  // INT
  42.     const u8 dt2[] = { 0x90, 0x32, 0x00, 0x00, 0x00 };  // IDI
  43. /*  const u8 dt3[] = { 0x90, 0x34, 0x00, 0x00, 0x26, 0x44, 0x1E, 0x02,
  44.                        0x54, 0x68, 0x69, 0x73, 0x20, 0x6?, 0x69, 0x6?,  // Odd Key
  45.                        0x6?, 0x20, 0x70, 0x6?, 0x73, 0x74, 0x31, 0x39,  // Even Key
  46.                        0x??, 0x3?, 0x?2, 0x??, 0x54, 0x21, 0x95,
  47.                        0x6?, 0x25, 0x2?, 0x33, 0x00, 0x?6, 0x?9,
  48.                        0x1?, 0x42, 0x40, 0x8?, 0x00, 0x00 };            // ECM
  49. */
  50.     struct {
  51.         const u8 *ptr;
  52.         u8 size;
  53.     } testapdu[] = {
  54.         { dt1, sizeof(dt1) },   // INT
  55.         { dt2, sizeof(dt2) },   // IDI
  56. /*      { dt3, sizeof(dt3) },   // ECM
  57. */      { NULL, 0 },
  58.     };
  59.  
  60.     static u8 index = 0;
  61.  
  62.     if (testapdu[index].ptr != NULL) {
  63.         memcpy(Input.dBuff, testapdu[index].ptr, testapdu[index].size);
  64.         Input.len = testapdu[index].size;
  65.         index++;
  66.     } else {
  67.         exit(0);    // test complete
  68.     }
  69.     Input.pt1 = 0x00;
  70.     Input.pt2 = Flg;
  71.     Flg ^= 0x40;
  72.     Input.dBuff[Input.len] = 0x00;  // zero clear
  73.     chksum1(&Input);                // calculate sum
  74.     Input.dBuff[Input.len] = CkSum; // store sum
  75.  
  76. #if !defined(FAKE_WINSCARD)
  77.     printf("    :");
  78.     for (u8 i = 0 ; i < Input.len ; i++)
  79.         printf(" %02x", Input.dBuff[i]);
  80.     printf(" %02x",Input.dBuff[Input.len]); // store sum
  81.     printf("\n");
  82. #endif
  83.  
  84. }
  85. #endif
  86.  
  87. static void reply1(void)
  88. {
  89.     Output.pt1 = Input.pt1;
  90.     Output.pt2 = Input.pt2;
  91.     Output.dBuff[Output.len] = 0x00;
  92.     chksum1(&Output);
  93.     Output.dBuff[Output.len] = CkSum;
  94.  
  95.     memset(&Input, 0, sizeof(Input));
  96.  
  97. #if !defined(FAKE_WINSCARD)
  98.     printf("    :");
  99.     for (u8 i = 0 ; i < Output.len ; i++)
  100.         printf(" %02x", Output.dBuff[i]);
  101.     printf("\n");
  102. #endif
  103. }
  104.  
  105. static u8 CheckProtocol(u8 Protocol)
  106. {
  107.     if (Protocol == 0x00 || Protocol == 0x04 || Protocol == 0x40 || Protocol == 0x44)
  108.         return 1;
  109.  
  110.     return 0;
  111. }
  112.  
  113. static void SetReturnCode(u16 data) // set return code.
  114. {
  115.     Output.dBuff[OUTPUT_OFFSET_RCODE + 0] = (data >> 8) & 0xff;
  116.     Output.dBuff[OUTPUT_OFFSET_RCODE + 1] = (data >> 0) & 0xff;
  117. }
  118.  
  119. static void SetOutputLen(u8 size) // set length
  120. {
  121.     Output.len = size + 2;
  122. }
  123.  
  124. static void SetTrailer(u16 data)
  125. {
  126.     Output.dBuff[Output.len - 2] = (data >> 8) & 0xff;
  127.     Output.dBuff[Output.len - 1] = (data >> 0) & 0xff;
  128. }
  129.  
  130. static void Save_Card(void);
  131.  
  132. static void Load_Card(void)
  133. {
  134.     FILE *fp;
  135.  
  136.     fp = fopen("b_cas.card1", "rb");
  137.     if (fp != NULL) {
  138.         fread(&State, sizeof(State), 1, fp);
  139.         fread(CardInfo, sizeof(CardInfo), 1, fp);
  140.         fread(WkKey, sizeof(WkKey), 1, fp);
  141.         fclose(fp);
  142.     } else {
  143.         Save_Card();    // Create file when file not found.
  144.     }
  145. }
  146.  
  147. static void Save_Card(void)
  148. {
  149.     FILE *fp;
  150.  
  151.     fp = fopen("b_cas.card1", "wb");
  152.     if (fp != NULL) {
  153.         fwrite(&State, sizeof(State), 1, fp);
  154.         fwrite(CardInfo, sizeof(CardInfo), 1, fp);
  155.         fwrite(WkKey, sizeof(WkKey), 1, fp);
  156.         fclose(fp);
  157.     }
  158. }
  159.  
  160. static void WriteOffsetData(u16 Offset, u16 data)
  161. {
  162.     FILE *fp;
  163.  
  164.     fp = fopen("b_cas.card1", "w+b");
  165.     if (fp != NULL) {
  166.         fseek(fp, Offset, SEEK_SET);
  167.         fwrite((const u8 *)&State + Offset, data, 1, fp);
  168.         fclose(fp);
  169.     }
  170. }
  171.  
  172. static void WriteWkKeyData(void)
  173. {
  174.     FILE *fp;
  175.  
  176.     fp = fopen("b_cas.card1", "w+b");
  177.     if (fp != NULL) {
  178.         fseek(fp, sizeof(State) + sizeof(CardInfo), SEEK_SET);
  179.         fwrite(WkKey, sizeof(WkKey), 1, fp);
  180.         fclose(fp);
  181.     }
  182. }
  183.  
  184. static void WriteCardInfoData(void)
  185. {
  186.     FILE *fp;
  187.  
  188.     fp = fopen("b_cas.card1", "w+b");
  189.     if (fp != NULL) {
  190.         fseek(fp, sizeof(State), SEEK_SET);
  191.         fwrite(CardInfo, sizeof(CardInfo), 1, fp);
  192.         fclose(fp);
  193.     }
  194. }
  195.  
  196. static void ECM_variable_dt(u8 size)
  197. {
  198.     u8 hensu = INPUT_OFFSET_DATA + sizeof(BCAS_ECM_Request_t);
  199.     u8 *pECM = &Input.dBuff[hensu];
  200.     u8 siz, cmd, i;
  201.  
  202.     while (size >= 2) {
  203.         size -= 2;
  204.         siz = *pECM++;
  205.         cmd = *pECM++;
  206.         if (siz > size)
  207.             siz = size;
  208.  
  209.         switch (cmd) {
  210.         case 0x52:
  211.             for ( i= 0 ; i < siz && i < 32; i++) {
  212.                 if (WkKey[BroadCastID].Bouquet[i] & pECM[i])
  213.                     break;
  214.             }
  215.             if (i == siz || i == 32)
  216.                 SetReturnCode(0x8901);
  217.             break;
  218.         }
  219.  
  220.         pECM += siz;
  221.         size -= siz;
  222.     }
  223. }
  224.  
  225. static void EMM_variable_dt(u8 size)
  226. {
  227.     u8 block = INPUT_OFFSET_DATA + sizeof(BCAS_EMM_Request_t);
  228.     u8 *pEMM = &Input.dBuff[block];
  229.     u8 siz, cmd, i;
  230.  
  231.     while (size >= 2) {
  232.         size -= 2;
  233.         siz = *pEMM++;
  234.         cmd = *pEMM++;
  235.         if (siz > size)
  236.             siz = size;
  237.  
  238.         switch (cmd) {
  239.         case 0x10:
  240.             if (siz == 9) {
  241.                 WkKey[BroadCastID].ActivationState = 0x01;
  242.                 WkKey[BroadCastID].Key[pEMM[0] & 1].WorkKeyID = pEMM[0];
  243.                 memcpy(WkKey[BroadCastID].Key[pEMM[0] & 1].Key, pEMM + 1, 8);
  244.             }
  245.             break;
  246.         case 0x11:
  247.             for (i = 0 ; i < siz && i < 32; i++)
  248.                 WkKey[BroadCastID].Bouquet[i] = pEMM[i];
  249.             break;
  250.         case 0x12:
  251.             printf("        139:");
  252.             for (i = 0 ; i < siz && i < 8; i++)
  253.                 printf(" %02x", pEMM[i]);
  254.             printf("\n");
  255.             break;
  256.         case 0x13:  // CardInfo update
  257.             if (siz == 14) {
  258.                 block = pEMM[0] >> 5;
  259.                 if (block) {
  260.                     memcpy(CardInfo[block] + 0, pEMM, 6);
  261.                     CardInfo[block][6] = CardInfo[block][0] ^ CardInfo[block][2] ^ CardInfo[block][4];
  262.                     CardInfo[block][7] = CardInfo[block][1] ^ CardInfo[block][3] ^ CardInfo[block][5];
  263.                     memcpy(CardInfo[block] + 8, pEMM + 6, 8);
  264.                     WriteCardInfoData();
  265.                 }
  266.             }
  267.             break;
  268.         }
  269.  
  270.         pEMM += siz;
  271.         size -= siz;
  272.     }
  273. }
  274. // INT
  275. static void bcas_int(void)
  276. {
  277.     BCAS_INT_Response_t *Response;
  278.     u8 i;
  279.  
  280.     if (Input.dBuff[INPUT_OFFSET_LC]) {
  281.         reply(0x6700);  // length error
  282.         return;
  283.     }
  284.  
  285.     Response = (BCAS_INT_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  286.     Response->ProtocolUnitNumber = 0x00;
  287.     Response->UnitLength = 0x39;
  288.     Response->ICCardInstruction[0] = 0x00;
  289.     Response->ICCardInstruction[1] = 0x00;
  290.     Response->ReturnCode[0] = 0x21;
  291.     Response->ReturnCode[1] = 0x00;
  292.  
  293.     Response->CASystemID[0] = 0x00;
  294.     Response->CASystemID[1] = 0x05;
  295.  
  296.     memcpy(Response->CardID, CardInfo[0], 6);
  297.     Response->CardType = 0x01;
  298.  
  299.     Response->MessagePartitionLength = 0x50;
  300.  
  301.     memcpy(Response->SystemKey, State.SystemKey, 32);
  302.     memcpy(Response->IV, State.SystemIV, 8);
  303.  
  304.     Response->SystemManagementIDCount = 0x01;
  305.     Response->SystemManagementID[0] = 0x02;
  306.     Response->SystemManagementID[1] = 0x01; // [1] header bug?
  307.  
  308.     for (i = 1 ; i < 8 ; i++) {
  309.         if (CardInfo[i][0]) {
  310.             Response->ICCardInstruction[0] |= 0x04;
  311.             break;
  312.         }
  313.     }
  314.     // fit size '12-06-23
  315.     SetOutputLen(sizeof(BCAS_INT_Response_t) + Response->SystemManagementIDCount * sizeof(Response->SystemManagementID[1]));
  316.     reply(0x9000);
  317. }
  318. // IDI
  319. static void bcas_idi(void)
  320. {
  321.     BCAS_IDI_Response_t *Response;
  322.     u8 i;
  323.  
  324.     Response = (BCAS_IDI_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  325.     Response->ProtocolUnitNumber = 0x00;
  326.     Response->UnitLength = 0x05;    // 04 -> 05 '12-06-23
  327.     Response->ICCardInstruction[0] = 0x00;
  328.     Response->ICCardInstruction[1] = 0x00;
  329.     Response->ReturnCode[0] = 0x21;
  330.     Response->ReturnCode[1] = 0x00;
  331.  
  332.     Response->Count = 0x00;
  333.     for (i = 0 ; i < 8 ; i++) {
  334.         u8 Count;
  335.  
  336.         if (i && CardInfo[i][0] == 0)
  337.             continue;
  338.  
  339.         Count = Response->Count++;
  340.         Response->Info[Count].Manufacturer = 'T'; //T002 CARD
  341.         Response->Info[Count].Version = 0x02;
  342.         memcpy(Response->Info[Count].ID, CardInfo[i], 8);
  343.         Response->UnitLength += 10;
  344.     }
  345.  
  346.     SetOutputLen(sizeof(BCAS_IDI_Response_t) + Response->Count * sizeof(Response->Info[0]));
  347.     reply(0x9000);
  348. }
  349. // ECM
  350. static void bcas_ecm(void)
  351. {
  352.     BCAS_ECM_Request_t *Request;
  353.     BCAS_ECM_Response_t *Response;
  354.     u8 MAC[4], size;
  355.     Key_t *Key;
  356.     Tier_t *Tier;
  357.     u16 MJDxxx7, MJDxxxx8;
  358.  
  359.     size = Input.dBuff[INPUT_OFFSET_LC];
  360.     if (size < 30) {
  361.         reply(0x6700);  // length error
  362.         return;
  363.     }
  364.  
  365.     SetOutputLen(sizeof(BCAS_ECM_Response_t));
  366.     reply(0x9000);
  367.  
  368.     Request = (BCAS_ECM_Request_t *)&Input.dBuff[INPUT_OFFSET_DATA];
  369.     Response = (BCAS_ECM_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  370.  
  371.     Response->ProtocolUnitNumber = 0x00;
  372.     Response->UnitLength = 0x15;
  373.     Response->ICCardInstruction[0] = 0x00;
  374.     Response->ICCardInstruction[1] = 0x00;
  375.  
  376.     if (CheckProtocol(Request->ProtocolNumber) == 0) {
  377.         Response->ReturnCode[0] = 0xA1;
  378.         Response->ReturnCode[1] = 0x02;
  379.         goto L419;
  380.     }
  381.  
  382.     BroadCastID = Request->BroadcasterGroupID;
  383.     if (BroadCastID >= 32) {
  384.         Response->ReturnCode[0] = 0xA1;
  385.         Response->ReturnCode[1] = 0x03;
  386.         goto L419;
  387.     }
  388.  
  389.     Tier = &WkKey[BroadCastID];
  390.  
  391.     if (Tier->ActivationState == 0) {
  392.         Response->ReturnCode[0] = 0xA1;
  393.         Response->ReturnCode[1] = 0x03;
  394.         goto L419;
  395.     }
  396.  
  397.     Key = &Tier->Key[Request->WorkKeyID & 1];
  398.     if (Key->WorkKeyID != Request->WorkKeyID) {
  399.         u8 i;
  400.         Response->ReturnCode[0] = 0xA1;
  401.         Response->ReturnCode[1] = 0x03;
  402.         goto L419;
  403.     }
  404.  
  405. //  LogWrite("EMUDecrIN  :          ", Request->OddKey, size - 3);
  406. //  LogWrite("Key        : ", Key->Key, 8);
  407.     Decrypt(Request->ProtocolNumber, Key->Key, Request->OddKey, size - 3);
  408. //  LogWrite("EMUDecrOUT :          ", Request->OddKey, size -3);
  409. //  LogWrite("MAC_IN     : ", ((u8 *)Request + size - 4), 4 );
  410.     GenerateMAC(Request->ProtocolNumber, Key->Key, (const u8 *)Request, size - 4, MAC);
  411. //  LogWrite("MAC_OUT    : ", MAC, 4 );
  412.  
  413.     if (memcmp(((u8 *)Request) + size - 4, MAC, 4)) {
  414.         Response->ReturnCode[0] = 0xA1;
  415.         Response->ReturnCode[1] = 0x06;
  416.         goto L419;
  417.     }
  418.     MJDxxx7 = (Request->Date[0] << 8) | Request->Date[1];
  419.     MJDxxxx8 = (Tier->ExpiryDate[0] << 8) | Tier->ExpiryDate[1];
  420.  
  421.     if (MJDxxx7 > MJDxxxx8) {
  422.         Response->ReturnCode[0] = 0x89;
  423.         Response->ReturnCode[1] = 0x02;
  424.         goto L419;
  425.     }
  426.  
  427.     Response->ReturnCode[0] = 0x08; // 0x21 -> 0x08
  428.     Response->ReturnCode[1] = 0x00;
  429.  
  430.  
  431.     ECM_variable_dt(size - 30);
  432.  
  433.     memcpy(Response->OddKey, Request->OddKey, 8);
  434.     memcpy(Response->EvenKey, Request->EvenKey, 8);
  435.     Response->RecordingControl = 0x01;
  436.  
  437.     return;
  438.  
  439. L419:
  440.     memset(Response->OddKey, 0, 8);
  441.     memset(Response->EvenKey, 0, 8);
  442.     Response->RecordingControl = 0x00;
  443. }
  444. // EMM
  445. static void bcas_emm(void)
  446. {
  447.     BCAS_EMM_Request_t *Request;
  448.     BCAS_EMM_Response_t *Response;
  449.     u8 MAC[4], size, i, *key;
  450.     u16 MJDlocal9, MJDlocal10;
  451.  
  452.     Request = (BCAS_EMM_Request_t *)&Input.dBuff[INPUT_OFFSET_DATA];
  453.     Response = (BCAS_EMM_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  454.  
  455.     SetOutputLen(sizeof(BCAS_EMM_Response_t));
  456.     reply(0x9000);
  457.  
  458.     Response->ProtocolUnitNumber = 0x00;
  459.     Response->UnitLength = 0x04;
  460.     Response->ICCardInstruction[0] = 0x00;
  461.     Response->ICCardInstruction[1] = 0x00;
  462.  
  463.     if (CheckProtocol(Request->ProtocolNumber) == 0) {
  464.         Response->ReturnCode[0] = 0xA1;
  465.         Response->ReturnCode[1] = 0x02;
  466.         return;
  467.     }
  468.  
  469.     for (i = 0 ; i < 8 ; i++) {
  470.         if (memcmp(Request->ID, CardInfo[i], 6) == 0)
  471.             break;
  472.     }
  473.     if (i == 8) {
  474.         Response->ReturnCode[0] = 0xA1;
  475.         Response->ReturnCode[1] = 0xFE;
  476.         return;
  477.     }
  478.  
  479.     key = CardInfo[i] + 8;
  480.  
  481.     size = Input.dBuff[INPUT_OFFSET_LC];
  482.     Decrypt(Request->ProtocolNumber, key, &Request->BroadcasterGroupID, Request->Length - 1);
  483.     GenerateMAC(Request->ProtocolNumber, key, (const u8 *)Request, Request->Length + 3, MAC);
  484.     if (memcmp(((u8 *)Request) + size - 4, MAC, 4)) {
  485.         Response->ReturnCode[0] = 0xA1;
  486.         Response->ReturnCode[1] = 0x07;
  487.         return;
  488.     }
  489.  
  490.     BroadCastID = Request->BroadcasterGroupID;
  491.  
  492.     Response->ReturnCode[0] = 0x21;
  493.     Response->ReturnCode[1] = 0x00;
  494.  
  495.     MJDlocal9 = (Request->ExpiryDate[0] << 8) | Request->ExpiryDate[1];
  496.     MJDlocal10 = (WkKey[BroadCastID].ExpiryDate[0] << 8) | WkKey[BroadCastID].ExpiryDate[1];
  497.  
  498.     if (MJDlocal9 <= MJDlocal10)
  499.         return;
  500.  
  501.     WkKey[BroadCastID].ExpiryDate[0] = Request->ExpiryDate[0];
  502.     WkKey[BroadCastID].ExpiryDate[1] = Request->ExpiryDate[1];
  503.  
  504.     EMM_variable_dt(size - 17);
  505.  
  506.     WriteWkKeyData();
  507. }
  508. // EMG
  509. static void bcas_emg(void)
  510. {
  511.     BCAS_EMG_Response_t *Response;
  512.  
  513.     Response = (BCAS_EMG_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  514.  
  515.     Response->ProtocolUnitNumber = 0x00;
  516.     Response->UnitLength = 0x04;
  517.     Response->ICCardInstruction[0] = 0x00;
  518.     Response->ICCardInstruction[1] = 0x00;
  519.     Response->ReturnCode[0] = 0x21;
  520.     Response->ReturnCode[1] = 0x00;
  521.  
  522.     SetOutputLen(sizeof(BCAS_EMG_Response_t));
  523.     reply(0x9000);
  524. }
  525. // EMD
  526. static void bcas_emd(void)
  527. {
  528.     BCAS_EMD_Response_t *Response;
  529.  
  530.     Response = (BCAS_EMD_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  531.  
  532.     Response->ProtocolUnitNumber = 0x00;
  533.     Response->UnitLength = 0x0B;    // 0x0?
  534.     Response->ICCardInstruction[0] = 0x00;
  535.     Response->ICCardInstruction[1] = 0x00;
  536.     Response->ReturnCode[0] = 0xA1; // 0x?1 -> 0xA1
  537.     Response->ReturnCode[1] = 0x01;
  538.  
  539.     Response->ExpiryDate[0] = 0x00;
  540.     Response->ExpiryDate[1] = 0x00;
  541.     Response->PresetText[0] = 0x00;
  542.     Response->PresetText[1] = 0x00;
  543.     Response->Number = 0x00;
  544.     Response->Length[0] = 0x00;
  545.     Response->Length[1] = 0x00;
  546.  
  547.     SetOutputLen(sizeof(BCAS_EMD_Response_t));
  548.     reply(0x9000);
  549. }
  550. // CHK
  551. static void bcas_chk(void)
  552. {
  553.     BCAS_CHK_Request_t *Request;
  554.     BCAS_CHK_Response_t *Response;
  555.     u8 size;
  556.     Key_t *Key;
  557.     Tier_t *Tier;
  558.     u16 MJD1111, MJD22222;
  559.  
  560.     size = Input.dBuff[INPUT_OFFSET_LC];
  561.     if (size < 2) {
  562.         reply(0x6700); // length error
  563.         return;
  564.     }
  565.  
  566.     SetOutputLen(sizeof(BCAS_CHK_Response_t));
  567.     reply(0x9000);
  568.  
  569.     Request = (BCAS_CHK_Request_t *)&Input.dBuff[INPUT_OFFSET_DATA];
  570.     Response = (BCAS_CHK_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  571.  
  572.     Response->ProtocolUnitNumber = 0x00;
  573.     Response->UnitLength = sizeof(BCAS_CHK_Response_t) - 2;
  574.     Response->ICCardInstruction[0] = 0x00;
  575.     Response->ICCardInstruction[1] = 0x00;
  576.  
  577.     BroadCastID = Request->BroadcasterGroupID;
  578.     if (BroadCastID >= 32) {
  579.         Response->ReturnCode[0] = 0xA1;
  580.         Response->ReturnCode[1] = 0x03;
  581.         goto L598;
  582.     }
  583.  
  584.     Tier = &WkKey[BroadCastID];
  585.  
  586.     if (Tier->ActivationState == 0) {
  587.         Response->ReturnCode[0] = 0xA1;
  588.         Response->ReturnCode[1] = 0x03;
  589.         goto L598;
  590.     }
  591.  
  592.     Key = &Tier->Key[Request->WorkKeyID & 1];
  593.     if (Key->WorkKeyID != Request->WorkKeyID) {
  594.         Response->ReturnCode[0] = 0xA1;
  595.         Response->ReturnCode[1] = 0x03;
  596.         goto L598;
  597.     }
  598.  
  599.     Decrypt(Request->ProtocolNumber, Key->Key, (u8 *)(Request + 1), size - 5);
  600.  
  601.     MJD1111 = (Request->Date[0] << 8) | Request->Date[1];
  602.     MJD22222 = (Tier->ExpiryDate[0] << 8) | Tier->ExpiryDate[1];
  603.  
  604.     if (MJD1111 > MJD22222) {
  605.         Response->ReturnCode[0] = 0x89;
  606.         Response->ReturnCode[1] = 0x02;
  607.         goto L598;
  608.     }
  609.  
  610.     Response->ReturnCode[0] = 0x08;
  611.     Response->ReturnCode[1] = 0x00;
  612.  
  613.     Response->BroadcasterGroupID = Request->BroadcasterGroupID;
  614.     Response->RecordingControl = 0x01;
  615.  
  616.     return;
  617.  
  618. L598:
  619.     Response->RecordingControl = 0x00;
  620. }
  621. // CRQ
  622. static void bcas_crq(void)
  623. {
  624.     BCAS_CRQ_Response_t *Response;
  625.  
  626.     if (Input.dBuff[INPUT_OFFSET_LC] != 0x05) {
  627.         reply(0x6700);  // length error
  628.         return;
  629.     }
  630.  
  631.     Response = (BCAS_CRQ_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  632.  
  633.     Response->ProtocolUnitNumber = 0x00;
  634.     Response->UnitLength = 0x04;
  635.     Response->ICCardInstruction[0] = 0x00;
  636.     Response->ICCardInstruction[1] = 0x00;
  637.     Response->ReturnCode[0] = 0x21;
  638.     Response->ReturnCode[1] = 0x00;
  639.  
  640.     SetOutputLen(sizeof(BCAS_CRQ_Response_t));
  641.     reply(0x9000);
  642. }
  643. // WUI
  644. static void bcas_wui(void)
  645. {
  646.     BCAS_WUI_Response_t *Response;
  647.  
  648.     if (Input.dBuff[INPUT_OFFSET_LC] != 0x01) {
  649.         reply(0x6700);
  650.         return;
  651.     }
  652.  
  653.     SetOutputLen(sizeof(BCAS_WUI_Response_t));
  654.  
  655.     Response = (BCAS_WUI_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  656.     memset(Response, 0, sizeof(BCAS_WUI_Response_t));
  657.     Response->UnitLength = 0x04;
  658.     Response->ReturnCode[0] = 0xA1; // 0x?1 -> 0xA1
  659.     Response->ReturnCode[1] = 0x01;
  660.  
  661.     reply(0x9000);
  662. }
  663. //   update_Request
  664. static void bcas_upd(void)
  665. {
  666.     BCAS_UPD_Request_t *Request;
  667.     BCAS_UPD_Response_t *Response;
  668.  
  669.     if (Input.dBuff[INPUT_OFFSET_LC] < 33 || Input.dBuff[INPUT_OFFSET_LC] > sizeof(BCAS_UPD_Request_t)) {
  670.         reply(0x6700);  // length error
  671.         return;
  672.     }
  673.     Request = (BCAS_UPD_Request_t *)&Input.dBuff[INPUT_OFFSET_DATA];
  674.     Response = (BCAS_UPD_Response_t *)&Output.dBuff[OUTPUT_OFFSET_DATA];
  675.  
  676.     //                
  677.     //                              
  678.     //                
  679.  
  680.     Response->ProtocolUnitNumber = 0x00;
  681.     Response->UnitLength = 0x04;
  682.     Response->ICCardInstruction[0] = 0x00;
  683.     Response->ICCardInstruction[1] = 0x00;
  684.     Response->ReturnCode[0] = 0x21;
  685.     Response->ReturnCode[1] = 0x00;
  686.  
  687.     SetOutputLen(sizeof(BCAS_UPD_Response_t));
  688.     SetReturnCode(0x9000);
  689.  
  690.     switch (Request->Index) {
  691.     case BCAS_UPD_INDEX_SystemKey:
  692.         memcpy(State.SystemKey, Request->Update.SystemKey, sizeof(State.SystemKey));
  693.         WriteOffsetData(offsetof(CryptoState_t, SystemKey), sizeof(State.SystemKey));
  694.         break;
  695.     case BCAS_UPD_INDEX_SystemIV:
  696.         memcpy(State.SystemIV, Request->Update.SystemIV, sizeof(State.SystemIV));
  697.         WriteOffsetData(offsetof(CryptoState_t, SystemIV), sizeof(State.SystemIV));
  698.         break;
  699.     case BCAS_UPD_INDEX_Sbox:
  700.         memcpy(State.Sbox, Request->Update.Sbox, sizeof(State.Sbox));
  701.         WriteOffsetData(offsetof(CryptoState_t, Sbox), sizeof(State.Sbox));
  702.         break;
  703.     case BCAS_UPD_INDEX_LUT0:
  704.         memcpy(State.LookupTable +   0, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  705.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) +   0, sizeof(Request->Update.LookupTable));
  706.         break;
  707.     case BCAS_UPD_INDEX_LUT1:
  708.         memcpy(State.LookupTable +  32, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  709.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) +  32, sizeof(Request->Update.LookupTable));
  710.         break;
  711.     case BCAS_UPD_INDEX_LUT2:
  712.         memcpy(State.LookupTable +  64, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  713.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) +  64, sizeof(Request->Update.LookupTable));
  714.         break;
  715.     case BCAS_UPD_INDEX_LUT3:
  716.         memcpy(State.LookupTable +  96, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  717.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) +  96, sizeof(Request->Update.LookupTable));
  718.         break;
  719.     case BCAS_UPD_INDEX_LUT4:
  720.         memcpy(State.LookupTable + 128, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  721.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) + 128, sizeof(Request->Update.LookupTable));
  722.         break;
  723.     case BCAS_UPD_INDEX_LUT5:
  724.         memcpy(State.LookupTable + 160, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  725.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) + 160, sizeof(Request->Update.LookupTable));
  726.         break;
  727.     case BCAS_UPD_INDEX_LUT6:
  728.         memcpy(State.LookupTable + 192, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  729.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) + 192, sizeof(Request->Update.LookupTable));
  730.         break;
  731.     case BCAS_UPD_INDEX_LUT7:
  732.         memcpy(State.LookupTable + 224, Request->Update.LookupTable, sizeof(Request->Update.LookupTable));
  733.         WriteOffsetData(offsetof(CryptoState_t, LookupTable) + 224, sizeof(Request->Update.LookupTable));
  734.         break;
  735.     case BCAS_UPD_INDEX_IV1:
  736.         memcpy(State.InitialisationVector1, Request->Update.IV, sizeof(State.InitialisationVector1));
  737.         WriteOffsetData(offsetof(CryptoState_t, InitialisationVector1), sizeof(State.InitialisationVector1));
  738.         break;
  739.     case BCAS_UPD_INDEX_IV2:
  740.         memcpy(State.InitialisationVector2, Request->Update.IV, sizeof(State.InitialisationVector2));
  741.         WriteOffsetData(offsetof(CryptoState_t, InitialisationVector2), sizeof(State.InitialisationVector2));
  742.         break;
  743.     case BCAS_UPD_INDEX_ScheduleIV:
  744.         memcpy(State.ScheduleIV, Request->Update.ScheduleIV, sizeof(State.ScheduleIV));
  745.         WriteOffsetData(offsetof(CryptoState_t, ScheduleIV), sizeof(State.ScheduleIV));
  746.         break;
  747.     case BCAS_UPD_INDEX_CardInfo0:
  748.         memcpy(CardInfo[0], Request->Update.CardInfo, sizeof(CardInfo[0]));
  749.         WriteCardInfoData();
  750.         break;
  751.     case BCAS_UPD_INDEX_CardInfo1:
  752.         memcpy(CardInfo[1], Request->Update.CardInfo, sizeof(CardInfo[1]));
  753.         WriteCardInfoData();
  754.         break;
  755.     case BCAS_UPD_INDEX_CardInfo2:
  756.         memcpy(CardInfo[2], Request->Update.CardInfo, sizeof(CardInfo[2]));
  757.         WriteCardInfoData();
  758.         break;
  759.     case BCAS_UPD_INDEX_CardInfo3:
  760.         memcpy(CardInfo[3], Request->Update.CardInfo, sizeof(CardInfo[3]));
  761.         WriteCardInfoData();
  762.         break;
  763.     case BCAS_UPD_INDEX_CardInfo4:
  764.         memcpy(CardInfo[4], Request->Update.CardInfo, sizeof(CardInfo[4]));
  765.         WriteCardInfoData();
  766.         break;
  767.     case BCAS_UPD_INDEX_CardInfo5:
  768.         memcpy(CardInfo[5], Request->Update.CardInfo, sizeof(CardInfo[5]));
  769.         WriteCardInfoData();
  770.         break;
  771.     case BCAS_UPD_INDEX_CardInfo6:
  772.         memcpy(CardInfo[6], Request->Update.CardInfo, sizeof(CardInfo[6]));
  773.         WriteCardInfoData();
  774.         break;
  775.     case BCAS_UPD_INDEX_CardInfo7:
  776.         memcpy(CardInfo[7], Request->Update.CardInfo, sizeof(CardInfo[7]));
  777.         WriteCardInfoData();
  778.         break;
  779.     default:
  780.         SetReturnCode(0x6900);
  781.         break;
  782.     }
  783. }
  784. //   Input_perser
  785. static void cardrun_1(void)
  786. {
  787.     memset(&Output, 0, sizeof(Output));
  788.     chksum1(&Input);
  789.     SetOutputLen(0);
  790.     if (CkSum) {
  791.         //reply(0x6   );
  792.         goto L831;
  793.     }
  794.     if (Input.len != (5 + Input.dBuff[INPUT_OFFSET_LC] + 1)) {
  795.         if (Input.dBuff[INPUT_OFFSET_P1] || Input.len != (5 + Input.dBuff[INPUT_OFFSET_LC])) {
  796.             reply(0x6F00);
  797.             goto L831;
  798.         }
  799.     }
  800.     if (Input.dBuff[INPUT_OFFSET_CLA] == 0x00) {    // Classs 0 ?
  801.         //                
  802.     } else if (Input.dBuff[INPUT_OFFSET_CLA] == 0x90) {
  803.         if (Input.dBuff[INPUT_OFFSET_P1] | Input.dBuff[INPUT_OFFSET_P2]) {
  804.             reply(0x6A86);  // P1,P2 is not correct.
  805.             goto L831;
  806.         }
  807.    
  808.         switch (Input.dBuff[INPUT_OFFSET_INS]) {
  809.         case BCAS_INS_INT:  // 0x30
  810.             bcas_int();
  811.             break;
  812.         case BCAS_INS_IDI:  // 0x32
  813.             bcas_idi();
  814.             break;
  815.         case BCAS_INS_ECM:  // 0x34
  816.             bcas_ecm();
  817.             break;
  818.         case BCAS_INS_EMM:  // 0x36
  819.             bcas_emm();
  820.             break;
  821.         case BCAS_INS_EMG:  // 0x38
  822.             bcas_emg();
  823.             break;
  824.         case BCAS_INS_EMD:  // 0x3A
  825.             bcas_emd();
  826.             break;
  827.         case BCAS_INS_CHK:  // 0x3C
  828.             bcas_chk();
  829.             break;
  830.         case BCAS_INS_CRQ:  // 0x50
  831.             bcas_crq();
  832.             break;
  833.         case BCAS_INS_WUI:  // 0x80
  834.             bcas_wui();
  835.             break;
  836.         case BCAS_INS_UPD:  //
  837.             bcas_upd();
  838.             break;
  839.         default:
  840.             reply(0x6D00);  // Unknown INS
  841.             break;
  842.         }
  843.     } else {
  844.         if (Input.dBuff[INPUT_OFFSET_CLA] & 0  )
  845.             reply(0x6800);  // lower nibble != 0
  846.         else //if (Input.dBuff[INPUT_OFFSET_CLA & 0xf0)!= 0x90 )
  847.             reply(0x6E00);  // upper nibble != 9
  848.     }
  849.  
  850. L831:
  851.     reply1();
  852. }
  853.  
  854. void DefaultData(void);
  855.  
  856. #if !defined(FAKE_WINSCARD) // Driver mode
  857. static void mainloop(void)
  858. {
  859.     while (1) {
  860.         testptrn1();
  861.         cardrun_1();
  862.     }
  863. }
  864. #define entry main
  865. int entry(int argc, char *argv[])
  866. {
  867.     Load_Card();
  868.     DefaultData();
  869.     mainloop();
  870.  
  871.     return 0;
  872. }
  873. #else                       // Fake WINSCARD
  874. void CardInit(void)
  875. {
  876.     Load_Card();
  877.     DefaultData();
  878. }
  879.  
  880. void CardRun(void)
  881. {
  882.     cardrun_1();
  883. }
  884.  
  885. void CardIN(const u8 *In, u8 Length)
  886. {
  887.     Input.pt1 = 0x00;
  888.     Input.pt2 = Flg;
  889.     Input.len = Length;
  890.     memcpy(Input.dBuff, In, Length);
  891.     Input.dBuff[Input.len] = 0x00;  // zero clear
  892.     chksum1(&Input);                // calculate sum
  893.     Input.dBuff[Input.len] = CkSum; // store sum
  894.     Flg ^= 0x40;
  895. }
  896.  
  897. u8 CardOUT(u8 *Out)
  898. {
  899.     memcpy(Out, Output.dBuff, Output.len);
  900.  
  901.     return Output.len;
  902. }
  903. #endif
  904.  
  905. #include "Init_data.cpp"
Advertisement
Add Comment
Please, Sign In to add comment