Advertisement
Guest User

Untitled

a guest
Jul 25th, 2012
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Index: include/usb_cmd.h
  2. ===================================================================
  3. --- include/usb_cmd.h   (revision 603)
  4. +++ include/usb_cmd.h   (working copy)
  5. @@ -91,6 +91,7 @@
  6.  #define CMD_SNOOP_ISO_14443a                       0x0383
  7.  #define CMD_SIMULATE_TAG_ISO_14443a            0x0384
  8.  #define CMD_READER_ISO_14443a                      0x0385
  9. +#define CMD_PACE_ISO_14443a                     0x386
  10.  #define CMD_SIMULATE_TAG_LEGIC_RF              0x0387
  11.  #define CMD_READER_LEGIC_RF                            0x0388
  12.  #define CMD_WRITER_LEGIC_RF                            0x0399
  13. Index: armsrc/iso14443a.c
  14. ===================================================================
  15. --- armsrc/iso14443a.c  (revision 603)
  16. +++ armsrc/iso14443a.c  (working copy)
  17. @@ -1790,6 +1790,192 @@
  18.     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
  19.     LEDsoff();
  20.  }
  21. +
  22. +//-----------------------------------------------------------------------------
  23. +// Perform initial part of PACE protocol
  24. +//
  25. +//-----------------------------------------------------------------------------
  26. +void PaceIso14443a(UsbCommand * c, UsbCommand * ack)
  27. +{
  28. +    /*
  29. +     * ack layout:
  30. +     *     arg:
  31. +     *         1. element
  32. +     *             1. bit: 1 = failure, 0 = success
  33. +     *             2.+3. bit: step where failure occured
  34. +     *                        0: card select
  35. +     *                        1: PACE MSE: Set AT
  36. +     *                        2: PACE General Authenticate
  37. +     *             16.-31. bit: SW1 || SW2 of response APDU (in case of failure)
  38. +     *         2. element
  39. +     *             iso14_apdu() return code
  40. +     *     d:
  41. +     *         Encrypted nonce
  42. +     */
  43. +
  44. +   //iso14a_command_t param = c->arg[0];
  45. +   //uint8_t * cmd = c->d.asBytes;
  46. +   //size_t len = c->arg[1];
  47. +
  48. +    // card UID
  49. +   uint8_t uid[8];
  50. +
  51. +   // card select information
  52. +   iso14a_card_select_t card_select_info;
  53. +
  54. +   // return value of a function
  55. +   int func_return;
  56. +
  57. +   // command APDU
  58. +   // size should be the max. size needed by any command used here
  59. +   uint8_t command_apdu[20] = {0};
  60. +   // response APDU
  61. +   // for the size the same holds as for the command APDU
  62. +   uint8_t response_apdu[6] = {0};
  63. +
  64. +   // initialize ack with 0
  65. +   memset(ack->arg, 0, 12);
  66. +   memset(ack->d.asBytes, 0, 48);
  67. +
  68. +    // power up the field
  69. +    iso14443a_setup();
  70. +
  71. +    // select the card
  72. +    func_return = iso14443a_select_card(uid, &card_select_info, NULL);
  73. +    // if this failed already, abort
  74. +    if(func_return != 1)
  75. +    {
  76. +        // set fail bit
  77. +        ack->arg[0] |= 0x80000000;
  78. +        UsbSendPacket((void *)ack, sizeof(UsbCommand));
  79. +        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
  80. +        LEDsoff();
  81. +        return;
  82. +    }
  83. +
  84. +    // command APDU to initiate PACE
  85. +    uint8_t i = 0;
  86. +    // CLA
  87. +    command_apdu[i++]  = 0x00;
  88. +    // INS
  89. +    command_apdu[i++]  = 0x22;
  90. +    // P1
  91. +    command_apdu[i++]  = 0xC1;
  92. +    // P2
  93. +    command_apdu[i++]  = 0xA4;
  94. +    // Lc: 15 bytes
  95. +    command_apdu[i++]  = 0x0F;
  96. +    // Content:
  97. +    // Type: Protocol (by OID)
  98. +    command_apdu[i++]  = 0x80;
  99. +    // Length: 10 bytes
  100. +    command_apdu[i++]  = 0x0A;
  101. +    // OID
  102. +    // bsi-de
  103. +    command_apdu[i++]  = 0x04;
  104. +    command_apdu[i++]  = 0x00;
  105. +    command_apdu[i++]  = 0x7F;
  106. +    command_apdu[i++] = 0x00;
  107. +    command_apdu[i++] = 0x07;
  108. +    // protocols
  109. +    command_apdu[i++] = 0x02;
  110. +    // smartcard
  111. +    command_apdu[i++] = 0x02;
  112. +    // id_PACE
  113. +    command_apdu[i++] = 0x04;
  114. +    // ECDH-GM
  115. +    command_apdu[i++] = 0x02;
  116. +    // 3DES-CBC-CBC
  117. +    command_apdu[i++] = 0x01;
  118. +    // Type: Password
  119. +    command_apdu[i++] = 0x83;
  120. +    // Length: 1 byte
  121. +    command_apdu[i++] = 0x01;
  122. +    // CAN
  123. +    command_apdu[i++] = 0x02;
  124. +
  125. +    // send it
  126. +    iso14_apdu(command_apdu, 20, response_apdu);
  127. +    // check if command failed
  128. +    if(func_return == -1 || response_apdu[0] != 0x90 || response_apdu[1] != 0x00)
  129. +    {
  130. +        // fail
  131. +        ack->arg[0] |= 0x80000000;
  132. +        // step 1
  133. +        ack->arg[0] |= 0x20000000;
  134. +        // SW1 of RAPDU
  135. +        ack->arg[0] |= ((uint32_t) response_apdu[0]) << 8;
  136. +        // SW2 of RAPDU
  137. +        ack->arg[0] |= ((uint32_t) response_apdu[1]);
  138. +
  139. +        // return code
  140. +        ack->arg[1] = func_return;
  141. +
  142. +        // send it
  143. +        UsbSendPacket((void *)ack, sizeof(UsbCommand));
  144. +        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
  145. +        LEDsoff();
  146. +        return;
  147. +    }
  148. +    // clear command and response APDUs
  149. +    memset(command_apdu, 0, 20);
  150. +    memset(response_apdu, 0, 2);
  151. +
  152. +    // command APDU to request the encrypted nonce
  153. +    i = 0;
  154. +    // CLA
  155. +    command_apdu[i++] = 0x00;
  156. +    // INS
  157. +    command_apdu[i++] = 0x86;
  158. +    // P1
  159. +    command_apdu[i++] = 0x00;
  160. +    // P2
  161. +    command_apdu[i++] = 0x00;
  162. +    // Lc = 2 bytes
  163. +    command_apdu[i++] = 0x02;
  164. +    // Content:
  165. +    // General Authenticate
  166. +    command_apdu[i++] = 0x7C;
  167. +    // zero byte (indicate first step?)
  168. +    command_apdu[i++] = 0x00;
  169. +    // Trailer:
  170. +    // Le = 4 bytes
  171. +    command_apdu[i++] = 0x04;
  172. +
  173. +    // send it
  174. +    func_return = iso14_apdu(command_apdu, 8, response_apdu);
  175. +    // check if command failed
  176. +    if(func_return == -1 || response_apdu[4] != 0x90 || response_apdu[5] != 0x00)
  177. +    {
  178. +        // fail
  179. +        ack->arg[0] |= 0x80000000;
  180. +        // step 2
  181. +        ack->arg[0] |= 0x40000000;
  182. +        // note: if command failed, APDU consists only of SW1 || SW2, no content
  183. +        // SW1 of RAPDU
  184. +        ack->arg[0] |= ((uint32_t) response_apdu[0]) << 8;
  185. +        // SW2 of RAPDU
  186. +        ack->arg[0] |= ((uint32_t) response_apdu[1]);
  187. +
  188. +        // return code
  189. +        ack->arg[1] = func_return;
  190. +
  191. +        // send it
  192. +        UsbSendPacket((void *)ack, sizeof(UsbCommand));
  193. +        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
  194. +        LEDsoff();
  195. +        return;
  196. +    }
  197. +
  198. +    // all succeeded, copy the nonce into the ack and return
  199. +    memcpy(ack->d.asBytes, response_apdu, 4);
  200. +
  201. +    // all done, return
  202. +    UsbSendPacket((void *)ack, sizeof(UsbCommand));
  203. +    FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
  204. +    LEDsoff();
  205. +}
  206. +
  207.  //-----------------------------------------------------------------------------
  208.  // Read an ISO 14443a tag. Send out commands and store answers.
  209.  //
  210. Index: armsrc/apps.h
  211. ===================================================================
  212. --- armsrc/apps.h   (revision 603)
  213. +++ armsrc/apps.h   (working copy)
  214. @@ -135,6 +135,7 @@
  215.  void RAMFUNC SnoopIso14443a(uint8_t param);
  216.  void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd);  // ## simulate iso14443a tag
  217.  void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
  218. +void PaceIso14443a(UsbCommand * c, UsbCommand * ack);
  219.  // Also used in iclass.c
  220.  int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
  221.  uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
  222. Index: armsrc/appmain.c
  223. ===================================================================
  224. --- armsrc/appmain.c    (revision 603)
  225. +++ armsrc/appmain.c    (working copy)
  226. @@ -711,6 +711,9 @@
  227.         case CMD_READER_ISO_14443a:
  228.             ReaderIso14443a(c, &ack);
  229.             break;
  230. +        case CMD_PACE_ISO_14443a:
  231. +            PaceIso14443a(c, &ack);
  232. +            break;
  233.         case CMD_SIMULATE_TAG_ISO_14443a:
  234.             SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2]);  // ## Simulate iso14443a tag - pass tag type & UID
  235.             break;
  236. Index: client/cmdhf14a.c
  237. ===================================================================
  238. --- client/cmdhf14a.c   (revision 603)
  239. +++ client/cmdhf14a.c   (working copy)
  240. @@ -199,6 +199,82 @@
  241.     return resp->arg[0];
  242.  }
  243.  
  244. +// Collect ISO14443 Type A UIDs
  245. +int CmdHF14ACUIDs(const char *Cmd)
  246. +{
  247. +    // requested number of UIDs
  248. +    int n = atoi(Cmd);
  249. +    int i;
  250. +
  251. +    PrintAndLog("Collecting %d UIDs", n);
  252. +    PrintAndLog("Start: %u", time(NULL));
  253. +    // repeat n times
  254. +    for(i = 0; i < n; i++)
  255. +    {
  256. +        // execute anticollision procedure
  257. +        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
  258. +        SendCommand(&c);
  259. +        UsbCommand * resp = WaitForResponse(CMD_ACK);
  260. +        uint8_t              * uid  = resp->d.asBytes;
  261. +        iso14a_card_select_t * card = (iso14a_card_select_t *)(uid + 12);
  262. +
  263. +        // check if command failed
  264. +        if(resp->arg[0] == 0) {
  265. +            PrintAndLog("Card select failed.");
  266. +        }
  267. +        else
  268. +        {
  269. +            // check if UID is 4 bytes
  270. +            if((card->atqa[1] & 0xC0) == 0)
  271. +            {
  272. +                PrintAndLog("%02X%02X%02X%02X", *uid, *(uid+1), *(uid+2), *(uid+3));
  273. +            }
  274. +            else
  275. +            {
  276. +                PrintAndLog("UID longer than 4 bytes");
  277. +            }
  278. +        }
  279. +    }
  280. +    PrintAndLog("End: %u", time(NULL));
  281. +
  282. +   return 1;
  283. +}
  284. +
  285. +// Perform initial PACE steps and aqcuire enrypted random nonce
  286. +int CmdHF14APACE(const char *Cmd)
  287. +{
  288. +    // requested number of Nonces
  289. +    int n = atoi(Cmd);
  290. +    int i;
  291. +
  292. +    PrintAndLog("Collecting %d nonces", n);
  293. +    PrintAndLog("Start: %u", time(NULL));
  294. +    // repeat n times
  295. +    for(i = 0; i < n; i++)
  296. +    {
  297. +        // execute PACE
  298. +        UsbCommand c = {CMD_PACE_ISO_14443a, {0, 0, 0}};
  299. +        SendCommand(&c);
  300. +        UsbCommand * resp = WaitForResponse(CMD_ACK);
  301. +
  302. +        // check if command failed
  303. +        if((resp->arg[0] & 0x80000000) != 0) {
  304. +            PrintAndLog("Operation failed in step %d, Return code: %d, SW: 0x%04X",
  305. +                        (resp->arg[0] & 0x60000000) >> 29,
  306. +                        (int)resp->arg[1],
  307. +                        (resp->arg[0] & 0x0000FFFF));
  308. +        }
  309. +        else
  310. +        {
  311. +            // print nonce
  312. +            PrintAndLog("E(r): 0x%08X", resp->d.asDwords);
  313. +        }
  314. +    }
  315. +    PrintAndLog("End: %u", time(NULL));
  316. +
  317. +   return 1;
  318. +}
  319. +
  320.  // ## simulate iso14443a tag
  321.  // ## greg - added ability to specify tag UID
  322.  int CmdHF14ASim(const char *Cmd)
  323. @@ -313,6 +389,8 @@
  324.    {"help",   CmdHelp,          1, "This help"},
  325.    {"list",   CmdHF14AList,     0, "List ISO 14443a history"},
  326.    {"reader", CmdHF14AReader,   0, "Act like an ISO14443 Type A reader"},
  327. +  {"cuids",  CmdHF14ACUIDs,    0, "<n> Collect n ISO14443 Type A UIDs"},
  328. +  {"pace",   CmdHF14APACE,     0, "<n> Acquire n encrypted PACE nonces"},
  329.    {"sim",    CmdHF14ASim,      0, "<UID> -- Fake ISO 14443a tag"},
  330.    {"snoop",  CmdHF14ASnoop,    0, "Eavesdrop ISO 14443 Type A"},
  331.    {NULL, NULL, 0, NULL}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement