Skip to content

Commit 4366c8a

Browse files
authored
Merge branch 'dev' into porta/3925-js-views-finale
2 parents 93800e6 + 0d5beed commit 4366c8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+444
-124
lines changed

applications/debug/bt_debug_app/views/bt_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct BtTestParam {
1818
void* context;
1919
};
2020

21-
ARRAY_DEF(BtTestParamArray, BtTestParam, M_POD_OPLIST);
21+
ARRAY_DEF(BtTestParamArray, BtTestParam, M_POD_OPLIST); //-V658
2222

2323
struct BtTest {
2424
View* view;

applications/debug/unit_tests/tests/bt/bt_test.c

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,23 @@
44

55
#include <bt/bt_service/bt_keys_storage.h>
66
#include <storage/storage.h>
7+
#include <toolbox/saved_struct.h>
78

89
#define BT_TEST_KEY_STORAGE_FILE_PATH EXT_PATH("unit_tests/bt_test.keys")
10+
#define BT_TEST_MIGRATION_FILE_PATH EXT_PATH("unit_tests/bt_migration_test.keys")
911
#define BT_TEST_NVM_RAM_BUFF_SIZE (507 * 4) // The same as in ble NVM storage
1012

13+
// Identity root key
14+
static const uint8_t gap_legacy_irk[16] =
15+
{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
16+
// Encryption root key
17+
static const uint8_t gap_legacy_erk[16] =
18+
{0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21};
19+
20+
// Test constants for migration (matching bt_keys_storage.c)
21+
#define BT_KEYS_STORAGE_MAGIC_TEST (0x18)
22+
#define BT_KEYS_STORAGE_VERSION_1_TEST (1)
23+
1124
typedef struct {
1225
Storage* storage;
1326
BtKeysStorage* bt_keys_storage;
@@ -88,6 +101,134 @@ static void bt_test_keys_remove_test_file(void) {
88101
"Can't remove test file");
89102
}
90103

104+
// Helper function to create a version 0 file manually
105+
static bool
106+
bt_test_create_v0_file(const char* file_path, const uint8_t* nvm_data, size_t nvm_size) {
107+
// Version 0 files use saved_struct format with magic 0x18, version 0, containing only BLE pairing data
108+
return saved_struct_save(
109+
file_path,
110+
nvm_data,
111+
nvm_size,
112+
BT_KEYS_STORAGE_MAGIC_TEST,
113+
0); // Version 0
114+
}
115+
116+
// Helper function to verify file format version
117+
static bool bt_test_verify_file_version(const char* file_path, uint32_t expected_version) {
118+
uint8_t magic, version;
119+
size_t size;
120+
121+
if(!saved_struct_get_metadata(file_path, &magic, &version, &size)) {
122+
return false;
123+
}
124+
125+
return (magic == BT_KEYS_STORAGE_MAGIC_TEST && version == expected_version);
126+
}
127+
128+
// Test migration from version 0 to version 1, including root key preservation
129+
static void bt_test_migration_v0_to_v1(void) {
130+
// Create test NVM data
131+
const size_t test_nvm_size = 100;
132+
uint8_t test_nvm_data[test_nvm_size];
133+
for(size_t i = 0; i < test_nvm_size; i++) {
134+
test_nvm_data[i] = (uint8_t)(i & 0xFF);
135+
}
136+
137+
// Create a version 0 file
138+
mu_assert(
139+
bt_test_create_v0_file(BT_TEST_MIGRATION_FILE_PATH, test_nvm_data, test_nvm_size),
140+
"Failed to create version 0 test file");
141+
142+
// Create BT keys storage and load the v0 file (should trigger migration)
143+
BtKeysStorage* migration_storage = bt_keys_storage_alloc(BT_TEST_MIGRATION_FILE_PATH);
144+
uint8_t loaded_buffer[BT_TEST_NVM_RAM_BUFF_SIZE];
145+
memset(loaded_buffer, 0, sizeof(loaded_buffer));
146+
bt_keys_storage_set_ram_params(migration_storage, loaded_buffer, sizeof(loaded_buffer));
147+
148+
// Load should succeed and migrate v0 to v1
149+
mu_assert(bt_keys_storage_load(migration_storage), "Failed to load and migrate v0 file");
150+
151+
// Verify the file is now version 1
152+
mu_assert(
153+
bt_test_verify_file_version(BT_TEST_MIGRATION_FILE_PATH, BT_KEYS_STORAGE_VERSION_1_TEST),
154+
"File was not migrated to version 1");
155+
156+
// Verify the NVM data was preserved during migration
157+
mu_assert(
158+
memcmp(test_nvm_data, loaded_buffer, test_nvm_size) == 0,
159+
"NVM data was corrupted during migration");
160+
161+
// Verify that legacy root keys are used after migration
162+
const GapRootSecurityKeys* migrated_keys = bt_keys_storage_get_root_keys(migration_storage);
163+
mu_assert(
164+
memcmp(migrated_keys->irk, gap_legacy_irk, sizeof(gap_legacy_irk)) == 0,
165+
"IRK not set to legacy after migration");
166+
mu_assert(
167+
memcmp(migrated_keys->erk, gap_legacy_erk, sizeof(gap_legacy_erk)) == 0,
168+
"ERK not set to legacy after migration");
169+
170+
bt_keys_storage_free(migration_storage);
171+
storage_simply_remove(bt_test->storage, BT_TEST_MIGRATION_FILE_PATH);
172+
}
173+
174+
// Test that migration preserves existing pairing data and root keys are not changed on reload
175+
static void bt_test_migration_preserves_pairings_and_keys(void) {
176+
const size_t pairing_data_size = 200;
177+
uint8_t pairing_data[pairing_data_size];
178+
for(size_t i = 0; i < pairing_data_size; i++) {
179+
pairing_data[i] = (uint8_t)((i * 7 + 42) & 0xFF);
180+
}
181+
mu_assert(
182+
bt_test_create_v0_file(BT_TEST_MIGRATION_FILE_PATH, pairing_data, pairing_data_size),
183+
"Failed to create v0 file with pairing data");
184+
185+
GapRootSecurityKeys keys_after_first_load;
186+
for(int iteration = 0; iteration < 2; iteration++) {
187+
BtKeysStorage* storage = bt_keys_storage_alloc(BT_TEST_MIGRATION_FILE_PATH);
188+
uint8_t buffer[BT_TEST_NVM_RAM_BUFF_SIZE];
189+
memset(buffer, 0, sizeof(buffer));
190+
bt_keys_storage_set_ram_params(storage, buffer, sizeof(buffer));
191+
mu_assert(bt_keys_storage_load(storage), "Failed to load on iteration");
192+
mu_assert(
193+
memcmp(pairing_data, buffer, pairing_data_size) == 0,
194+
"Pairing data corrupted on iteration");
195+
const GapRootSecurityKeys* keys = bt_keys_storage_get_root_keys(storage);
196+
if(iteration == 0)
197+
memcpy(&keys_after_first_load, keys, sizeof(GapRootSecurityKeys));
198+
else
199+
mu_assert(
200+
memcmp(&keys_after_first_load, keys, sizeof(GapRootSecurityKeys)) == 0,
201+
"Root keys changed after reload");
202+
bt_keys_storage_free(storage);
203+
}
204+
storage_simply_remove(bt_test->storage, BT_TEST_MIGRATION_FILE_PATH);
205+
}
206+
207+
// Test that delete operation generates new secure keys in v1 and does not match legacy
208+
static void bt_test_delete_generates_new_keys_and_not_legacy(void) {
209+
BtKeysStorage* storage = bt_keys_storage_alloc(BT_TEST_MIGRATION_FILE_PATH);
210+
uint8_t buffer[BT_TEST_NVM_RAM_BUFF_SIZE];
211+
memset(buffer, 0x55, sizeof(buffer));
212+
bt_keys_storage_set_ram_params(storage, buffer, sizeof(buffer));
213+
mu_assert(bt_keys_storage_update(storage, buffer, 100), "Failed to create initial v1 file");
214+
const GapRootSecurityKeys* original_keys = bt_keys_storage_get_root_keys(storage);
215+
uint8_t original_keys_copy[sizeof(GapRootSecurityKeys)];
216+
memcpy(original_keys_copy, original_keys, sizeof(original_keys_copy));
217+
bt_keys_storage_delete(storage);
218+
const GapRootSecurityKeys* new_keys = bt_keys_storage_get_root_keys(storage);
219+
mu_assert(
220+
memcmp(original_keys_copy, new_keys, sizeof(original_keys_copy)) != 0,
221+
"Root keys were not regenerated after delete");
222+
mu_assert(
223+
memcmp(new_keys->irk, gap_legacy_irk, sizeof(gap_legacy_irk)) != 0,
224+
"IRK after delete should not match legacy");
225+
mu_assert(
226+
memcmp(new_keys->erk, gap_legacy_erk, sizeof(gap_legacy_erk)) != 0,
227+
"ERK after delete should not match legacy");
228+
bt_keys_storage_free(storage);
229+
storage_simply_remove(bt_test->storage, BT_TEST_MIGRATION_FILE_PATH);
230+
}
231+
91232
MU_TEST(bt_test_keys_storage_serial_profile) {
92233
furi_check(bt_test);
93234

@@ -96,10 +237,28 @@ MU_TEST(bt_test_keys_storage_serial_profile) {
96237
bt_test_keys_remove_test_file();
97238
}
98239

240+
MU_TEST(bt_test_migration_v0_to_v1_test) {
241+
furi_check(bt_test);
242+
bt_test_migration_v0_to_v1();
243+
}
244+
245+
MU_TEST(bt_test_migration_preserves_pairings_and_keys_test) {
246+
furi_check(bt_test);
247+
bt_test_migration_preserves_pairings_and_keys();
248+
}
249+
250+
MU_TEST(bt_test_delete_generates_new_keys_and_not_legacy_test) {
251+
furi_check(bt_test);
252+
bt_test_delete_generates_new_keys_and_not_legacy();
253+
}
254+
99255
MU_TEST_SUITE(test_bt) {
100256
bt_test_alloc();
101257

102258
MU_RUN_TEST(bt_test_keys_storage_serial_profile);
259+
MU_RUN_TEST(bt_test_migration_v0_to_v1_test);
260+
MU_RUN_TEST(bt_test_migration_preserves_pairings_and_keys_test);
261+
MU_RUN_TEST(bt_test_delete_generates_new_keys_and_not_legacy_test);
103262

104263
bt_test_free();
105264
}

applications/main/infrared/infrared_brute_force.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "infrared_signal.h"
99

10-
ARRAY_DEF(SignalPositionArray, size_t, M_DEFAULT_OPLIST);
10+
ARRAY_DEF(SignalPositionArray, size_t, M_DEFAULT_OPLIST); //-V658
1111

1212
typedef struct {
1313
size_t index;

applications/main/nfc/helpers/mfkey32_logger.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ typedef struct {
2121
uint32_t ar1;
2222
} Mfkey32LoggerParams;
2323

24-
ARRAY_DEF(Mfkey32LoggerParams, Mfkey32LoggerParams, M_POD_OPLIST);
24+
ARRAY_DEF(Mfkey32LoggerParams, Mfkey32LoggerParams, M_POD_OPLIST); //-V658
2525

2626
struct Mfkey32Logger {
2727
uint32_t cuid;

applications/main/nfc/helpers/nfc_supported_cards.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ typedef struct {
2929
NfcSupportedCardsPluginFeature feature;
3030
} NfcSupportedCardsPluginCache;
3131

32-
ARRAY_DEF(NfcSupportedCardsPluginCache, NfcSupportedCardsPluginCache, M_POD_OPLIST);
32+
ARRAY_DEF(NfcSupportedCardsPluginCache, NfcSupportedCardsPluginCache, M_POD_OPLIST); //-V658
3333

3434
typedef enum {
3535
NfcSupportedCardsLoadStateIdle,

applications/main/onewire/onewire_cli.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static void onewire_cli_search(PipeSide* pipe) {
2525
onewire_host_start(onewire);
2626
power_enable_otg(power, true);
2727

28-
while(!done) {
28+
while(!done) { //-V1044
2929
if(onewire_host_search(onewire, address, OneWireHostSearchModeNormal) != 1) {
3030
printf("Search finished\r\n");
3131
onewire_host_reset_search(onewire);

applications/main/subghz/helpers/subghz_frequency_analyzer_log_item_array.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ TUPLE_DEF2( //-V1048
3535
M_DEFAULT_OPLIST)
3636

3737
/* Define the array, register the oplist and define further algorithms on it */
38-
ARRAY_DEF(SubGhzFrequencyAnalyzerLogItemArray, SubGhzFrequencyAnalyzerLogItem_t) //-V779
38+
ARRAY_DEF(SubGhzFrequencyAnalyzerLogItemArray, SubGhzFrequencyAnalyzerLogItem_t) //-V779 //-V658
3939
#define M_OPL_SubGhzFrequencyAnalyzerLogItemArray_t() \
4040
ARRAY_OPLIST(SubGhzFrequencyAnalyzerLogItemArray, M_OPL_SubGhzFrequencyAnalyzerLogItem_t())
4141
ALGO_DEF(SubGhzFrequencyAnalyzerLogItemArray, SubGhzFrequencyAnalyzerLogItemArray_t)

applications/main/subghz/subghz_history.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ typedef struct {
1616
SubGhzRadioPreset* preset;
1717
} SubGhzHistoryItem;
1818

19-
ARRAY_DEF(SubGhzHistoryItemArray, SubGhzHistoryItem, M_POD_OPLIST)
19+
ARRAY_DEF(SubGhzHistoryItemArray, SubGhzHistoryItem, M_POD_OPLIST) //-V658
2020

2121
#define M_OPL_SubGhzHistoryItemArray_t() ARRAY_OPLIST(SubGhzHistoryItemArray, M_POD_OPLIST)
2222

applications/main/subghz/views/receiver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ typedef struct {
1818
uint8_t type;
1919
} SubGhzReceiverMenuItem;
2020

21-
ARRAY_DEF(SubGhzReceiverMenuItemArray, SubGhzReceiverMenuItem, M_POD_OPLIST)
21+
ARRAY_DEF(SubGhzReceiverMenuItemArray, SubGhzReceiverMenuItem, M_POD_OPLIST) //-V658
2222

2323
#define M_OPL_SubGhzReceiverMenuItemArray_t() \
2424
ARRAY_OPLIST(SubGhzReceiverMenuItemArray, M_POD_OPLIST)

applications/services/bt/bt_service/bt.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ static void bt_change_profile(Bt* bt, BtMessage* message) {
403403
bt->current_profile = furi_hal_bt_change_app(
404404
message->data.profile.template,
405405
message->data.profile.params,
406+
bt_keys_storage_get_root_keys(bt->keys_storage),
406407
bt_on_gap_event_callback,
407408
bt);
408409
if(bt->current_profile) {
@@ -458,16 +459,19 @@ static void bt_load_keys(Bt* bt) {
458459
bt_keys_storage_load(bt->keys_storage);
459460

460461
bt->current_profile = NULL;
461-
462462
} else {
463463
FURI_LOG_I(TAG, "Keys unchanged");
464464
}
465465
}
466466

467467
static void bt_start_application(Bt* bt) {
468468
if(!bt->current_profile) {
469-
bt->current_profile =
470-
furi_hal_bt_change_app(ble_profile_serial, NULL, bt_on_gap_event_callback, bt);
469+
bt->current_profile = furi_hal_bt_change_app(
470+
ble_profile_serial,
471+
NULL,
472+
bt_keys_storage_get_root_keys(bt->keys_storage),
473+
bt_on_gap_event_callback,
474+
bt);
471475

472476
if(!bt->current_profile) {
473477
FURI_LOG_E(TAG, "BLE App start failed");

0 commit comments

Comments
 (0)