Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'applications/picopass/picopass_worker.c')
-rw-r--r--applications/picopass/picopass_worker.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/applications/picopass/picopass_worker.c b/applications/picopass/picopass_worker.c
index 645a1bce..7ecfbc3b 100644
--- a/applications/picopass/picopass_worker.c
+++ b/applications/picopass/picopass_worker.c
@@ -55,12 +55,11 @@ static ReturnCode picopass_worker_parse_wiegand(uint8_t* data, PicopassWiegandRe
if(record->bitLength == 26) {
uint8_t* v4 = data + 4;
- v4[0] = 0;
-
uint32_t bot = v4[3] | (v4[2] << 8) | (v4[1] << 16) | (v4[0] << 24);
record->CardNumber = (bot >> 1) & 0xFFFF;
record->FacilityCode = (bot >> 17) & 0xFF;
+ FURI_LOG_D(TAG, "FC:%u CN: %u\n", record->FacilityCode, record->CardNumber);
record->valid = true;
} else {
record->CardNumber = 0;
@@ -165,7 +164,7 @@ ReturnCode picopass_detect_card(int timeout) {
return ERR_NONE;
}
-ReturnCode picopass_read_card(ApplicationArea* AA1) {
+ReturnCode picopass_read_card(PicopassBlock* AA1) {
rfalPicoPassIdentifyRes idRes;
rfalPicoPassSelectRes selRes;
rfalPicoPassReadCheckRes rcRes;
@@ -205,10 +204,20 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) {
return err;
}
- for(size_t i = 0; i < 4; i++) {
- FURI_LOG_D(TAG, "rfalPicoPassPollerReadBlock block %d", i + 6);
+ rfalPicoPassReadBlockRes csn;
+ err = rfalPicoPassPollerReadBlock(PICOPASS_CSN_BLOCK_INDEX, &csn);
+ memcpy(AA1[PICOPASS_CSN_BLOCK_INDEX].data, csn.data, sizeof(csn.data));
+
+ rfalPicoPassReadBlockRes cfg;
+ err = rfalPicoPassPollerReadBlock(PICOPASS_CONFIG_BLOCK_INDEX, &cfg);
+ memcpy(AA1[PICOPASS_CONFIG_BLOCK_INDEX].data, cfg.data, sizeof(cfg.data));
+
+ size_t app_limit = cfg.data[0] < PICOPASS_MAX_APP_LIMIT ? cfg.data[0] : PICOPASS_MAX_APP_LIMIT;
+
+ for(size_t i = 2; i < app_limit; i++) {
+ FURI_LOG_D(TAG, "rfalPicoPassPollerReadBlock block %d", i);
rfalPicoPassReadBlockRes block;
- err = rfalPicoPassPollerReadBlock(i + 6, &block);
+ err = rfalPicoPassPollerReadBlock(i, &block);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "rfalPicoPassPollerReadBlock error %d", err);
return err;
@@ -217,7 +226,7 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) {
FURI_LOG_D(
TAG,
"rfalPicoPassPollerReadBlock %d %02x%02x%02x%02x%02x%02x%02x%02x",
- i + 6,
+ i,
block.data[0],
block.data[1],
block.data[2],
@@ -227,7 +236,7 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) {
block.data[6],
block.data[7]);
- memcpy(&(AA1->block[i]), &block, sizeof(block));
+ memcpy(AA1[i].data, block.data, sizeof(block.data));
}
return ERR_NONE;
@@ -251,7 +260,7 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) {
picopass_device_data_clear(picopass_worker->dev_data);
PicopassDeviceData* dev_data = picopass_worker->dev_data;
- ApplicationArea* AA1 = &dev_data->AA1;
+ PicopassBlock* AA1 = dev_data->AA1;
PicopassPacs* pacs = &dev_data->pacs;
ReturnCode err;
@@ -263,34 +272,39 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) {
FURI_LOG_E(TAG, "picopass_read_card error %d", err);
}
- pacs->biometrics = AA1->block[0].data[4];
- pacs->encryption = AA1->block[0].data[7];
+ // Thank you proxmark!
+ pacs->legacy = (memcmp(AA1[5].data, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0);
+ pacs->se_enabled = (memcmp(AA1[5].data, "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0);
+
+ pacs->biometrics = AA1[6].data[4];
+ pacs->pin_length = AA1[6].data[6] & 0x0F;
+ pacs->encryption = AA1[6].data[7];
- if(pacs->encryption == 0x17) {
+ if(pacs->encryption == PicopassDeviceEncryption3DES) {
FURI_LOG_D(TAG, "3DES Encrypted");
- err = picopass_worker_decrypt(AA1->block[1].data, pacs->credential);
+ err = picopass_worker_decrypt(AA1[7].data, pacs->credential);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "decrypt error %d", err);
break;
}
- err = picopass_worker_decrypt(AA1->block[2].data, pacs->pin0);
+ err = picopass_worker_decrypt(AA1[8].data, pacs->pin0);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "decrypt error %d", err);
break;
}
- err = picopass_worker_decrypt(AA1->block[3].data, pacs->pin1);
+ err = picopass_worker_decrypt(AA1[9].data, pacs->pin1);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "decrypt error %d", err);
break;
}
- } else if(pacs->encryption == 0x14) {
+ } else if(pacs->encryption == PicopassDeviceEncryptionNone) {
FURI_LOG_D(TAG, "No Encryption");
- memcpy(pacs->credential, AA1->block[1].data, RFAL_PICOPASS_MAX_BLOCK_LEN);
- memcpy(pacs->pin0, AA1->block[2].data, RFAL_PICOPASS_MAX_BLOCK_LEN);
- memcpy(pacs->pin1, AA1->block[3].data, RFAL_PICOPASS_MAX_BLOCK_LEN);
- } else if(pacs->encryption == 0x15) {
+ memcpy(pacs->credential, AA1[7].data, PICOPASS_BLOCK_LEN);
+ memcpy(pacs->pin0, AA1[8].data, PICOPASS_BLOCK_LEN);
+ memcpy(pacs->pin1, AA1[9].data, PICOPASS_BLOCK_LEN);
+ } else if(pacs->encryption == PicopassDeviceEncryptionDES) {
FURI_LOG_D(TAG, "DES Encrypted");
} else {
FURI_LOG_D(TAG, "Unknown encryption");