Advertisement
Guest User

Untitled

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