Eric Betts 2 лет назад
Родитель
Сommit
be889102c1
3 измененных файлов с 69 добавлено и 15 удалено
  1. 61 7
      sam_api.c
  2. 1 0
      sam_api.h
  3. 7 8
      seader_worker.c

+ 61 - 7
sam_api.c

@@ -11,10 +11,68 @@ static char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
 char asn1_log[SEADER_UART_RX_BUF_SIZE] = {0};
 char asn1_log[SEADER_UART_RX_BUF_SIZE] = {0};
 bool requestPacs = true;
 bool requestPacs = true;
 
 
+uint8_t read4Block6[] = {0x06, 0x06, 0x45, 0x56};
+uint8_t read4Block9[] = {0x06, 0x09, 0xB2, 0xAE};
+uint8_t read4Block10[] = {0x06, 0x0A, 0x29, 0x9C};
+uint8_t read4Block13[] = {0x06, 0x0D, 0x96, 0xE8};
+uint8_t updateBlock2[] = {RFAL_PICOPASS_CMD_UPDATE, 0x02};
+
 void* calloc(size_t count, size_t size) {
 void* calloc(size_t count, size_t size) {
     return malloc(count * size);
     return malloc(count * size);
 }
 }
 
 
+// Forward declarations
+void seader_send_nfc_rx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t len);
+PicopassError seader_worker_fake_epurse_update(BitBuffer* tx_buffer, BitBuffer* rx_buffer);
+static uint16_t seader_worker_picopass_calculate_ccitt(
+    uint16_t preloadValue,
+    const uint8_t* buf,
+    uint16_t length);
+
+void seader_picopass_state_machine(Seader* seader, uint8_t* buffer, size_t len) {
+    SeaderWorker* seader_worker = seader->worker;
+    SeaderUartBridge* seader_uart = seader_worker->uart;
+
+    BitBuffer* tx_buffer = bit_buffer_alloc(len);
+    bit_buffer_append_bytes(tx_buffer, buffer, len);
+    BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
+    uint8_t sr_aia[PICOPASS_BLOCK_LEN + 2] = {
+        0xFF, 0xff, 0xff, 0xff, 0xFF, 0xFf, 0xff, 0xFF, 0x00, 0x00};
+    uint8_t epurse[PICOPASS_BLOCK_LEN] = {0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff};
+
+    do {
+        switch(buffer[0]) {
+        case RFAL_PICOPASS_CMD_READ_OR_IDENTIFY:
+            // append_bytes(rx, seader->[picopass]->AA1[buffer[1]].data, PICOPASS_BLOCK_LEN);
+            if(buffer[1] == 5) { // TODO: _INDEX
+                uint16_t crc = seader_worker_picopass_calculate_ccitt(0xE012, sr_aia, 8);
+                memcpy(sr_aia + 8, &crc, sizeof(uint16_t));
+                bit_buffer_append_bytes(rx_buffer, sr_aia, sizeof(sr_aia));
+            }
+            break;
+        case RFAL_PICOPASS_CMD_UPDATE:
+            seader_worker_fake_epurse_update(tx_buffer, rx_buffer);
+            break;
+        case RFAL_PICOPASS_CMD_READCHECK_KD:
+            if(buffer[1] == 2) { // TODO: _INDEX
+                bit_buffer_append_bytes(rx_buffer, epurse, sizeof(epurse));
+            }
+            break;
+        case RFAL_PICOPASS_CMD_CHECK:
+
+            break;
+        }
+
+        seader_send_nfc_rx(
+            seader_uart,
+            (uint8_t*)bit_buffer_get_data(rx_buffer),
+            bit_buffer_get_size_bytes(rx_buffer));
+
+    } while(false);
+    bit_buffer_free(tx_buffer);
+    bit_buffer_free(rx_buffer);
+}
+
 bool seader_send_apdu(
 bool seader_send_apdu(
     SeaderUartBridge* seader_uart,
     SeaderUartBridge* seader_uart,
     uint8_t CLA,
     uint8_t CLA,
@@ -339,12 +397,6 @@ void seader_send_nfc_rx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t l
     ASN_STRUCT_FREE(asn_DEF_Response, response);
     ASN_STRUCT_FREE(asn_DEF_Response, response);
 }
 }
 
 
-uint8_t read4Block6[] = {0x06, 0x06, 0x45, 0x56};
-uint8_t read4Block9[] = {0x06, 0x09, 0xB2, 0xAE};
-uint8_t read4Block10[] = {0x06, 0x0A, 0x29, 0x9C};
-uint8_t read4Block13[] = {0x06, 0x0D, 0x96, 0xE8};
-uint8_t updateBlock2[] = {0x87, 0x02}; // TODO
-
 void seader_capture_sio(BitBuffer* tx_buffer, BitBuffer* rx_buffer, SeaderCredential* credential) {
 void seader_capture_sio(BitBuffer* tx_buffer, BitBuffer* rx_buffer, SeaderCredential* credential) {
     const uint8_t* buffer = bit_buffer_get_data(tx_buffer);
     const uint8_t* buffer = bit_buffer_get_data(tx_buffer);
     size_t len = bit_buffer_get_size_bytes(tx_buffer);
     size_t len = bit_buffer_get_size_bytes(tx_buffer);
@@ -491,7 +543,9 @@ void seader_parse_nfc_command_transmit(
         frameProtocol);
         frameProtocol);
 #endif
 #endif
 
 
-    if(frameProtocol == FrameProtocol_iclass) {
+    if(seader->credential->type == SeaderCredentialTypeVirtual) {
+        seader_picopass_state_machine(seader, nfcSend->data.buf, nfcSend->data.size);
+    } else if(frameProtocol == FrameProtocol_iclass) {
         seader_iso15693_transmit(
         seader_iso15693_transmit(
             seader, spc->picopass_poller, nfcSend->data.buf, nfcSend->data.size);
             seader, spc->picopass_poller, nfcSend->data.buf, nfcSend->data.size);
     } else if(frameProtocol == FrameProtocol_nfc) {
     } else if(frameProtocol == FrameProtocol_nfc) {

+ 1 - 0
sam_api.h

@@ -6,6 +6,7 @@
 #include "seader_credential.h"
 #include "seader_credential.h"
 #include "seader_bridge.h"
 #include "seader_bridge.h"
 #include "seader_worker.h"
 #include "seader_worker.h"
+#include "protocol/rfal_picopass.h"
 
 
 #include <Payload.h>
 #include <Payload.h>
 
 

+ 7 - 8
seader_worker.c

@@ -177,14 +177,13 @@ void seader_worker_virtual_credential(Seader* seader) {
                     view_dispatcher_send_custom_event(
                     view_dispatcher_send_custom_event(
                         seader->view_dispatcher, SeaderCustomEventWorkerExit);
                         seader->view_dispatcher, SeaderCustomEventWorkerExit);
                 }
                 }
-            if(seader_process_success_response_i(
-                   seader, seaderApdu.buf, seaderApdu.len, true, NULL)) {
-                // no-op
-            } else {
-                FURI_LOG_I(TAG, "Response false");
-                running = false;
-            }
-
+                if(seader_process_success_response_i(
+                       seader, seaderApdu.buf, seaderApdu.len, true, NULL)) {
+                    // no-op
+                } else {
+                    FURI_LOG_I(TAG, "Response false");
+                    running = false;
+                }
 
 
                 // fake being SR
                 // fake being SR
                 // picopass commands
                 // picopass commands