Просмотр исходного кода

continue work on picopass state machine

Eric Betts 2 лет назад
Родитель
Сommit
ec3ded124f
2 измененных файлов с 64 добавлено и 13 удалено
  1. 62 13
      sam_api.c
  2. 2 0
      sam_api.h

+ 62 - 13
sam_api.c

@@ -11,10 +11,10 @@ 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 read4Block6[] = {RFAL_PICOPASS_CMD_READ4, 0x06, 0x45, 0x56};
+uint8_t read4Block9[] = {RFAL_PICOPASS_CMD_READ4, 0x09, 0xB2, 0xAE};
+uint8_t read4Block10[] = {RFAL_PICOPASS_CMD_READ4, 0x0A, 0x29, 0x9C};
+uint8_t read4Block13[] = {RFAL_PICOPASS_CMD_READ4, 0x0D, 0x96, 0xE8};
 uint8_t updateBlock2[] = {RFAL_PICOPASS_CMD_UPDATE, 0x02};
 uint8_t updateBlock2[] = {RFAL_PICOPASS_CMD_UPDATE, 0x02};
 
 
 void* calloc(size_t count, size_t size) {
 void* calloc(size_t count, size_t size) {
@@ -24,31 +24,65 @@ void* calloc(size_t count, size_t size) {
 // Forward declarations
 // Forward declarations
 void seader_send_nfc_rx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t len);
 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);
 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) {
 void seader_picopass_state_machine(Seader* seader, uint8_t* buffer, size_t len) {
     SeaderWorker* seader_worker = seader->worker;
     SeaderWorker* seader_worker = seader->worker;
     SeaderUartBridge* seader_uart = seader_worker->uart;
     SeaderUartBridge* seader_uart = seader_worker->uart;
 
 
+    memset(display, 0, sizeof(display));
+    for(uint8_t i = 0; i < len; i++) {
+        snprintf(display + (i * 2), sizeof(display), "%02x", buffer[i]);
+    }
+    FURI_LOG_D(TAG, "Picopass State Macine %d: %s", len, display);
+
     BitBuffer* tx_buffer = bit_buffer_alloc(len);
     BitBuffer* tx_buffer = bit_buffer_alloc(len);
     bit_buffer_append_bytes(tx_buffer, buffer, len);
     bit_buffer_append_bytes(tx_buffer, buffer, len);
     BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
     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};
+    // TODO: have this come from the actual saved card
+    uint8_t csn[PICOPASS_BLOCK_LEN] = {0xf8, 0x7c, 0xd7, 0x12, 0xff, 0xff, 0x12, 0xe0};
+    uint8_t sr_aia[PICOPASS_BLOCK_LEN] = {0xFF, 0xff, 0xff, 0xff, 0xFF, 0xFf, 0xff, 0xFF};
     uint8_t epurse[PICOPASS_BLOCK_LEN] = {0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff};
     uint8_t epurse[PICOPASS_BLOCK_LEN] = {0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff};
+    uint8_t pacs_sr_cfg[PICOPASS_BLOCK_LEN] = {0xA3, 0x03, 0x03, 0x03, 0x00, 0x03, 0xe0, 0x14};
+
+    /*
+30 33 81 05 01 87 BC 0F
+45 A5 02 05 00 A6 08 81
+01 01 04 03 03 00 08 A7
+18 85 16 E0 8C 96 D4 1E
+26 55 12 79 6A 65 00 21
+C1 7D 19 27 CA 9F 80 35
+98 A9 02 05 00 05 00 00
+ */
+
+    uint8_t sio_first[PICOPASS_BLOCK_LEN * 4] = {
+  0x30, 0x33, 0x81, 0x05, 0x01, 0x87, 0xbc, 0x0f,
+  0x45, 0xa5, 0x02, 0x05, 0x00, 0xa6, 0x08, 0x81,
+  0x01, 0x01, 0x04, 0x03, 0x03, 0x00, 0x08, 0xa7,
+  0x18, 0x85, 0x16, 0xe0, 0x8c, 0x96, 0xd4, 0x1e
+    };
+    // NOTE: 8 byte overlap
+    uint8_t sio_second[PICOPASS_BLOCK_LEN * 4] = {
+  0x18, 0x85, 0x16, 0xe0, 0x8c, 0x96, 0xd4, 0x1e,
+  0x26, 0x55, 0x12, 0x79, 0x6a, 0x65, 0x00, 0x21,
+  0xc1, 0x7d, 0x19, 0x27, 0xca, 0x9f, 0x80, 0x35,
+  0x98, 0xa9, 0x02, 0x05, 0x00, 0x05, 0x00, 0x00
+    };
+
+    const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33, 0x78};
+
+    uint8_t tmac[4] = {};
+    uint8_t div_key[PICOPASS_BLOCK_LEN] = {};
 
 
     do {
     do {
         switch(buffer[0]) {
         switch(buffer[0]) {
         case RFAL_PICOPASS_CMD_READ_OR_IDENTIFY:
         case RFAL_PICOPASS_CMD_READ_OR_IDENTIFY:
             // append_bytes(rx, seader->[picopass]->AA1[buffer[1]].data, PICOPASS_BLOCK_LEN);
             // 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));
+            if(buffer[1] == AIA_INDEX) { // TODO: _INDEX
                 bit_buffer_append_bytes(rx_buffer, sr_aia, sizeof(sr_aia));
                 bit_buffer_append_bytes(rx_buffer, sr_aia, sizeof(sr_aia));
+            } else if (buffer[1] == PACS_CFG_INDEX) {
+                bit_buffer_append_bytes(rx_buffer, pacs_sr_cfg, sizeof(pacs_sr_cfg));
             }
             }
+            iso13239_crc_append(Iso13239CrcTypePicopass, rx_buffer);
             break;
             break;
         case RFAL_PICOPASS_CMD_UPDATE:
         case RFAL_PICOPASS_CMD_UPDATE:
             seader_worker_fake_epurse_update(tx_buffer, rx_buffer);
             seader_worker_fake_epurse_update(tx_buffer, rx_buffer);
@@ -59,7 +93,22 @@ void seader_picopass_state_machine(Seader* seader, uint8_t* buffer, size_t len)
             }
             }
             break;
             break;
         case RFAL_PICOPASS_CMD_CHECK:
         case RFAL_PICOPASS_CMD_CHECK:
+            //memcpy(cc, data->AA1[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data, sizeof(PicopassBlock));
+            loclass_iclass_calc_div_key(csn, picopass_iclass_key, div_key, false);
+            LoclassState_t cipher_state = loclass_opt_doTagMAC_1(epurse, div_key);
+            // loclass_opt_doBothMAC_2(cipher_state, rx_buffer+1, rmac, tmac, div_key);
 
 
+            loclass_opt_doTagMAC_2(cipher_state, buffer + 1, tmac, div_key);
+            bit_buffer_append_bytes(rx_buffer, tmac, sizeof(tmac));
+            break;
+        case RFAL_PICOPASS_CMD_READ4:
+            if(buffer[1] == 10) {
+                bit_buffer_append_bytes(rx_buffer, sio_first, sizeof(sio_first));
+            }
+            if(buffer[1] == 13) {
+                bit_buffer_append_bytes(rx_buffer, sio_second, sizeof(sio_second));
+            }
+            iso13239_crc_append(Iso13239CrcTypePicopass, rx_buffer);
             break;
             break;
         }
         }
 
 

+ 2 - 0
sam_api.h

@@ -1,6 +1,8 @@
 #pragma once
 #pragma once
 
 
 #include <nfc/helpers/iso13239_crc.h>
 #include <nfc/helpers/iso13239_crc.h>
+#include <optimized_ikeys.h>
+#include <optimized_cipher.h>
 
 
 #include "seader_i.h"
 #include "seader_i.h"
 #include "seader_credential.h"
 #include "seader_credential.h"