diff options
Diffstat (limited to 'applications/picopass/picopass_worker.c')
-rw-r--r-- | applications/picopass/picopass_worker.c | 54 |
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"); |