]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443a.c
FIDO U2F NFC authenticators (#697)
[proxmark3-svn] / armsrc / iso14443a.c
index 059db71e5f0708f39f3c5128f3051a4d5197f2e6..7bf8f5af7d110e4f440b933ebed4f5c1f8138052 100644 (file)
@@ -1935,15 +1935,21 @@ b8 b7 b6 b5 b4 b3 b2 b1
 b5,b6 = 00 - DESELECT
         11 - WTX 
 */    
-int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
+int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) {
        uint8_t parity[MAX_PARITY_SIZE];
        uint8_t real_cmd[cmd_len + 4];
        
-       // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
-       real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) 
-       // put block number into the PCB
-       real_cmd[0] |= iso14_pcb_blocknum;
-       memcpy(real_cmd + 1, cmd, cmd_len);
+       if (cmd_len) {
+               // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
+               real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) 
+               // put block number into the PCB
+               real_cmd[0] |= iso14_pcb_blocknum;
+               memcpy(real_cmd + 1, cmd, cmd_len);
+       } else {
+               // R-block. ACK
+               real_cmd[0] = 0xA2; // r-block + ACK    
+               real_cmd[0] |= iso14_pcb_blocknum;
+       }
        AppendCrc14443a(real_cmd, cmd_len + 1);
  
        ReaderTransmit(real_cmd, cmd_len + 3, NULL);
@@ -1982,9 +1988,13 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
                {
                        iso14_pcb_blocknum ^= 1;
                }
+               
+               // if we received I-block with chaining we need to send ACK and receive another block of data
+               if (res)
+                       *res = data_bytes[0];
 
                // crc check
-               if (len >=3 && !CheckCrc14443(CRC_14443_A, data_bytes, len)) {
+               if (len >= 3 && !CheckCrc14443(CRC_14443_A, data_bytes, len)) {
                        return -1;
                }
                
@@ -2050,9 +2060,10 @@ void ReaderIso14443a(UsbCommand *c)
        }
 
        if(param & ISO14A_APDU && !cantSELECT) {
-               arg0 = iso14_apdu(cmd, len, buf);
+               uint8_t res;
+               arg0 = iso14_apdu(cmd, len, buf, &res);
                LED_B_ON();
-               cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
+               cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf));
                LED_B_OFF();
        }
 
Impressum, Datenschutz