]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/epa.c
Applied Holiman's fixes for iclass.c and CSNs
[proxmark3-svn] / armsrc / epa.c
index 8ab4311cf3976c0a13801252e7a5fdcf62fee2a3..a3c6669ed648374608c30fc000ac1a7fc2bcda30 100644 (file)
@@ -12,8 +12,8 @@
 //-----------------------------------------------------------------------------
 
 #include "iso14443a.h"
-
 #include "epa.h"
+#include "../common/cmd.h"
 
 // Protocol and Parameter Selection Request
 // use regular (1x) speed in both directions
@@ -185,6 +185,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
            || response_apdu[rapdu_length - 4] != 0x90
            || response_apdu[rapdu_length - 3] != 0x00)
        {
+               Dbprintf("epa - no select cardaccess");
                return -1;
        }
        
@@ -196,6 +197,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
            || response_apdu[rapdu_length - 4] != 0x90
            || response_apdu[rapdu_length - 3] != 0x00)
        {
+               Dbprintf("epa - no read cardaccess");
                return -1;
        }
        
@@ -211,24 +213,24 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
 // Abort helper function for EPA_PACE_Collect_Nonce
 // sets relevant data in ack, sends the response
 //-----------------------------------------------------------------------------
-static void EPA_PACE_Collect_Nonce_Abort(UsbCommand *ack, uint8_t step, int func_return)
+static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
 {
-       // step in which the failure occured
-       ack->arg[0] = step;
-       // last return code
-       ack->arg[1] = func_return;
-       
-       // send the USB packet
-       UsbSendPacket((void *)ack, sizeof(UsbCommand));
+//     // step in which the failure occured
+//     ack->arg[0] = step;
+//     // last return code
+//     ack->arg[1] = func_return;
 
        // power down the field
        EPA_Finish();
+       
+       // send the USB packet
+       cmd_send(CMD_ACK,step,func_return,0,0,0);
 }
 
 //-----------------------------------------------------------------------------
 // Acquire one encrypted PACE nonce
 //-----------------------------------------------------------------------------
-void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
+void EPA_PACE_Collect_Nonce(UsbCommand *c)
 {
        /*
         * ack layout:
@@ -242,21 +244,23 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
         */
 
        // return value of a function
-       int func_return;
+       int func_return = 0;
 
-       // initialize ack with 0s
-       memset(ack->arg, 0, 12);
-       memset(ack->d.asBytes, 0, 48);
+//     // initialize ack with 0s
+//     memset(ack->arg, 0, 12);
+//     memset(ack->d.asBytes, 0, 48);
        
        // set up communication
        func_return = EPA_Setup();
-       if (func_return != 0) {
-               EPA_PACE_Collect_Nonce_Abort(ack, 1, func_return);
+       if (func_return != 0) { 
+               EPA_PACE_Collect_Nonce_Abort(1, func_return);
+               Dbprintf("epa: setup fucked up! %d", func_return);
                return;
        }
 
        // increase the timeout (at least some cards really do need this!)
        iso14a_set_timeout(0x0002FFFF);
+       Dbprintf("epa: Epic!");
        
        // read the CardAccess file
        // this array will hold the CardAccess file
@@ -264,10 +268,13 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
        int card_access_length = EPA_Read_CardAccess(card_access, 256);
        // the response has to be at least this big to hold the OID
        if (card_access_length < 18) {
-               EPA_PACE_Collect_Nonce_Abort(ack, 2, card_access_length);
+               Dbprintf("epa: Too small!");
+               EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
                return;
        }
 
+       Dbprintf("epa: foo!");
+       
        // this will hold the PACE info of the card
        pace_version_info_t pace_version_info;
        // search for the PACE OID
@@ -275,10 +282,12 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
                                           card_access_length,
                                           &pace_version_info);
        if (func_return != 0 || pace_version_info.version == 0) {
-               EPA_PACE_Collect_Nonce_Abort(ack, 3, func_return);
+               EPA_PACE_Collect_Nonce_Abort(3, func_return);
                return;
        }
        
+       Dbprintf("epa: bar!");
+       
        // initiate the PACE protocol
        // use the CAN for the password since that doesn't change
        func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
@@ -290,17 +299,17 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
        // check if the command succeeded
        if (func_return < 0)
        {
-               EPA_PACE_Collect_Nonce_Abort(ack, 4, func_return);
+               EPA_PACE_Collect_Nonce_Abort(4, func_return);
                return;
        }
+  
+  // all done, return
+       EPA_Finish();
        
        // save received information
-       ack->arg[1] = func_return;
-       memcpy(ack->d.asBytes, nonce, func_return);
-
-       // all done, return
-       EPA_Finish();
-       UsbSendPacket((void *)ack, sizeof(UsbCommand));
+//     ack->arg[1] = func_return;
+//     memcpy(ack->d.asBytes, nonce, func_return);
+       cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
 }
 
 //-----------------------------------------------------------------------------
@@ -415,27 +424,88 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
 int EPA_Setup()
 {
        // return code
-       int return_code = 0;
+       //int return_code = 0;
+       
        // card UID
-       uint8_t uid[8];
-       // card select information
-       iso14a_card_select_t card_select_info;
+       //uint8_t uid[10] = {0x00};
+       
        // power up the field
-       iso14443a_setup();
-
+       iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
+       iso14a_clear_trace();
+       iso14a_set_tracing(TRUE);
+       iso14a_set_timeout(10500);
+       
+       // card select information
+       byte_t cardbuf[USB_CMD_DATA_SIZE];
+       memset(cardbuf,0,USB_CMD_DATA_SIZE);
+       iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
+       
        // select the card
-       return_code = iso14443a_select_card(uid, &card_select_info, NULL);
-       if (return_code != 1) {
-               return 1;
-       }
+       // if (!iso14443a_select_card(uid, &card_info, NULL)) {
+               // Dbprintf("Epa: Can't select card");
+               // return -1;
+       // }
+       
+       uint8_t wupa[]     = { 0x26 };  // 0x26 - REQA  0x52 - WAKE-UP
+       uint8_t sel_all[]  = { 0x93,0x20 };
+       uint8_t sel_uid[]  = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+       uint8_t rats[]       = { 0xE0,0x81,0x00,0x00 }; // FSD=256, FSDI=8, CID=1
+       
+       uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
+       uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+       
+       byte_t uid_resp[4];
+       size_t uid_resp_len = 4;
+
+       uint8_t sak = 0x04; // cascade uid
+       int len;
+        
+       // Broadcast for a card, WUPA (0x52) will force response from all cards in the field
+    ReaderTransmitBitsPar(wupa,7,0, NULL);
+       
+       // Receive the ATQA
+       if(!ReaderReceive(resp, resp_par)) return -1;
+  
+    // SELECT_ALL
+    ReaderTransmit(sel_all,sizeof(sel_all), NULL);
+    if (!ReaderReceive(resp, resp_par)) return -1;
+       
+       // uid response from tag
+       memcpy(uid_resp,resp,uid_resp_len);
 
+       // Construct SELECT UID command
+       // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
+    memcpy(sel_uid+2,uid_resp,4);                                                                              // the UID
+       sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5];         // calculate and add BCC
+    AppendCrc14443a(sel_uid,7);                                                                                        // calculate and add CRC
+    ReaderTransmit(sel_uid,sizeof(sel_uid), NULL);
+
+    // Receive the SAK
+    if (!ReaderReceive(resp, resp_par)) return -1;
+    sak = resp[0];
+       
+       // Request for answer to select
+       AppendCrc14443a(rats, 2);
+       ReaderTransmit(rats, sizeof(rats), NULL);
+
+       if ( !(len = ReaderReceive(resp, resp_par) )) return -1;
+
+       // populate the collected data.
+    memcpy( card->uid, uid_resp, uid_resp_len);
+    card->uidlen += uid_resp_len;
+    card->sak = sak;
+    card->ats_len = len;
+    memcpy(card->ats, resp, sizeof(card->ats));
+       
+       
        // send the PPS request
-       ReaderTransmit((uint8_t *)pps, sizeof(pps));
-       uint8_t pps_response[3];
-       return_code = ReaderReceive(pps_response);
-       if (return_code != 3 || pps_response[0] != 0xD0) {
-               return return_code == 0 ? 2 : return_code;
-       }
+       // ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
+       // uint8_t pps_response[3];
+       // uint8_t pps_response_par[1];
+       // return_code = ReaderReceive(pps_response,pps_response_par);
+       // if (return_code != 3 || pps_response[0] != 0xD0) {
+               // return return_code == 0 ? 2 : return_code;
+       // }
        
-       return 0;
+       return -1;
 }
\ No newline at end of file
Impressum, Datenschutz