Skip to content

Commit

Permalink
update ofw plugins, add new plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
xMasterX committed Aug 13, 2023
1 parent f3107fd commit 9137b58
Show file tree
Hide file tree
Showing 33 changed files with 1,298 additions and 98 deletions.
3 changes: 2 additions & 1 deletion application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ App(
"gui",
],
stack_size=4 * 1024,
order=30,
fap_description="App to communicate with NFC tags using the PicoPass format",
fap_version="1.0",
fap_icon="125_10px.png",
fap_category="NFC",
fap_libs=["mbedtls"],
Expand Down
17 changes: 16 additions & 1 deletion lib/loclass/optimized_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,22 @@ void loclass_opt_doTagMAC_2(
loclass_opt_output(div_key_p, &_init, mac);
}

void loclass_iclass_calc_div_key(uint8_t* csn, uint8_t* key, uint8_t* div_key, bool elite) {
void loclass_opt_doBothMAC_2(
LoclassState_t _init,
uint8_t* nr,
uint8_t rmac[4],
uint8_t tmac[4],
const uint8_t* div_key_p) {
loclass_opt_suc(div_key_p, &_init, nr, 4, false);
// Save internal state for reuse before outputting
LoclassState_t nr_state = _init;
loclass_opt_output(div_key_p, &_init, rmac);
// Feed the 32 0 bits for the tag mac
loclass_opt_suc(div_key_p, &nr_state, NULL, 0, true);
loclass_opt_output(div_key_p, &nr_state, tmac);
}

void loclass_iclass_calc_div_key(uint8_t* csn, const uint8_t* key, uint8_t* div_key, bool elite) {
if(elite) {
uint8_t keytable[128] = {0};
uint8_t key_index[8] = {0};
Expand Down
17 changes: 16 additions & 1 deletion lib/loclass/optimized_cipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ void loclass_opt_doTagMAC_2(
uint8_t mac[4],
const uint8_t* div_key_p);

/**
* The same as loclass_opt_doTagMAC_2, but calculates both the reader and tag MACs at the same time
* @param _init - precalculated cipher state
* @param nr - the reader challenge
* @param rmac - where to store the reader MAC
* @param tmac - where to store the tag MAC
* @param div_key_p - the key to use
*/
void loclass_opt_doBothMAC_2(
LoclassState_t _init,
uint8_t* nr,
uint8_t rmac[4],
uint8_t tmac[4],
const uint8_t* div_key_p);

void loclass_doMAC_N(uint8_t* in_p, uint8_t in_size, uint8_t* div_key_p, uint8_t mac[4]);
void loclass_iclass_calc_div_key(uint8_t* csn, uint8_t* key, uint8_t* div_key, bool elite);
void loclass_iclass_calc_div_key(uint8_t* csn, const uint8_t* key, uint8_t* div_key, bool elite);
#endif // OPTIMIZED_CIPHER_H
6 changes: 3 additions & 3 deletions lib/loclass/optimized_elite.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Definition 14. Define the rotate key function loclass_rk : (F 82 ) 8 × N → (F
loclass_rk(x [0] . . . x [7] , 0) = x [0] . . . x [7]
loclass_rk(x [0] . . . x [7] , n + 1) = loclass_rk(loclass_rl(x [0] ) . . . loclass_rl(x [7] ), n)
**/
static void loclass_rk(uint8_t* key, uint8_t n, uint8_t* outp_key) {
static void loclass_rk(const uint8_t* key, uint8_t n, uint8_t* outp_key) {
memcpy(outp_key, key, 8);
uint8_t j;
while(n-- > 0) {
Expand All @@ -172,7 +172,7 @@ static void loclass_desdecrypt_iclass(uint8_t* iclass_key, uint8_t* input, uint8
mbedtls_des_crypt_ecb(&loclass_ctx_dec, input, output);
}

static void loclass_desencrypt_iclass(uint8_t* iclass_key, uint8_t* input, uint8_t* output) {
static void loclass_desencrypt_iclass(const uint8_t* iclass_key, uint8_t* input, uint8_t* output) {
uint8_t key_std_format[8] = {0};
loclass_permutekey_rev(iclass_key, key_std_format);
mbedtls_des_setkey_enc(&loclass_ctx_enc, key_std_format);
Expand All @@ -185,7 +185,7 @@ static void loclass_desencrypt_iclass(uint8_t* iclass_key, uint8_t* input, uint8
* @param loclass_hash1 loclass_hash1
* @param key_sel output key_sel=h[loclass_hash1[i]]
*/
void loclass_hash2(uint8_t* key64, uint8_t* outp_keytable) {
void loclass_hash2(const uint8_t* key64, uint8_t* outp_keytable) {
/**
*Expected:
* High Security Key Table
Expand Down
2 changes: 1 addition & 1 deletion lib/loclass/optimized_elite.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ void loclass_permutekey_rev(const uint8_t key[8], uint8_t dest[8]);
* @param k output
*/
void loclass_hash1(const uint8_t* csn, uint8_t* k);
void loclass_hash2(uint8_t* key64, uint8_t* outp_keytable);
void loclass_hash2(const uint8_t* key64, uint8_t* outp_keytable);

#endif
100 changes: 100 additions & 0 deletions loclass_writer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "loclass_writer.h"

#include <furi/furi.h>
#include <furi_hal.h>
#include <storage/storage.h>
#include <stream/stream.h>
#include <stream/buffered_file_stream.h>

struct LoclassWriter {
Stream* file_stream;
};

#define LOCLASS_LOGS_PATH EXT_PATH("apps_data/picopass/.loclass.log")

LoclassWriter* loclass_writer_alloc() {
LoclassWriter* instance = malloc(sizeof(LoclassWriter));
Storage* storage = furi_record_open(RECORD_STORAGE);
instance->file_stream = buffered_file_stream_alloc(storage);
if(!buffered_file_stream_open(
instance->file_stream, LOCLASS_LOGS_PATH, FSAM_WRITE, FSOM_OPEN_APPEND)) {
buffered_file_stream_close(instance->file_stream);
stream_free(instance->file_stream);
free(instance);
instance = NULL;
}

furi_record_close(RECORD_STORAGE);

return instance;
}

void loclass_writer_free(LoclassWriter* instance) {
furi_assert(instance != NULL);

buffered_file_stream_close(instance->file_stream);
stream_free(instance->file_stream);
free(instance);
}

bool loclass_writer_write_start_stop(LoclassWriter* instance, bool start) {
FuriHalRtcDateTime curr_dt;
furi_hal_rtc_get_datetime(&curr_dt);
uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);

FuriString* str = furi_string_alloc_printf(
"loclass-v1-info ts %lu %s\n", curr_ts, start ? "started" : "finished");
bool write_success = stream_write_string(instance->file_stream, str);
furi_string_free(str);
return write_success;
}

bool loclass_writer_write_params(
LoclassWriter* instance,
uint8_t log_no,
const uint8_t csn[8],
const uint8_t epurse[8],
const uint8_t nr[4],
const uint8_t mac[4]) {
furi_assert(instance != NULL);

FuriHalRtcDateTime curr_dt;
furi_hal_rtc_get_datetime(&curr_dt);
uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);

FuriString* str = furi_string_alloc_printf(
"loclass-v1-mac ts %lu no %u "
"csn %02x%02x%02x%02x%02x%02x%02x%02x "
"cc %02x%02x%02x%02x%02x%02x%02x%02x "
"nr %02x%02x%02x%02x "
"mac %02x%02x%02x%02x\n",
curr_ts,
log_no,
csn[0],
csn[1],
csn[2],
csn[3],
csn[4],
csn[5],
csn[6],
csn[7],
epurse[0],
epurse[1],
epurse[2],
epurse[3],
epurse[4],
epurse[5],
epurse[6],
epurse[7],
nr[0],
nr[1],
nr[2],
nr[3],
mac[0],
mac[1],
mac[2],
mac[3]);
bool write_success = stream_write_string(instance->file_stream, str);
furi_string_free(str);
return write_success;
}
20 changes: 20 additions & 0 deletions loclass_writer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <stdint.h>
#include <stdbool.h>

typedef struct LoclassWriter LoclassWriter;

LoclassWriter* loclass_writer_alloc();

void loclass_writer_free(LoclassWriter* instance);

bool loclass_writer_write_start_stop(LoclassWriter* instance, bool start);

bool loclass_writer_write_params(
LoclassWriter* instance,
uint8_t log_no,
const uint8_t csn[8],
const uint8_t epurse[8],
const uint8_t nr[4],
const uint8_t mac[4]);
31 changes: 30 additions & 1 deletion picopass.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ Picopass* picopass_alloc() {
PicopassViewTextInput,
text_input_get_view(picopass->text_input));

// Byte Input
picopass->byte_input = byte_input_alloc();
view_dispatcher_add_view(
picopass->view_dispatcher,
PicopassViewByteInput,
byte_input_get_view(picopass->byte_input));

// Custom Widget
picopass->widget = widget_alloc();
view_dispatcher_add_view(
Expand All @@ -79,6 +86,10 @@ Picopass* picopass_alloc() {
PicopassViewDictAttack,
dict_attack_get_view(picopass->dict_attack));

picopass->loclass = loclass_alloc();
view_dispatcher_add_view(
picopass->view_dispatcher, PicopassViewLoclass, loclass_get_view(picopass->loclass));

return picopass;
}

Expand All @@ -105,13 +116,20 @@ void picopass_free(Picopass* picopass) {
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewTextInput);
text_input_free(picopass->text_input);

// ByteInput
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewByteInput);
byte_input_free(picopass->byte_input);

// Custom Widget
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewWidget);
widget_free(picopass->widget);

view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewDictAttack);
dict_attack_free(picopass->dict_attack);

view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewLoclass);
loclass_free(picopass->loclass);

// Worker
picopass_worker_stop(picopass->worker);
picopass_worker_free(picopass->worker);
Expand Down Expand Up @@ -153,6 +171,13 @@ static const NotificationSequence picopass_sequence_blink_start_cyan = {
NULL,
};

static const NotificationSequence picopass_sequence_blink_start_magenta = {
&message_blink_start_10,
&message_blink_set_color_magenta,
&message_do_not_reset,
NULL,
};

static const NotificationSequence picopass_sequence_blink_stop = {
&message_blink_stop,
NULL,
Expand All @@ -162,6 +187,10 @@ void picopass_blink_start(Picopass* picopass) {
notification_message(picopass->notifications, &picopass_sequence_blink_start_cyan);
}

void picopass_blink_emulate_start(Picopass* picopass) {
notification_message(picopass->notifications, &picopass_sequence_blink_start_magenta);
}

void picopass_blink_stop(Picopass* picopass) {
notification_message(picopass->notifications, &picopass_sequence_blink_stop);
}
Expand Down Expand Up @@ -209,4 +238,4 @@ int32_t picopass_app(void* p) {
picopass_free(picopass);

return 0;
}
}
22 changes: 13 additions & 9 deletions picopass_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,14 @@ static bool picopass_device_save_file(
if(!flipper_format_write_uint32(file, "Facility Code", &fc, 1)) break;
if(!flipper_format_write_uint32(file, "Card Number", &cn, 1)) break;
if(!flipper_format_write_hex(
file, "Credential", pacs->credential, PICOPASS_BLOCK_LEN))
file, "Credential", pacs->credential, RFAL_PICOPASS_BLOCK_LEN))
break;
if(pacs->pin_length > 0) {
if(!flipper_format_write_hex(file, "PIN\t\t", pacs->pin0, PICOPASS_BLOCK_LEN))
if(!flipper_format_write_hex(
file, "PIN\t\t", pacs->pin0, RFAL_PICOPASS_BLOCK_LEN))
break;
if(!flipper_format_write_hex(
file, "PIN(cont.)\t", pacs->pin1, PICOPASS_BLOCK_LEN))
file, "PIN(cont.)\t", pacs->pin1, RFAL_PICOPASS_BLOCK_LEN))
break;
}
}
Expand All @@ -88,7 +89,10 @@ static bool picopass_device_save_file(
for(size_t i = 0; i < app_limit; i++) {
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
file,
furi_string_get_cstr(temp_str),
AA1[i].data,
RFAL_PICOPASS_BLOCK_LEN)) {
block_saved = false;
break;
}
Expand Down Expand Up @@ -162,7 +166,7 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
for(size_t i = 0; i < 6; i++) {
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_read_hex(
file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
file, furi_string_get_cstr(temp_str), AA1[i].data, RFAL_PICOPASS_BLOCK_LEN)) {
block_read = false;
break;
}
Expand All @@ -174,7 +178,7 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
for(size_t i = 6; i < app_limit; i++) {
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_read_hex(
file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
file, furi_string_get_cstr(temp_str), AA1[i].data, RFAL_PICOPASS_BLOCK_LEN)) {
block_read = false;
break;
}
Expand Down Expand Up @@ -338,9 +342,9 @@ ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pa
}
} else if(pacs->encryption == PicopassDeviceEncryptionNone) {
FURI_LOG_D(TAG, "No Encryption");
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);
memcpy(pacs->credential, AA1[7].data, RFAL_PICOPASS_BLOCK_LEN);
memcpy(pacs->pin0, AA1[8].data, RFAL_PICOPASS_BLOCK_LEN);
memcpy(pacs->pin1, AA1[9].data, RFAL_PICOPASS_BLOCK_LEN);
} else if(pacs->encryption == PicopassDeviceEncryptionDES) {
FURI_LOG_D(TAG, "DES Encrypted");
} else {
Expand Down
Loading

0 comments on commit 9137b58

Please sign in to comment.