Update apps

This commit is contained in:
Willy-JL
2023-08-30 18:59:32 +02:00
parent 160ab755a2
commit ee37769ee2
308 changed files with 2314 additions and 801 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

View File

@@ -192,10 +192,46 @@ bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, u
TAG_BYTES) == 0);
#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
// increase internal counter
// update replay dict and increase internal counter
if(ret) {
ESubGhzChatReplayDict_set_at(ctx->replay_dict, ctx->run_id, ctx->counter);
ctx->counter++;
}
return ret;
}
size_t crypto_ctx_dump_replay_dict(
ESubGhzChatCryptoCtx* ctx,
CryptoCtxReplayDictWriter writer,
void* writer_ctx) {
size_t ret = 0;
ESubGhzChatReplayDict_it_t i;
for(ESubGhzChatReplayDict_it(i, ctx->replay_dict); !ESubGhzChatReplayDict_end_p(i);
ESubGhzChatReplayDict_next(i), ret++) {
ESubGhzChatReplayDict_itref_t* ref = ESubGhzChatReplayDict_ref(i);
if(!writer(ref->key, ref->value, writer_ctx)) {
break;
}
}
return ret;
}
size_t crypto_ctx_read_replay_dict(
ESubGhzChatCryptoCtx* ctx,
CryptoCtxReplayDictReader reader,
void* reader_ctx) {
size_t ret = 0;
uint64_t run_id;
uint32_t counter;
while(reader(&run_id, &counter, reader_ctx)) {
ESubGhzChatReplayDict_set_at(ctx->replay_dict, run_id, counter);
ret++;
}
return ret;
}

View File

@@ -34,6 +34,18 @@ void crypto_ctx_get_key(ESubGhzChatCryptoCtx* ctx, uint8_t* key);
bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out);
bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out);
typedef bool (*CryptoCtxReplayDictWriter)(uint64_t run_id, uint32_t counter, void* context);
typedef bool (*CryptoCtxReplayDictReader)(uint64_t* run_id, uint32_t* counter, void* context);
size_t crypto_ctx_dump_replay_dict(
ESubGhzChatCryptoCtx* ctx,
CryptoCtxReplayDictWriter writer,
void* writer_ctx);
size_t crypto_ctx_read_replay_dict(
ESubGhzChatCryptoCtx* ctx,
CryptoCtxReplayDictReader reader,
void* reader_ctx);
#ifdef __cplusplus
}
#endif

View File

@@ -1,14 +1,13 @@
#include <furi_hal.h>
#include <gui/elements.h>
#include <gui/gui.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
#include "helpers/radio_device_loader.h"
#include "esubghz_chat_i.h"
#define CHAT_LEAVE_DELAY 10
#define TICK_INTERVAL 50
#define MESSAGE_COMPLETION_TIMEOUT 500
#define TIMEOUT_BETWEEN_MESSAGES 500
#define KBD_UNLOCK_CNT 3
#define KBD_UNLOCK_TIMEOUT 1000
@@ -125,15 +124,23 @@ void tx_msg_input(ESubGhzChatState* state) {
subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer, tx_size);
}
/* Displays whether or not encryption has been enabled in the text box. Also
* clears the text input buffer to remove the password and starts the Sub-GHz
* worker. After starting the worker a join message is transmitted. */
/* Displays information on frequency, encryption and radio type in the text
* box. Also clears the text input buffer to remove the password and starts the
* Sub-GHz worker. After starting the worker a join message is transmitted. */
void enter_chat(ESubGhzChatState* state) {
furi_string_cat_printf(state->chat_box_store, "Frequency: %lu", state->frequency);
furi_string_cat_printf(
state->chat_box_store, "\nEncrypted: %s", (state->encrypted ? "yes" : "no"));
subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device, state->frequency);
if(strcmp(state->subghz_device->name, "cc1101_ext") == 0) {
furi_string_cat_printf(state->chat_box_store, "\nRadio: External");
} else {
furi_string_cat_printf(state->chat_box_store, "\nRadio: Internal");
}
/* concatenate the name prefix and join message */
furi_string_set(state->msg_input, state->name_prefix);
furi_string_cat_str(state->msg_input, " joined chat.");
@@ -523,6 +530,9 @@ int32_t esubghz_chat(void) {
goto err_alloc_crypto;
}
/* set the default frequency */
state->frequency = DEFAULT_FREQ;
/* set the have_read callback of the Sub-GHz worker */
subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker, have_read_cb, state);
@@ -531,7 +541,12 @@ int32_t esubghz_chat(void) {
/* init internal device */
subghz_devices_init();
state->subghz_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
state->subghz_device =
radio_device_loader_set(state->subghz_device, SubGhzRadioDeviceTypeExternalCC1101);
subghz_devices_reset(state->subghz_device);
subghz_devices_idle(state->subghz_device);
/* set chat name prefix */
furi_string_printf(state->name_prefix, "%s", furi_hal_version_get_name_ptr());
@@ -582,8 +597,8 @@ int32_t esubghz_chat(void) {
Gui* gui = furi_record_open(RECORD_GUI);
view_dispatcher_attach_to_gui(state->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
/* switch to the frequency input scene */
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
/* switch to the key menu scene */
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyMenu);
/* run the view dispatcher, this call only returns when we close the
* application */
@@ -627,6 +642,8 @@ int32_t esubghz_chat(void) {
crypto_explicit_bzero(state->nfc_dev_data, sizeof(NfcDeviceData));
/* deinit devices */
radio_device_loader_end(state->subghz_device);
subghz_devices_deinit();
/* exit suppress charge mode */

View File

@@ -18,8 +18,8 @@
#include "crypto_wrapper.h"
#include "scenes/esubghz_chat_scene.h"
#include <assets_icons.h>
#include "esubghz_chat_icons.h"
#include <assets_icons.h>
#define APPLICATION_NAME "ESubGhzChat"

View File

@@ -0,0 +1,25 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define NFC_MAX_BYTES 256
#define NFC_CONFIG_PAGES 4
struct FreqNfcEntry {
uint32_t frequency;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
} __attribute__((packed));
struct ReplayDictNfcEntry {
uint64_t run_id;
uint32_t counter;
uint32_t unused;
} __attribute__((packed));
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,65 @@
#include "radio_device_loader.h"
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
static void radio_device_loader_power_on() {
uint8_t attempts = 0;
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
furi_hal_power_enable_otg();
//CC1101 power-up time
furi_delay_ms(10);
}
}
static void radio_device_loader_power_off() {
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
}
bool radio_device_loader_is_connect_external(const char* name) {
bool is_connect = false;
bool is_otg_enabled = furi_hal_power_is_otg_enabled();
if(!is_otg_enabled) {
radio_device_loader_power_on();
}
const SubGhzDevice* device = subghz_devices_get_by_name(name);
if(device) {
is_connect = subghz_devices_is_connect(device);
}
if(!is_otg_enabled) {
radio_device_loader_power_off();
}
return is_connect;
}
const SubGhzDevice* radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type) {
const SubGhzDevice* radio_device;
if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
radio_device_loader_power_on();
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
subghz_devices_begin(radio_device);
} else if(current_radio_device == NULL) {
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
} else {
radio_device_loader_end(current_radio_device);
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
}
return radio_device;
}
void radio_device_loader_end(const SubGhzDevice* radio_device) {
furi_assert(radio_device);
radio_device_loader_power_off();
// Code below is not used (and will cause crash) since its called from tx_rx worker end!
//if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
// subghz_devices_end(radio_device);
//}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <lib/subghz/devices/devices.h>
/** SubGhzRadioDeviceType */
typedef enum {
SubGhzRadioDeviceTypeInternal,
SubGhzRadioDeviceTypeExternalCC1101,
} SubGhzRadioDeviceType;
const SubGhzDevice* radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type);
void radio_device_loader_end(const SubGhzDevice* radio_device);

View File

@@ -1,12 +1,11 @@
#include "../esubghz_chat_i.h"
/* Sends FreqEntered event to scene manager and displays the frequency in the
* text box. */
/* Sends FreqEntered event to scene manager and enters the chat. */
static void freq_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
furi_string_cat_printf(state->chat_box_store, "Frequency: %lu", state->frequency);
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_FreqEntered);
}
@@ -49,7 +48,7 @@ void scene_on_enter_freq_input(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu", (uint32_t)DEFAULT_FREQ);
snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu", state->frequency);
text_input_reset(state->text_input);
text_input_set_result_callback(
state->text_input,
@@ -76,9 +75,9 @@ bool scene_on_event_freq_input(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
/* switch to password input scene */
/* switch to message input scene */
case ESubGhzChatEvent_FreqEntered:
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyMenu);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
consumed = true;
break;
}

View File

@@ -1,7 +1,7 @@
#include "../esubghz_chat_i.h"
/* Sets the entered bytes as the key, enters the chat and sends a HexKeyEntered
* event to the scene manager. */
/* Sets the entered bytes as the key and sends a HexKeyEntered event to the
* scene manager. */
static void hex_key_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
@@ -20,8 +20,6 @@ static void hex_key_input_cb(void* context) {
state->encrypted = true;
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_HexKeyEntered);
}
@@ -55,9 +53,9 @@ bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
/* switch to message input scene */
/* switch to frequency input scene */
case ESubGhzChatEvent_HexKeyEntered:
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;
}

View File

@@ -17,7 +17,6 @@ static void key_menu_cb(void* context, uint32_t index) {
switch(index) {
case ESubGhzChatKeyMenuItems_NoEncryption:
state->encrypted = false;
enter_chat(state);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyMenuNoEncryption);
@@ -49,7 +48,6 @@ static void key_menu_cb(void* context, uint32_t index) {
/* set encrypted flag and enter the chat */
state->encrypted = true;
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuGenKey);
break;
@@ -73,33 +71,37 @@ void scene_on_enter_key_menu(void* context) {
menu_reset(state->menu);
/* clear the crypto CTX in case we got back from password or hex key
* input */
crypto_ctx_clear(state->crypto_ctx);
menu_add_item(
state->menu,
"No encryption",
&I_chat_10px,
&I_chat_14px,
ESubGhzChatKeyMenuItems_NoEncryption,
key_menu_cb,
state);
menu_add_item(
state->menu,
"Password",
&I_keyboard_10px,
&I_keyboard_14px,
ESubGhzChatKeyMenuItems_Password,
key_menu_cb,
state);
menu_add_item(
state->menu, "Hex Key", &I_hex_10px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
state->menu, "Hex Key", &I_hex_14px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
menu_add_item(
state->menu,
"Generate Key",
&I_u2f_10px,
&I_u2f_14px,
ESubGhzChatKeyMenuItems_GenKey,
key_menu_cb,
state);
menu_add_item(
state->menu,
"Read Key from NFC",
&I_Nfc_10px,
&I_Nfc_14px,
ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
key_menu_cb,
state);
@@ -119,10 +121,10 @@ bool scene_on_event_key_menu(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
/* switch to message input scene */
/* switch to frequency input scene */
case ESubGhzChatEvent_KeyMenuNoEncryption:
case ESubGhzChatEvent_KeyMenuGenKey:
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;

View File

@@ -1,4 +1,5 @@
#include "../esubghz_chat_i.h"
#include "../helpers/nfc_helpers.h"
typedef enum {
KeyReadPopupState_Idle,
@@ -28,18 +29,46 @@ static void key_read_popup_timeout_cb(void* context) {
if(cur_state == KeyReadPopupState_Fail) {
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupFailed);
/* done displaying our success, enter chat */
/* done displaying our success */
} else if(cur_state == KeyReadPopupState_Success) {
enter_chat(state);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupSucceeded);
}
}
struct ReplayDictNfcReaderContext {
uint8_t* cur;
uint8_t* max;
};
static bool replay_dict_nfc_reader(uint64_t* run_id, uint32_t* counter, void* context) {
struct ReplayDictNfcReaderContext* ctx = (struct ReplayDictNfcReaderContext*)context;
if(ctx->cur + sizeof(struct ReplayDictNfcEntry) > ctx->max) {
return false;
}
struct ReplayDictNfcEntry* entry = (struct ReplayDictNfcEntry*)ctx->cur;
*run_id = entry->run_id;
*counter = __ntohl(entry->counter);
ctx->cur += sizeof(struct ReplayDictNfcEntry);
return true;
}
static bool key_read_popup_handle_key_read(ESubGhzChatState* state) {
NfcDeviceData* dev_data = state->nfc_dev_data;
if(dev_data->mf_ul_data.data_read < KEY_BITS / 8) {
/* check for config pages */
if(dev_data->mf_ul_data.data_read < NFC_CONFIG_PAGES * 4) {
return false;
}
size_t data_read = dev_data->mf_ul_data.data_read - (NFC_CONFIG_PAGES * 4);
/* check if key was transmitted */
if(data_read < KEY_BITS / 8) {
return false;
}
@@ -55,6 +84,21 @@ static bool key_read_popup_handle_key_read(ESubGhzChatState* state) {
return false;
}
/* read the frequency */
if(data_read >= (KEY_BITS / 8) + sizeof(struct FreqNfcEntry)) {
struct FreqNfcEntry* freq_entry =
(struct FreqNfcEntry*)(dev_data->mf_ul_data.data + (KEY_BITS / 8));
state->frequency = __ntohl(freq_entry->frequency);
}
/* read the replay dict */
struct ReplayDictNfcReaderContext rd_ctx = {
.cur = dev_data->mf_ul_data.data + (KEY_BITS / 8) + sizeof(struct FreqNfcEntry),
.max =
dev_data->mf_ul_data.data + (data_read < NFC_MAX_BYTES ? data_read : NFC_MAX_BYTES)};
crypto_ctx_read_replay_dict(state->crypto_ctx, replay_dict_nfc_reader, &rd_ctx);
/* set encrypted flag */
state->encrypted = true;
@@ -183,9 +227,9 @@ bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event) {
consumed = true;
break;
/* success, go to chat input */
/* success, go to frequency input */
case ESubGhzChatEvent_KeyReadPopupSucceeded:
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;

View File

@@ -1,4 +1,25 @@
#include "../esubghz_chat_i.h"
#include "../helpers/nfc_helpers.h"
struct ReplayDictNfcWriterContext {
uint8_t* cur;
uint8_t* max;
};
static bool replay_dict_nfc_writer(uint64_t run_id, uint32_t counter, void* context) {
struct ReplayDictNfcWriterContext* ctx = (struct ReplayDictNfcWriterContext*)context;
struct ReplayDictNfcEntry entry = {.run_id = run_id, .counter = __htonl(counter), .unused = 0};
if(ctx->cur + sizeof(entry) > ctx->max) {
return false;
}
memcpy(ctx->cur, &entry, sizeof(entry));
ctx->cur += sizeof(entry);
return true;
}
static void prepare_nfc_dev_data(ESubGhzChatState* state) {
NfcDeviceData* dev_data = state->nfc_dev_data;
@@ -20,9 +41,32 @@ static void prepare_nfc_dev_data(ESubGhzChatState* state) {
dev_data->mf_ul_data.version.storage_size = 0x11;
dev_data->mf_ul_data.version.protocol_type = 0x03;
/* Add 16 to the size for config pages */
dev_data->mf_ul_data.data_size = (KEY_BITS / 8) + 16;
size_t data_written = 0;
/* write key */
crypto_ctx_get_key(state->crypto_ctx, dev_data->mf_ul_data.data);
data_written += (KEY_BITS / 8);
/* write frequency */
struct FreqNfcEntry* freq_entry =
(struct FreqNfcEntry*)(dev_data->mf_ul_data.data + data_written);
freq_entry->frequency = __htonl(state->frequency);
freq_entry->unused1 = 0;
freq_entry->unused2 = 0;
freq_entry->unused3 = 0;
data_written += sizeof(struct FreqNfcEntry);
/* write the replay dict */
struct ReplayDictNfcWriterContext wr_ctx = {
.cur = dev_data->mf_ul_data.data + data_written,
.max = dev_data->mf_ul_data.data + NFC_MAX_BYTES};
size_t n_entries =
crypto_ctx_dump_replay_dict(state->crypto_ctx, replay_dict_nfc_writer, &wr_ctx);
data_written += n_entries * sizeof(struct ReplayDictNfcEntry);
/* calculate size of data, add 16 for config pages */
dev_data->mf_ul_data.data_size = data_written + (NFC_CONFIG_PAGES * 4);
}
/* Prepares the key share popup scene. */

View File

@@ -1,14 +1,12 @@
#include "../esubghz_chat_i.h"
/* Sends PassEntered event to scene manager and enters the chat. */
/* Sends PassEntered event to scene manager. */
static void pass_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store));
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_PassEntered);
}
@@ -83,9 +81,9 @@ bool scene_on_event_pass_input(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
/* switch to message input scene */
/* switch to frequency input scene */
case ESubGhzChatEvent_PassEntered:
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;
}