MX 10 месяцев назад
Родитель
Сommit
0cda8cf6e5
4 измененных файлов с 31 добавлено и 28 удалено
  1. 6 1
      readme.md
  2. 21 25
      sam_api.c
  3. 3 2
      seader_credential.c
  4. 1 0
      seader_credential.h

+ 6 - 1
readme.md

@@ -38,8 +38,13 @@ Buy it at [Red Team Tools](https://www.redteamtools.com/flippermeister/).
 
 ### Option 3: Smart Card 2 Click
 
+Buy HID SAM:
+ * [USA](https://www.cdw.com/product/hp-sim-for-hid-iclass-for-hip2-reader-security-sim/4854794)
+ * [Europe](https://www.rfideas-shop.com/en/kt-sim-se-sim-card-hid-iclass-and-seos-for-sphip-r.html)
+ * [Canada](https://www.pc-canada.com/item/hp-sim-for-hid-iclass-se-and-hid-iclass-seos-for-hip2-reader/y7c07a)
+ * [eBay](https://www.ebay.com/p/4037642616)
 
-Put SAM ([USA](https://www.cdw.com/product/hp-sim-for-hid-iclass-for-hip2-reader-security-sim/4854794) [EU](https://www.rfideas-shop.com/en/kt-sim-se-sim-card-hid-iclass-and-seos-for-sphip-r.html) [CA](https://www.pc-canada.com/item/hp-sim-for-hid-iclass-se-and-hid-iclass-seos-for-hip2-reader/y7c07a)) into **[adapter](https://a.co/d/1E9Zk1h)** (because of chip on top) and plug into **Smart Card 2 Click** ([Mikroe](https://www.mikroe.com/smart-card-2-click) [digikey](https://www.digikey.com/en/products/detail/mikroelektronika/MIKROE-5492/20840872) with cheaper US shipping). Connect Smart Card 2 Click to Flipper Zero (See `Connections` below).
+Put SAM into **[adapter](https://a.co/d/1E9Zk1h)** (because of chip on top) and plug into **Smart Card 2 Click** ([Mikroe](https://www.mikroe.com/smart-card-2-click) [digikey](https://www.digikey.com/en/products/detail/mikroelektronika/MIKROE-5492/20840872) with cheaper US shipping). Connect Smart Card 2 Click to Flipper Zero (See `Connections` below).
 
 Optionally 3d print a [case designed by sean](https://www.printables.com/model/543149-case-for-flipper-zero-devboard-smart2click-samsim)
 

+ 21 - 25
sam_api.c

@@ -19,12 +19,6 @@ static char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
 char asn1_log[SEADER_UART_RX_BUF_SIZE] = {0};
 #endif
 
-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 read4Block14[] = {RFAL_PICOPASS_CMD_READ4, 0x0E, 0x0d, 0xda};
-
 uint8_t updateBlock2[] = {RFAL_PICOPASS_CMD_UPDATE, 0x02};
 
 uint8_t ev2_request[] =
@@ -387,15 +381,14 @@ bool seader_unpack_pacs(Seader* seader, uint8_t* buf, size_t size) {
             ->op->print_struct(&asn_DEF_PAC, pac, 1, seader_print_struct_callback, pacDebug);
         if(strlen(pacDebug) > 0) {
             FURI_LOG_D(TAG, "Received pac: %s", pacDebug);
+        }
 
-            memset(display, 0, sizeof(display));
-            if(seader_credential->sio[0] == 0x30) {
-                for(uint8_t i = 0; i < seader_credential->sio_len; i++) {
-                    snprintf(
-                        display + (i * 2), sizeof(display), "%02x", seader_credential->sio[i]);
-                }
-                FURI_LOG_D(TAG, "SIO %s", display);
+        memset(display, 0, sizeof(display));
+        if(seader_credential->sio[0] == 0x30) {
+            for(uint8_t i = 0; i < seader_credential->sio_len; i++) {
+                snprintf(display + (i * 2), sizeof(display), "%02x", seader_credential->sio[i]);
             }
+            FURI_LOG_D(TAG, "SIO %s", display);
         }
 
         if(pac->size <= sizeof(seader_credential->credential)) {
@@ -634,18 +627,21 @@ void seader_capture_sio(BitBuffer* tx_buffer, BitBuffer* rx_buffer, SeaderCreden
     const uint8_t* rxBuffer = bit_buffer_get_data(rx_buffer);
 
     if(credential->type == SeaderCredentialTypePicopass) {
-        if(memcmp(buffer, read4Block6, len) == 0 && rxBuffer[0] == 0x30) {
-            memcpy(credential->sio, rxBuffer, 32);
-            credential->sio_len += 32;
-        } else if(memcmp(buffer, read4Block10, len) == 0 && rxBuffer[0] == 0x30) {
-            memcpy(credential->sio, rxBuffer, 32);
-            credential->sio_len += 32;
-        } else if(memcmp(buffer, read4Block9, len) == 0) {
-            memcpy(credential->sio + 32, rxBuffer + 8, 24);
-            credential->sio_len += 24;
-        } else if(memcmp(buffer, read4Block13, len) == 0) {
-            memcpy(credential->sio + 32, rxBuffer + 8, 24);
-            credential->sio_len += 24;
+        if(buffer[0] == RFAL_PICOPASS_CMD_READ_OR_IDENTIFY) {
+            FURI_LOG_D(TAG, "Picopass Read1 block %02x", buffer[1]);
+        }
+        if(buffer[0] == RFAL_PICOPASS_CMD_READ4) {
+            FURI_LOG_D(TAG, "Picopass Read4 block %02x", buffer[1]);
+        }
+
+        if(buffer[0] == RFAL_PICOPASS_CMD_READ4) {
+            uint8_t block_num = buffer[1];
+            if(credential->sio_len == 0 && rxBuffer[0] == 0x30) {
+                credential->sio_start_block = block_num;
+            }
+            uint8_t offset = (block_num - credential->sio_start_block) * PICOPASS_BLOCK_LEN;
+            memcpy(credential->sio + offset, rxBuffer, PICOPASS_BLOCK_LEN * 4);
+            credential->sio_len += PICOPASS_BLOCK_LEN * 4;
         }
     } else if(credential->type == SeaderCredentialType14A) {
         // Desfire EV1 passes SIO in the clear

+ 3 - 2
seader_credential.c

@@ -71,10 +71,10 @@ static bool seader_credential_load(SeaderCredential* cred, FuriString* path, boo
         cred->credential = swapped;
 
         // Optional SIO/Diversifier
-        flipper_format_read_hex(file, "SIO", cred->sio, sizeof(cred->sio));
         cred->sio_len = sizeof(cred->sio); // No way to know real length;
-        flipper_format_read_hex(file, "Diversifier", cred->diversifier, sizeof(cred->diversifier));
         cred->diversifier_len = sizeof(cred->diversifier); // No way to know real length;
+        flipper_format_read_hex(file, "SIO", cred->sio, cred->sio_len);
+        flipper_format_read_hex(file, "Diversifier", cred->diversifier, cred->diversifier_len);
 
         parsed = true;
     } while(false);
@@ -639,6 +639,7 @@ void seader_credential_clear(SeaderCredential* cred) {
     cred->type = SeaderCredentialTypeNone;
     memset(cred->sio, 0, sizeof(cred->sio));
     cred->sio_len = 0;
+    cred->sio_start_block = 0;
     memset(cred->diversifier, 0, sizeof(cred->diversifier));
     cred->diversifier_len = 0;
     furi_string_reset(cred->load_path);

+ 1 - 0
seader_credential.h

@@ -41,6 +41,7 @@ typedef struct {
     uint8_t sio_len;
     uint8_t diversifier[8];
     uint8_t diversifier_len;
+    uint8_t sio_start_block; // for iClass SE vs iClass SR
     bool isDesfire;
     SeaderCredentialType type;
     SeaderCredentialSaveFormat save_format;