Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions nfc_magic/.catalog/changelog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 1.1
- Rework application with new NFC API
## 1.0
- Initial release
2 changes: 1 addition & 1 deletion nfc_magic/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ App(
],
stack_size=4 * 1024,
fap_description="Application for writing to NFC tags with modifiable sector 0",
fap_version="1.0",
fap_version="1.1",
fap_icon="assets/125_10px.png",
fap_category="NFC",
fap_private_libs=[
Expand Down
2 changes: 2 additions & 0 deletions nfc_rfid_detector/.catalog/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## 1.2
- Rework application with new NFC API
## 1.1
- App rename, removed About screen
## 1.0
Expand Down
2 changes: 1 addition & 1 deletion nfc_rfid_detector/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ App(
requires=["gui"],
stack_size=4 * 1024,
fap_description="Identify the reader type: NFC (13 MHz) and/or RFID (125 KHz).",
fap_version="1.1",
fap_version="1.2",
fap_icon="nfc_rfid_detector_10px.png",
fap_category="Tools",
fap_icon_assets="images",
Expand Down
2 changes: 2 additions & 0 deletions picopass/.catalog/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## 1.7
- Rework application with new NFC API
## 1.6
- Faster loclass response collection
- Save as LF for all bit lengths
Expand Down
2 changes: 1 addition & 1 deletion picopass/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ App(
],
stack_size=4 * 1024,
fap_description="App to communicate with NFC tags using the PicoPass(iClass) format",
fap_version="1.6",
fap_version="1.7",
fap_icon="125_10px.png",
fap_category="NFC",
fap_libs=["mbedtls"],
Expand Down
9 changes: 4 additions & 5 deletions picopass/picopass.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ void picopass_tick_event_callback(void* context) {
Picopass* picopass_alloc() {
Picopass* picopass = malloc(sizeof(Picopass));

picopass->worker = picopass_worker_alloc();
picopass->view_dispatcher = view_dispatcher_alloc();
picopass->scene_manager = scene_manager_alloc(&picopass_scene_handlers, picopass);
view_dispatcher_enable_queue(picopass->view_dispatcher);
Expand All @@ -35,6 +34,8 @@ Picopass* picopass_alloc() {
view_dispatcher_set_tick_event_callback(
picopass->view_dispatcher, picopass_tick_event_callback, 100);

picopass->nfc = nfc_alloc();

// Picopass device
picopass->dev = picopass_device_alloc();

Expand Down Expand Up @@ -100,6 +101,8 @@ void picopass_free(Picopass* picopass) {
picopass_device_free(picopass->dev);
picopass->dev = NULL;

nfc_free(picopass->nfc);

// Submenu
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewMenu);
submenu_free(picopass->submenu);
Expand Down Expand Up @@ -130,10 +133,6 @@ void picopass_free(Picopass* picopass) {
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewLoclass);
loclass_free(picopass->loclass);

// Worker
picopass_worker_stop(picopass->worker);
picopass_worker_free(picopass->worker);

// View Dispatcher
view_dispatcher_free(picopass->view_dispatcher);

Expand Down
35 changes: 8 additions & 27 deletions picopass/picopass_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
}
if(!block_read) break;

if(picopass_device_parse_credential(AA1, pacs) != ERR_NONE) break;
if(picopass_device_parse_wiegand(pacs->credential, pacs) != ERR_NONE) break;
picopass_device_parse_credential(AA1, pacs);
picopass_device_parse_wiegand(pacs->credential, pacs);

parsed = true;
} while(false);
Expand Down Expand Up @@ -343,43 +343,28 @@ void picopass_device_set_loading_callback(
dev->loading_cb_ctx = context;
}

ReturnCode picopass_device_decrypt(uint8_t* enc_data, uint8_t* dec_data) {
void picopass_device_decrypt(uint8_t* enc_data, uint8_t* dec_data) {
uint8_t key[32] = {0};
memcpy(key, picopass_iclass_decryptionkey, sizeof(picopass_iclass_decryptionkey));
mbedtls_des3_context ctx;
mbedtls_des3_init(&ctx);
mbedtls_des3_set2key_dec(&ctx, key);
mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data);
mbedtls_des3_free(&ctx);
return ERR_NONE;
}

ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs) {
ReturnCode err;

void picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs) {
pacs->biometrics = AA1[6].data[4];
pacs->pin_length = AA1[6].data[6] & 0x0F;
pacs->encryption = AA1[6].data[7];

if(pacs->encryption == PicopassDeviceEncryption3DES) {
FURI_LOG_D(TAG, "3DES Encrypted");
err = picopass_device_decrypt(AA1[7].data, pacs->credential);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "decrypt error %d", err);
return err;
}
picopass_device_decrypt(AA1[7].data, pacs->credential);

err = picopass_device_decrypt(AA1[8].data, pacs->pin0);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "decrypt error %d", err);
return err;
}
picopass_device_decrypt(AA1[8].data, pacs->pin0);

err = picopass_device_decrypt(AA1[9].data, pacs->pin1);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "decrypt error %d", err);
return err;
}
picopass_device_decrypt(AA1[9].data, pacs->pin1);
} else if(pacs->encryption == PicopassDeviceEncryptionNone) {
FURI_LOG_D(TAG, "No Encryption");
memcpy(pacs->credential, AA1[7].data, PICOPASS_BLOCK_LEN);
Expand All @@ -392,11 +377,9 @@ ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pa
}

pacs->sio = (AA1[10].data[0] == 0x30); // rough check

return ERR_NONE;
}

ReturnCode picopass_device_parse_wiegand(uint8_t* credential, PicopassPacs* pacs) {
void picopass_device_parse_wiegand(uint8_t* credential, PicopassPacs* pacs) {
uint32_t* halves = (uint32_t*)credential;
if(halves[0] == 0) {
uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[1]));
Expand All @@ -413,8 +396,6 @@ ReturnCode picopass_device_parse_wiegand(uint8_t* credential, PicopassPacs* pacs
swapped = swapped ^ sentinel;
memcpy(credential, &swapped, sizeof(uint64_t));
FURI_LOG_D(TAG, "PACS: (%d) %016llx", pacs->bitLength, swapped);

return ERR_NONE;
}

bool picopass_device_hid_csn(PicopassDevice* dev) {
Expand Down
5 changes: 2 additions & 3 deletions picopass/picopass_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ typedef struct {
typedef struct {
PicopassBlock AA1[PICOPASS_MAX_APP_LIMIT];
PicopassPacs pacs;
IclassEliteDictAttackData iclass_elite_dict_attack_data;
} PicopassDeviceData;

typedef struct {
Expand Down Expand Up @@ -147,6 +146,6 @@ void picopass_device_set_loading_callback(
PicopassLoadingCallback callback,
void* context);

ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs);
ReturnCode picopass_device_parse_wiegand(uint8_t* credential, PicopassPacs* pacs);
void picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs);
void picopass_device_parse_wiegand(uint8_t* credential, PicopassPacs* pacs);
bool picopass_device_hid_csn(PicopassDevice* dev);
42 changes: 40 additions & 2 deletions picopass/picopass_i.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include "picopass.h"
#include "picopass_worker.h"
#include "picopass_device.h"

#include "rfal_picopass.h"
Expand Down Expand Up @@ -29,8 +28,17 @@
#include <lib/toolbox/path.h>
#include <picopass_icons.h>

#include <nfc/nfc.h>
#include <nfc/helpers/nfc_dict.h>
#include "protocol/picopass_poller.h"
#include "protocol/picopass_listener.h"

#define PICOPASS_TEXT_STORE_SIZE 128

#define PICOPASS_ICLASS_ELITE_DICT_FLIPPER_NAME APP_ASSETS_PATH("iclass_elite_dict.txt")
#define PICOPASS_ICLASS_STANDARD_DICT_FLIPPER_NAME APP_ASSETS_PATH("iclass_standard_dict.txt")
#define PICOPASS_ICLASS_ELITE_DICT_USER_NAME APP_DATA_PATH("assets/iclass_elite_dict_user.txt")

enum PicopassCustomEvent {
// Reserve first 100 events for button types and indexes, starting from 0
PicopassCustomEventReserved = 100,
Expand All @@ -40,21 +48,47 @@ enum PicopassCustomEvent {
PicopassCustomEventByteInputDone,
PicopassCustomEventTextInputDone,
PicopassCustomEventDictAttackSkip,
PicopassCustomEventDictAttackUpdateView,
PicopassCustomEventLoclassGotMac,
PicopassCustomEventLoclassGotStandardKey,

PicopassCustomEventPollerSuccess,
PicopassCustomEventPollerFail,
};

typedef enum {
EventTypeTick,
EventTypeKey,
} EventType;

typedef struct {
const char* name;
uint16_t total_keys;
uint16_t current_key;
bool card_detected;
} PicopassDictAttackContext;

typedef struct {
uint8_t key_to_write[PICOPASS_BLOCK_LEN];
bool is_elite;
} PicopassWriteKeyContext;

typedef struct {
size_t macs_collected;
} PicopassLoclassContext;

struct Picopass {
PicopassWorker* worker;
ViewDispatcher* view_dispatcher;
Gui* gui;
NotificationApp* notifications;
SceneManager* scene_manager;
PicopassDevice* dev;

Nfc* nfc;
PicopassPoller* poller;
PicopassListener* listener;
NfcDict* dict;

char text_store[PICOPASS_TEXT_STORE_SIZE + 1];
FuriString* text_box_store;
uint8_t byte_input_store[PICOPASS_BLOCK_LEN];
Expand All @@ -68,6 +102,10 @@ struct Picopass {
Widget* widget;
DictAttack* dict_attack;
Loclass* loclass;

PicopassDictAttackContext dict_attack_ctx;
PicopassWriteKeyContext write_key_context;
PicopassLoclassContext loclass_context;
};

typedef enum {
Expand Down
Loading