diff --git a/t_1.c b/t_1.c index 33d1cc8..f19dfed 100644 --- a/t_1.c +++ b/t_1.c @@ -18,13 +18,21 @@ #define R_SEQUENCE_NUMBER_MASK 0x10 uint8_t NAD = 0x00; -uint8_t PCB = 0x40; // Init to 0x40 so first call to next_pcb will return 0x00 +uint8_t dPCB = 0x40; // Init to 0x40 so first call to next_pcb will return 0x00 +uint8_t cPCB = 0x00; // Init to 0x40 so first call to next_pcb will return 0x00 + +uint8_t seader_next_dpcb() { + uint8_t next_pcb = dPCB ^ 0x40; + FURI_LOG_D(TAG, "dPCB was: %02X, current dPCB: %02X", dPCB, next_pcb); + dPCB = next_pcb; + return dPCB; +} -uint8_t seader_next_pcb() { - uint8_t next_pcb = PCB ^ 0x40; - FURI_LOG_D(TAG, "PCB: %02X, Next PCB: %02X", PCB, next_pcb); - PCB = next_pcb; - return PCB; +uint8_t seader_next_cpcb() { + uint8_t next_pcb = cPCB ^ 0x40; + FURI_LOG_D(TAG, "cPCB was: %02X, current cPCB: %02X", cPCB, next_pcb); + cPCB = next_pcb; + return cPCB; } void seader_t_1_set_IFSD(Seader* seader) { @@ -51,15 +59,13 @@ void seader_t_1_send_ack(Seader* seader) { uint8_t frame_len = 0; frame[0] = NAD; - frame[1] = R_BLOCK | PCB; + frame[1] = R_BLOCK | dPCB; frame[2] = 0x00; frame_len = 3; frame_len = seader_add_lrc(frame, frame_len); FURI_LOG_D(TAG, "Sending R-Block ACK: PCB: %02x", frame[1]); - // Increment PCB - seader_next_pcb(); seader_ccid_XfrBlock(seader_uart, frame, frame_len); } @@ -82,9 +88,9 @@ void seader_send_t1(SeaderUartBridge* seader_uart, uint8_t* apdu, size_t len) { frame[0] = NAD; if(remaining > IFSC_VALUE) { - frame[1] = seader_next_pcb() | MORE_BIT; + frame[1] = seader_next_dpcb() | MORE_BIT; } else { - frame[1] = seader_next_pcb(); + frame[1] = seader_next_dpcb(); } frame[2] = copy_length; frame_len = 3; @@ -116,7 +122,7 @@ void seader_send_t1(SeaderUartBridge* seader_uart, uint8_t* apdu, size_t len) { } frame[0] = NAD; - frame[1] = seader_next_pcb(); + frame[1] = seader_next_dpcb(); frame[2] = len; frame_len = 3; @@ -154,7 +160,8 @@ bool seader_recv_t1(Seader* seader, CCID_Message* message) { return false; } - if(rPCB == PCB) { + if(rPCB == cPCB) { + seader_next_cpcb(); if(seader_t_1_rx_buffer != NULL) { bit_buffer_append_bytes(seader_t_1_rx_buffer, message->payload + 3, LEN); @@ -183,7 +190,7 @@ bool seader_recv_t1(Seader* seader, CCID_Message* message) { return true; } return seader_worker_process_sam_message(seader, message->payload, message->dwLength); - } else if(rPCB == (PCB | MORE_BIT)) { + } else if(rPCB == (cPCB | MORE_BIT)) { FURI_LOG_D(TAG, "Received T=1 frame with more bit set"); if(seader_t_1_rx_buffer == NULL) { seader_t_1_rx_buffer = bit_buffer_alloc(512); @@ -192,13 +199,22 @@ bool seader_recv_t1(Seader* seader, CCID_Message* message) { seader_t_1_send_ack(seader); return false; } else if((rPCB & R_BLOCK) == R_BLOCK) { + uint8_t R_SEQ = (rPCB & R_SEQUENCE_NUMBER_MASK) >> 4; + uint8_t I_SEQ = (dPCB ^ 0x40) >> 6; + if(R_SEQ != I_SEQ) { + FURI_LOG_D( + TAG, + "Received R-Block: Incorrect sequence. Expected: %02X, Received: %02X", + I_SEQ, + R_SEQ); + + return false; + } + if(seader_t_1_tx_buffer != NULL) { // Send more data, re-using the buffer to trigger the code path that sends the next block SeaderWorker* seader_worker = seader->worker; SeaderUartBridge* seader_uart = seader_worker->uart; - // Move the R Block sequence bit to the I Block position - // PCB = (rPCB & R_SEQUENCE_NUMBER_MASK) << 2; - // FURI_LOG_D(TAG, "Received R-Block: sending next chunk. rPCB: %02x masked: %02x PCB: %02x", rPCB, (rPCB & R_SEQUENCE_NUMBER_MASK), PCB); seader_send_t1( seader_uart, (uint8_t*)bit_buffer_get_data(seader_t_1_tx_buffer), @@ -207,7 +223,7 @@ bool seader_recv_t1(Seader* seader, CCID_Message* message) { } } else { FURI_LOG_W( - TAG, "Invalid T=1 frame: PCB mismatch. Expected: %02X, Received: %02X", PCB, rPCB); + TAG, "Invalid T=1 frame: PCB mismatch. Expected: %02X, Received: %02X", cPCB, rPCB); } return false;