diff --git a/.vscode/example/settings.json b/.vscode/example/settings.json index efa08157b..819917146 100644 --- a/.vscode/example/settings.json +++ b/.vscode/example/settings.json @@ -6,15 +6,9 @@ "cortex-debug.enableTelemetry": false, "cortex-debug.variableUseNaturalFormat": true, "cortex-debug.showRTOS": true, - "cortex-debug.armToolchainPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/bin", - "cortex-debug.armToolchainPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin", - "cortex-debug.armToolchainPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin", - "cortex-debug.openocdPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/openocd/bin/openocd.exe", - "cortex-debug.openocdPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/openocd/bin/openocd", - "cortex-debug.openocdPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/openocd/bin/openocd", - "cortex-debug.gdbPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/bin/arm-none-eabi-gdb-py.bat", - "cortex-debug.gdbPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py", - "cortex-debug.gdbPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gdb-py", + "cortex-debug.armToolchainPath": "${workspaceFolder}/toolchain/current/bin", + "cortex-debug.openocdPath": "${workspaceFolder}/toolchain/current/bin/openocd", + "cortex-debug.gdbPath": "${workspaceFolder}/toolchain/current/bin/arm-none-eabi-gdb-py3", "editor.formatOnSave": true, "files.associations": { "*.scons": "python", diff --git a/applications/debug/unit_tests/lfrfid/bit_lib_test.c b/applications/debug/unit_tests/bit_lib/bit_lib_test.c similarity index 67% rename from applications/debug/unit_tests/lfrfid/bit_lib_test.c rename to applications/debug/unit_tests/bit_lib/bit_lib_test.c index dcb69de7f..42b494413 100644 --- a/applications/debug/unit_tests/lfrfid/bit_lib_test.c +++ b/applications/debug/unit_tests/bit_lib/bit_lib_test.c @@ -1,6 +1,6 @@ #include #include "../minunit.h" -#include +#include MU_TEST(test_bit_lib_increment_index) { uint32_t index = 0; @@ -218,6 +218,178 @@ MU_TEST(test_bit_lib_get_bits_32) { mu_assert_int_eq(0b00001001101100011000110001100010, bit_lib_get_bits_32(value, 0, 32)); } +MU_TEST(test_bit_lib_get_bits_64) { + uint8_t value[8] = { + 0b00001001, + 0b10110001, + 0b10001100, + 0b01100010, + 0b00001001, + 0b10110001, + 0b10001100, + 0b01100010}; + mu_assert_int_eq(0b0, bit_lib_get_bits_64(value, 0, 1)); + mu_assert_int_eq(0b00, bit_lib_get_bits_64(value, 0, 2)); + mu_assert_int_eq(0b000, bit_lib_get_bits_64(value, 0, 3)); + mu_assert_int_eq(0b0000, bit_lib_get_bits_64(value, 0, 4)); + mu_assert_int_eq(0b00001, bit_lib_get_bits_64(value, 0, 5)); + mu_assert_int_eq(0b000010, bit_lib_get_bits_64(value, 0, 6)); + mu_assert_int_eq(0b0000100, bit_lib_get_bits_64(value, 0, 7)); + mu_assert_int_eq(0b00001001, bit_lib_get_bits_64(value, 0, 8)); + mu_assert_int_eq(0b000010011, bit_lib_get_bits_64(value, 0, 9)); + mu_assert_int_eq(0b0000100110, bit_lib_get_bits_64(value, 0, 10)); + mu_assert_int_eq(0b00001001101, bit_lib_get_bits_64(value, 0, 11)); + mu_assert_int_eq(0b000010011011, bit_lib_get_bits_64(value, 0, 12)); + mu_assert_int_eq(0b0000100110110, bit_lib_get_bits_64(value, 0, 13)); + mu_assert_int_eq(0b00001001101100, bit_lib_get_bits_64(value, 0, 14)); + mu_assert_int_eq(0b000010011011000, bit_lib_get_bits_64(value, 0, 15)); + mu_assert_int_eq(0b0000100110110001, bit_lib_get_bits_64(value, 0, 16)); + mu_assert_int_eq(0b00001001101100011, bit_lib_get_bits_64(value, 0, 17)); + mu_assert_int_eq(0b000010011011000110, bit_lib_get_bits_64(value, 0, 18)); + mu_assert_int_eq(0b0000100110110001100, bit_lib_get_bits_64(value, 0, 19)); + mu_assert_int_eq(0b00001001101100011000, bit_lib_get_bits_64(value, 0, 20)); + mu_assert_int_eq(0b000010011011000110001, bit_lib_get_bits_64(value, 0, 21)); + mu_assert_int_eq(0b0000100110110001100011, bit_lib_get_bits_64(value, 0, 22)); + mu_assert_int_eq(0b00001001101100011000110, bit_lib_get_bits_64(value, 0, 23)); + mu_assert_int_eq(0b000010011011000110001100, bit_lib_get_bits_64(value, 0, 24)); + mu_assert_int_eq(0b0000100110110001100011000, bit_lib_get_bits_64(value, 0, 25)); + mu_assert_int_eq(0b00001001101100011000110001, bit_lib_get_bits_64(value, 0, 26)); + mu_assert_int_eq(0b000010011011000110001100011, bit_lib_get_bits_64(value, 0, 27)); + mu_assert_int_eq(0b0000100110110001100011000110, bit_lib_get_bits_64(value, 0, 28)); + mu_assert_int_eq(0b00001001101100011000110001100, bit_lib_get_bits_64(value, 0, 29)); + mu_assert_int_eq(0b000010011011000110001100011000, bit_lib_get_bits_64(value, 0, 30)); + mu_assert_int_eq(0b0000100110110001100011000110001, bit_lib_get_bits_64(value, 0, 31)); + mu_assert_int_eq(0b00001001101100011000110001100010, bit_lib_get_bits_64(value, 0, 32)); + + uint64_t res = bit_lib_get_bits_64(value, 0, 33); + uint64_t expected = 0b000010011011000110001100011000100; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 34); + expected = 0b0000100110110001100011000110001000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 35); + expected = 0b00001001101100011000110001100010000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 36); + expected = 0b000010011011000110001100011000100000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 37); + expected = 0b0000100110110001100011000110001000001; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 38); + expected = 0b00001001101100011000110001100010000010; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 39); + expected = 0b000010011011000110001100011000100000100; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 40); + expected = 0b0000100110110001100011000110001000001001; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 41); + expected = 0b00001001101100011000110001100010000010011; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 42); + expected = 0b000010011011000110001100011000100000100110; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 43); + expected = 0b0000100110110001100011000110001000001001101; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 44); + expected = 0b00001001101100011000110001100010000010011011; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 45); + expected = 0b000010011011000110001100011000100000100110110; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 46); + expected = 0b0000100110110001100011000110001000001001101100; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 47); + expected = 0b00001001101100011000110001100010000010011011000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 48); + expected = 0b000010011011000110001100011000100000100110110001; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 49); + expected = 0b0000100110110001100011000110001000001001101100011; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 50); + expected = 0b00001001101100011000110001100010000010011011000110; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 51); + expected = 0b000010011011000110001100011000100000100110110001100; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 52); + expected = 0b0000100110110001100011000110001000001001101100011000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 53); + expected = 0b00001001101100011000110001100010000010011011000110001; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 54); + expected = 0b000010011011000110001100011000100000100110110001100011; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 55); + expected = 0b0000100110110001100011000110001000001001101100011000110; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 56); + expected = 0b00001001101100011000110001100010000010011011000110001100; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 57); + expected = 0b000010011011000110001100011000100000100110110001100011000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 58); + expected = 0b0000100110110001100011000110001000001001101100011000110001; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 59); + expected = 0b00001001101100011000110001100010000010011011000110001100011; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 60); + expected = 0b000010011011000110001100011000100000100110110001100011000110; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 61); + expected = 0b0000100110110001100011000110001000001001101100011000110001100; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 62); + expected = 0b00001001101100011000110001100010000010011011000110001100011000; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 63); + expected = 0b000010011011000110001100011000100000100110110001100011000110001; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + + res = bit_lib_get_bits_64(value, 0, 64); + expected = 0b0000100110110001100011000110001000001001101100011000110001100010; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); +} + MU_TEST(test_bit_lib_test_parity_u32) { // test even parity mu_assert_int_eq(bit_lib_test_parity_32(0b00000000, BitLibParityEven), 0); @@ -447,6 +619,95 @@ MU_TEST(test_bit_lib_crc16) { mu_assert_int_eq(0x31C3, bit_lib_crc16(data, data_size, 0x1021, 0x0000, false, false, 0x0000)); } +MU_TEST(test_bit_lib_num_to_bytes_be) { + uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + uint8_t dest[8]; + + bit_lib_num_to_bytes_be(0x01, 1, dest); + mu_assert_mem_eq(src, dest, sizeof(src[0])); + + bit_lib_num_to_bytes_be(0x0123456789ABCDEF, 4, dest); + mu_assert_mem_eq(src + 4, dest, 4 * sizeof(src[0])); + + bit_lib_num_to_bytes_be(0x0123456789ABCDEF, 8, dest); + mu_assert_mem_eq(src, dest, 8 * sizeof(src[0])); + + bit_lib_num_to_bytes_be(bit_lib_bytes_to_num_be(src, 8), 8, dest); + mu_assert_mem_eq(src, dest, 8 * sizeof(src[0])); +} + +MU_TEST(test_bit_lib_num_to_bytes_le) { + uint8_t dest[8]; + + uint8_t n2b_le_expected_1[] = {0x01}; + bit_lib_num_to_bytes_le(0x01, 1, dest); + mu_assert_mem_eq(n2b_le_expected_1, dest, sizeof(n2b_le_expected_1[0])); + + uint8_t n2b_le_expected_2[] = {0xEF, 0xCD, 0xAB, 0x89}; + bit_lib_num_to_bytes_le(0x0123456789ABCDEF, 4, dest); + mu_assert_mem_eq(n2b_le_expected_2, dest, 4 * sizeof(n2b_le_expected_2[0])); + + uint8_t n2b_le_expected_3[] = {0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01}; + bit_lib_num_to_bytes_le(0x0123456789ABCDEF, 8, dest); + mu_assert_mem_eq(n2b_le_expected_3, dest, 8 * sizeof(n2b_le_expected_3[0])); + + bit_lib_num_to_bytes_le(bit_lib_bytes_to_num_le(n2b_le_expected_3, 8), 8, dest); + mu_assert_mem_eq(n2b_le_expected_3, dest, 8 * sizeof(n2b_le_expected_3[0])); +} + +MU_TEST(test_bit_lib_bytes_to_num_be) { + uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + uint64_t res; + + res = bit_lib_bytes_to_num_be(src, 1); + mu_assert_int_eq(0x01, res); + + res = bit_lib_bytes_to_num_be(src, 4); + mu_assert_int_eq(0x01234567, res); + + res = bit_lib_bytes_to_num_be(src, 8); + uint64_t expected = 0x0123456789ABCDEF; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); +} + +MU_TEST(test_bit_lib_bytes_to_num_le) { + uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + uint64_t res; + + res = bit_lib_bytes_to_num_le(src, 1); + mu_assert_int_eq(0x01, res); + + res = bit_lib_bytes_to_num_le(src, 4); + mu_assert_int_eq(0x67452301, res); + + res = bit_lib_bytes_to_num_le(src, 8); + uint64_t expected = 0xEFCDAB8967452301; + mu_assert_mem_eq(&expected, &res, sizeof(expected)); +} + +MU_TEST(test_bit_lib_bytes_to_num_bcd) { + uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + uint64_t res; + bool is_bcd_res; + + res = bit_lib_bytes_to_num_bcd(src, 1, &is_bcd_res); + mu_assert_int_eq(01, res); + mu_assert_int_eq(true, is_bcd_res); + + res = bit_lib_bytes_to_num_bcd(src, 4, &is_bcd_res); + mu_assert_int_eq(1234567, res); + mu_assert_int_eq(true, is_bcd_res); + + uint8_t digits[5] = {0x98, 0x76, 0x54, 0x32, 0x10}; + uint64_t expected = 9876543210; + res = bit_lib_bytes_to_num_bcd(digits, 5, &is_bcd_res); + mu_assert_mem_eq(&expected, &res, sizeof(expected)); + mu_assert_int_eq(true, is_bcd_res); + + res = bit_lib_bytes_to_num_bcd(src, 8, &is_bcd_res); + mu_assert_int_eq(false, is_bcd_res); +} + MU_TEST_SUITE(test_bit_lib) { MU_RUN_TEST(test_bit_lib_increment_index); MU_RUN_TEST(test_bit_lib_is_set); @@ -457,6 +718,7 @@ MU_TEST_SUITE(test_bit_lib) { MU_RUN_TEST(test_bit_lib_get_bits); MU_RUN_TEST(test_bit_lib_get_bits_16); MU_RUN_TEST(test_bit_lib_get_bits_32); + MU_RUN_TEST(test_bit_lib_get_bits_64); MU_RUN_TEST(test_bit_lib_test_parity_u32); MU_RUN_TEST(test_bit_lib_test_parity); MU_RUN_TEST(test_bit_lib_remove_bit_every_nth); @@ -465,6 +727,11 @@ MU_TEST_SUITE(test_bit_lib) { MU_RUN_TEST(test_bit_lib_get_bit_count); MU_RUN_TEST(test_bit_lib_reverse_16_fast); MU_RUN_TEST(test_bit_lib_crc16); + MU_RUN_TEST(test_bit_lib_num_to_bytes_be); + MU_RUN_TEST(test_bit_lib_num_to_bytes_le); + MU_RUN_TEST(test_bit_lib_bytes_to_num_be); + MU_RUN_TEST(test_bit_lib_bytes_to_num_le); + MU_RUN_TEST(test_bit_lib_bytes_to_num_bcd); } int run_minunit_test_bit_lib() { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c index 71b6b7aee..b7abfd2fe 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c @@ -1,4 +1,5 @@ #include "../lfrfid_i.h" +#include #include "tools/t5577.h" #define TAG "Clear T5577" @@ -21,8 +22,7 @@ static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) { }; // Clear custom password - uint32_t custom_pass = (app->password[0] << 24) | (app->password[1] << 16) | - (app->password[2] << 8) | (app->password[3]); + uint32_t custom_pass = bit_lib_bytes_to_num_be(app->password, 4); snprintf(curr_buf, sizeof(curr_buf), "Custom password"); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_enter_password.c b/applications/main/lfrfid/scenes/lfrfid_scene_enter_password.c index 4809ef669..d387122eb 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_enter_password.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_enter_password.c @@ -1,4 +1,5 @@ #include "../lfrfid_i.h" +#include "bit_lib.h" #include "gui/scene_manager.h" int next_scene; @@ -16,7 +17,7 @@ void lfrfid_scene_enter_password_on_enter(void* context) { const uint32_t* password_list = lfrfid_get_t5577_default_passwords(&password_list_size); uint32_t pass = password_list[furi_get_tick() % password_list_size]; - for(uint8_t i = 0; i < 4; i++) app->password[4 - (i + 1)] = (pass >> (8 * i)) & 0xFF; + bit_lib_num_to_bytes_be(pass, 4, app->password); } byte_input_set_header_text(byte_input, "Enter the password in hex"); diff --git a/applications/main/nfc/helpers/mfkey32_logger.c b/applications/main/nfc/helpers/mfkey32_logger.c index 8024179f8..bdd899a36 100644 --- a/applications/main/nfc/helpers/mfkey32_logger.c +++ b/applications/main/nfc/helpers/mfkey32_logger.c @@ -2,7 +2,7 @@ #include -#include +#include #include #include @@ -63,9 +63,9 @@ static bool mfkey32_logger_add_nonce_to_existing_params( if(params->sector_num != sector_num) continue; if(params->key_type != auth_context->key_type) continue; - params->nt1 = nfc_util_bytes2num(auth_context->nt.data, sizeof(MfClassicNt)); - params->nr1 = nfc_util_bytes2num(auth_context->nr.data, sizeof(MfClassicNr)); - params->ar1 = nfc_util_bytes2num(auth_context->ar.data, sizeof(MfClassicAr)); + params->nt1 = bit_lib_bytes_to_num_be(auth_context->nt.data, sizeof(MfClassicNt)); + params->nr1 = bit_lib_bytes_to_num_be(auth_context->nr.data, sizeof(MfClassicNr)); + params->ar1 = bit_lib_bytes_to_num_be(auth_context->ar.data, sizeof(MfClassicAr)); params->is_filled = true; instance->params_collected++; @@ -90,9 +90,9 @@ void mfkey32_logger_add_nonce(Mfkey32Logger* instance, MfClassicAuthContext* aut .cuid = instance->cuid, .sector_num = sector_num, .key_type = auth_context->key_type, - .nt0 = nfc_util_bytes2num(auth_context->nt.data, sizeof(MfClassicNt)), - .nr0 = nfc_util_bytes2num(auth_context->nr.data, sizeof(MfClassicNr)), - .ar0 = nfc_util_bytes2num(auth_context->ar.data, sizeof(MfClassicAr)), + .nt0 = bit_lib_bytes_to_num_be(auth_context->nt.data, sizeof(MfClassicNt)), + .nr0 = bit_lib_bytes_to_num_be(auth_context->nr.data, sizeof(MfClassicNr)), + .ar0 = bit_lib_bytes_to_num_be(auth_context->ar.data, sizeof(MfClassicAr)), }; Mfkey32LoggerParams_push_back(instance->params_arr, params); instance->nonces_saves++; diff --git a/applications/main/nfc/plugins/supported_cards/aime.c b/applications/main/nfc/plugins/supported_cards/aime.c index c747a70b9..c4cd6d8bc 100644 --- a/applications/main/nfc/plugins/supported_cards/aime.c +++ b/applications/main/nfc/plugins/supported_cards/aime.c @@ -1,11 +1,10 @@ #include "nfc_supported_card_plugin.h" +#include -#include - -#include -#include #include +#include + #define TAG "Aime" static const uint64_t aime_key = 0x574343467632; @@ -19,7 +18,7 @@ bool aime_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Verifying sector %u", verify_sector); MfClassicKey key = {}; - nfc_util_num2bytes(aime_key, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(aime_key, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_ctx = {}; MfClassicError error = @@ -53,9 +52,9 @@ static bool aime_read(Nfc* nfc, NfcDevice* device) { data->type = type; MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(aime_key, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(aime_key, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(aime_key, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(aime_key, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -85,7 +84,7 @@ static bool aime_parse(const NfcDevice* device, FuriString* parsed_data) { do { // verify key MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, 0); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, 6); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6); if(key != aime_key) break; // Aime Magic is stored at block 1, starts from byte 0, len 4 bytes diff --git a/applications/main/nfc/plugins/supported_cards/all_in_one.c b/applications/main/nfc/plugins/supported_cards/all_in_one.c index 1be23d1f3..1378629e2 100644 --- a/applications/main/nfc/plugins/supported_cards/all_in_one.c +++ b/applications/main/nfc/plugins/supported_cards/all_in_one.c @@ -1,6 +1,6 @@ #include "nfc_supported_card_plugin.h" +#include -#include #include #define TAG "AllInOne" diff --git a/applications/main/nfc/plugins/supported_cards/clipper.c b/applications/main/nfc/plugins/supported_cards/clipper.c index c76fb1cdc..c24043be0 100644 --- a/applications/main/nfc/plugins/supported_cards/clipper.c +++ b/applications/main/nfc/plugins/supported_cards/clipper.c @@ -19,10 +19,11 @@ * along with this program. If not, see . */ #include "nfc_supported_card_plugin.h" +#include -#include #include -#include + +#include #include #include #include @@ -194,12 +195,12 @@ static bool dump_ride_event(const uint8_t* record, FuriString* parsed_data); // Unmarshal a 32-bit integer, big endian, unsigned static inline uint32_t get_u32be(const uint8_t* field) { - return nfc_util_bytes2num(field, 4); + return bit_lib_bytes_to_num_be(field, 4); } // Unmarshal a 16-bit integer, big endian, unsigned static uint16_t get_u16be(const uint8_t* field) { - return nfc_util_bytes2num(field, 2); + return bit_lib_bytes_to_num_be(field, 2); } // Unmarshal a 16-bit integer, big endian, signed, two's-complement @@ -330,7 +331,7 @@ static bool decode_id_file(const uint8_t* ef8_data, ClipperCardInfo* info) { // uk ?8?? Unknown, 8-bit byte // card_id U32BE Card identifier // - info->serial_number = nfc_util_bytes2num(&ef8_data[1], 4); + info->serial_number = bit_lib_bytes_to_num_be(&ef8_data[1], 4); return true; } diff --git a/applications/main/nfc/plugins/supported_cards/emv.c b/applications/main/nfc/plugins/supported_cards/emv.c index fd2c3fcb3..663f9a608 100644 --- a/applications/main/nfc/plugins/supported_cards/emv.c +++ b/applications/main/nfc/plugins/supported_cards/emv.c @@ -16,17 +16,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "core/string.h" -#include "furi_hal_rtc.h" -#include "helpers/nfc_emv_parser.h" + #include "nfc_supported_card_plugin.h" +#include #include "protocols/emv/emv.h" -#include "protocols/nfc_protocol.h" -#include +#include "helpers/nfc_emv_parser.h" -#include -#include +#include #define TAG "EMV" diff --git a/applications/main/nfc/plugins/supported_cards/gallagher.c b/applications/main/nfc/plugins/supported_cards/gallagher.c index 8b6a58987..869d74563 100644 --- a/applications/main/nfc/plugins/supported_cards/gallagher.c +++ b/applications/main/nfc/plugins/supported_cards/gallagher.c @@ -5,12 +5,11 @@ */ #include "nfc_supported_card_plugin.h" +#include + #include "../../api/gallagher/gallagher_util.h" -#include -#include -#include -#include +#include static bool gallagher_parse(const NfcDevice* device, FuriString* parsed_data) { furi_assert(device); @@ -30,8 +29,9 @@ static bool gallagher_parse(const NfcDevice* device, FuriString* parsed_data) { // Test 1: The first 8 bytes and the second 8 bytes should be bitwise inverses. const uint8_t* credential_block_start_ptr = &data->block[credential_sector_start_block_number].data[0]; - uint64_t cardholder_credential = nfc_util_bytes2num(credential_block_start_ptr, 8); - uint64_t cardholder_credential_inverse = nfc_util_bytes2num(credential_block_start_ptr + 8, 8); + uint64_t cardholder_credential = bit_lib_bytes_to_num_be(credential_block_start_ptr, 8); + uint64_t cardholder_credential_inverse = + bit_lib_bytes_to_num_be(credential_block_start_ptr + 8, 8); // Due to endianness, this is testing the bytes in the wrong order, // but the result still should be correct. if(cardholder_credential != ~cardholder_credential_inverse) { diff --git a/applications/main/nfc/plugins/supported_cards/hi.c b/applications/main/nfc/plugins/supported_cards/hi.c index 1d390196c..4ab66ddd2 100644 --- a/applications/main/nfc/plugins/supported_cards/hi.c +++ b/applications/main/nfc/plugins/supported_cards/hi.c @@ -1,9 +1,9 @@ #include "nfc_supported_card_plugin.h" -#include -#include -#include +#include + #include -#include + +#include #define TAG "HI!" #define KEY_LENGTH 6 @@ -91,7 +91,7 @@ static bool hi_verify_type(Nfc* nfc, MfClassicType type) { FURI_LOG_D(TAG, "Verifying sector %lu", cfg.verify_sector); MfClassicKey key = {0}; - nfc_util_num2bytes(cfg.keys[cfg.verify_sector].b, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(cfg.keys[cfg.verify_sector].b, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = @@ -139,16 +139,16 @@ static bool hi_read(Nfc* nfc, NfcDevice* device) { for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { if(cfg.keys[i].a == 0x000000000000 && cfg.keys[i].b == 0x000000000000) { - cfg.keys[i].a = nfc_util_bytes2num(keyA[i], KEY_LENGTH); - cfg.keys[i].b = nfc_util_bytes2num(keyB[i], KEY_LENGTH); + cfg.keys[i].a = bit_lib_bytes_to_num_be(keyA[i], KEY_LENGTH); + cfg.keys[i].b = bit_lib_bytes_to_num_be(keyB[i], KEY_LENGTH); } } MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -184,7 +184,7 @@ static bool hi_parse(const NfcDevice* device, FuriString* parsed_data) { // Verify key MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, cfg.verify_sector); - uint64_t key = nfc_util_bytes2num(sec_tr->key_b.data, 6); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_b.data, 6); if(key != cfg.keys[cfg.verify_sector].b) return false; //Get UID diff --git a/applications/main/nfc/plugins/supported_cards/hid.c b/applications/main/nfc/plugins/supported_cards/hid.c index cb0178ecc..39ab66351 100644 --- a/applications/main/nfc/plugins/supported_cards/hid.c +++ b/applications/main/nfc/plugins/supported_cards/hid.c @@ -1,11 +1,10 @@ #include "nfc_supported_card_plugin.h" +#include -#include - -#include -#include #include +#include + #define TAG "HID" static const uint64_t hid_key = 0x484944204953; @@ -19,7 +18,7 @@ bool hid_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Verifying sector %u", verify_sector); MfClassicKey key = {}; - nfc_util_num2bytes(hid_key, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(hid_key, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_ctx = {}; MfClassicError error = @@ -53,9 +52,9 @@ static bool hid_read(Nfc* nfc, NfcDevice* device) { data->type = type; MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(hid_key, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(hid_key, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(hid_key, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(hid_key, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -111,7 +110,7 @@ static bool hid_parse(const NfcDevice* device, FuriString* parsed_data) { const uint8_t verify_sector = 1; MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, verify_sector); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, 6); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6); if(key != hid_key) break; // Currently doesn't support bit length > 63 diff --git a/applications/main/nfc/plugins/supported_cards/itso.c b/applications/main/nfc/plugins/supported_cards/itso.c index a4e0c8869..94d258025 100644 --- a/applications/main/nfc/plugins/supported_cards/itso.c +++ b/applications/main/nfc/plugins/supported_cards/itso.c @@ -1,7 +1,7 @@ /* itso.c - Parser for ITSO cards (United Kingdom). */ #include "nfc_supported_card_plugin.h" +#include -#include #include #include diff --git a/applications/main/nfc/plugins/supported_cards/kazan.c b/applications/main/nfc/plugins/supported_cards/kazan.c index 841d126d1..361f7826b 100644 --- a/applications/main/nfc/plugins/supported_cards/kazan.c +++ b/applications/main/nfc/plugins/supported_cards/kazan.c @@ -17,14 +17,11 @@ * along with this program. If not, see . */ #include "nfc_supported_card_plugin.h" +#include -#include "protocols/mf_classic/mf_classic.h" -#include - -#include -#include #include +#include #include #define TAG "Kazan" @@ -134,7 +131,7 @@ static bool kazan_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Verifying sector %u", verification_sector_number); MfClassicKey key_1 = {0}; - nfc_util_num2bytes( + bit_lib_num_to_bytes_be( kazan_1k_keys_v1[verification_sector_number].a, COUNT_OF(key_1.data), key_1.data); MfClassicAuthContext auth_context; @@ -145,7 +142,7 @@ static bool kazan_verify(Nfc* nfc) { TAG, "Failed to read block %u: %d. Keys: v1", verification_block_number, error); MfClassicKey key_2 = {0}; - nfc_util_num2bytes( + bit_lib_num_to_bytes_be( kazan_1k_keys_v2[verification_sector_number].a, COUNT_OF(key_2.data), key_2.data); MfClassicAuthContext auth_context; @@ -196,17 +193,23 @@ static bool kazan_read(Nfc* nfc, NfcDevice* device) { }; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(kazan_1k_keys_v1[i].a, sizeof(MfClassicKey), keys_v1.key_a[i].data); - nfc_util_num2bytes(kazan_1k_keys_v2[i].a, sizeof(MfClassicKey), keys_v2.key_a[i].data); - nfc_util_num2bytes(kazan_1k_keys_v3[i].a, sizeof(MfClassicKey), keys_v3.key_a[i].data); + bit_lib_num_to_bytes_be( + kazan_1k_keys_v1[i].a, sizeof(MfClassicKey), keys_v1.key_a[i].data); + bit_lib_num_to_bytes_be( + kazan_1k_keys_v2[i].a, sizeof(MfClassicKey), keys_v2.key_a[i].data); + bit_lib_num_to_bytes_be( + kazan_1k_keys_v3[i].a, sizeof(MfClassicKey), keys_v3.key_a[i].data); FURI_BIT_SET(keys_v1.key_a_mask, i); FURI_BIT_SET(keys_v2.key_a_mask, i); FURI_BIT_SET(keys_v3.key_a_mask, i); - nfc_util_num2bytes(kazan_1k_keys_v1[i].b, sizeof(MfClassicKey), keys_v1.key_b[i].data); - nfc_util_num2bytes(kazan_1k_keys_v2[i].b, sizeof(MfClassicKey), keys_v2.key_b[i].data); - nfc_util_num2bytes(kazan_1k_keys_v3[i].b, sizeof(MfClassicKey), keys_v3.key_b[i].data); + bit_lib_num_to_bytes_be( + kazan_1k_keys_v1[i].b, sizeof(MfClassicKey), keys_v1.key_b[i].data); + bit_lib_num_to_bytes_be( + kazan_1k_keys_v2[i].b, sizeof(MfClassicKey), keys_v2.key_b[i].data); + bit_lib_num_to_bytes_be( + kazan_1k_keys_v3[i].b, sizeof(MfClassicKey), keys_v3.key_b[i].data); FURI_BIT_SET(keys_v1.key_b_mask, i); FURI_BIT_SET(keys_v2.key_b_mask, i); @@ -261,8 +264,8 @@ static bool kazan_parse(const NfcDevice* device, FuriString* parsed_data) { const MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, ticket_sector_number); - keys.a = nfc_util_bytes2num(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); - keys.b = nfc_util_bytes2num(sec_tr->key_b.data, COUNT_OF(sec_tr->key_b.data)); + keys.a = bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); + keys.b = bit_lib_bytes_to_num_be(sec_tr->key_b.data, COUNT_OF(sec_tr->key_b.data)); if(((keys.a != kazan_1k_keys_v1[8].a) && (keys.a != kazan_1k_keys_v2[8].a)) || ((keys.b != kazan_1k_keys_v1[8].b) && (keys.b != kazan_1k_keys_v2[8].b))) { @@ -305,11 +308,11 @@ static bool kazan_parse(const NfcDevice* device, FuriString* parsed_data) { start_block_num = mf_classic_get_first_block_num_of_sector(balance_sector_number); block_start_ptr = &data->block[start_block_num].data[0]; - const uint32_t trip_counter = nfc_util_bytes2num_little_endian(block_start_ptr, 4); + const uint32_t trip_counter = bit_lib_bytes_to_num_le(block_start_ptr, 4); size_t uid_len = 0; const uint8_t* uid = mf_classic_get_uid(data, &uid_len); - const uint32_t card_number = nfc_util_bytes2num_little_endian(uid, 4); + const uint32_t card_number = bit_lib_bytes_to_num_le(uid, 4); furi_string_cat_printf( parsed_data, "\e#Kazan transport card\nCard number: %lu\n", card_number); diff --git a/applications/main/nfc/plugins/supported_cards/metromoney.c b/applications/main/nfc/plugins/supported_cards/metromoney.c index 34855bcb5..338515f90 100644 --- a/applications/main/nfc/plugins/supported_cards/metromoney.c +++ b/applications/main/nfc/plugins/supported_cards/metromoney.c @@ -17,14 +17,12 @@ * along with this program. If not, see . */ #include "nfc_supported_card_plugin.h" +#include -#include "protocols/mf_classic/mf_classic.h" -#include - -#include -#include #include +#include + #define TAG "Metromoney" typedef struct { @@ -61,7 +59,7 @@ static bool metromoney_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Verifying sector %u", ticket_sector_number); MfClassicKey key = {0}; - nfc_util_num2bytes( + bit_lib_num_to_bytes_be( metromoney_1k_keys[ticket_sector_number].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; @@ -100,9 +98,11 @@ static bool metromoney_read(Nfc* nfc, NfcDevice* device) { .key_b_mask = 0, }; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(metromoney_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be( + metromoney_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(metromoney_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be( + metromoney_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -137,7 +137,8 @@ static bool metromoney_parse(const NfcDevice* device, FuriString* parsed_data) { const MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, ticket_sector_number); - const uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); + const uint64_t key = + bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); if(key != metromoney_1k_keys[ticket_sector_number].a) break; // Parse data @@ -147,14 +148,14 @@ static bool metromoney_parse(const NfcDevice* device, FuriString* parsed_data) { const uint8_t* block_start_ptr = &data->block[start_block_num + ticket_block_number].data[0]; - uint32_t balance = nfc_util_bytes2num_little_endian(block_start_ptr, 4) - 100; + uint32_t balance = bit_lib_bytes_to_num_le(block_start_ptr, 4) - 100; uint32_t balance_lari = balance / 100; uint8_t balance_tetri = balance % 100; size_t uid_len = 0; const uint8_t* uid = mf_classic_get_uid(data, &uid_len); - uint32_t card_number = nfc_util_bytes2num_little_endian(uid, 4); + uint32_t card_number = bit_lib_bytes_to_num_le(uid, 4); furi_string_printf( parsed_data, diff --git a/applications/main/nfc/plugins/supported_cards/microel.c b/applications/main/nfc/plugins/supported_cards/microel.c index 12c196d11..91e5b2286 100644 --- a/applications/main/nfc/plugins/supported_cards/microel.c +++ b/applications/main/nfc/plugins/supported_cards/microel.c @@ -1,9 +1,9 @@ #include "nfc_supported_card_plugin.h" -#include -#include -#include +#include + #include -#include + +#include #define TAG "Microel" #define KEY_LENGTH 6 @@ -116,7 +116,8 @@ static bool microel_read(Nfc* nfc, NfcDevice* device) { // Check key 0a to verify if it is a microel card MfClassicKey key = {0}; - nfc_util_num2bytes(nfc_util_bytes2num(keyA, KEY_LENGTH), COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be( + bit_lib_bytes_to_num_be(keyA, KEY_LENGTH), COUNT_OF(key.data), key.data); const uint8_t block_num = mf_classic_get_first_block_num_of_sector(0); // This is 0 MfClassicAuthContext auth_context; error = @@ -128,17 +129,19 @@ static bool microel_read(Nfc* nfc, NfcDevice* device) { // Save keys generated to stucture for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { if(microel_1k_keys[i].a == 0x000000000000) { - microel_1k_keys[i].a = nfc_util_bytes2num(keyA, KEY_LENGTH); + microel_1k_keys[i].a = bit_lib_bytes_to_num_be(keyA, KEY_LENGTH); } if(microel_1k_keys[i].b == 0x000000000000) { - microel_1k_keys[i].b = nfc_util_bytes2num(keyB, KEY_LENGTH); + microel_1k_keys[i].b = bit_lib_bytes_to_num_be(keyB, KEY_LENGTH); } } MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(microel_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be( + microel_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(microel_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be( + microel_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -179,8 +182,8 @@ static bool microel_parse(const NfcDevice* device, FuriString* parsed_data) { // Verify key MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, verify_sector); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, 6); - uint64_t key_for_check_from_array = nfc_util_bytes2num(keyA, KEY_LENGTH); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6); + uint64_t key_for_check_from_array = bit_lib_bytes_to_num_be(keyA, KEY_LENGTH); if(key != key_for_check_from_array) break; //Get credit in block number 8 diff --git a/applications/main/nfc/plugins/supported_cards/mizip.c b/applications/main/nfc/plugins/supported_cards/mizip.c index 4fd1bd5e0..dc5705059 100644 --- a/applications/main/nfc/plugins/supported_cards/mizip.c +++ b/applications/main/nfc/plugins/supported_cards/mizip.c @@ -1,9 +1,9 @@ #include "nfc_supported_card_plugin.h" -#include -#include -#include +#include + #include -#include + +#include #define TAG "MiZIP" #define KEY_LENGTH 6 @@ -102,7 +102,7 @@ static bool mizip_verify_type(Nfc* nfc, MfClassicType type) { FURI_LOG_D(TAG, "Verifying sector %lu", cfg.verify_sector); MfClassicKey key = {0}; - nfc_util_num2bytes(cfg.keys[cfg.verify_sector].b, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(cfg.keys[cfg.verify_sector].b, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = @@ -152,16 +152,16 @@ static bool mizip_read(Nfc* nfc, NfcDevice* device) { for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { if(cfg.keys[i].a == 0x000000000000 && cfg.keys[i].b == 0x000000000000) { - cfg.keys[i].a = nfc_util_bytes2num(keyA[i], KEY_LENGTH); - cfg.keys[i].b = nfc_util_bytes2num(keyB[i], KEY_LENGTH); + cfg.keys[i].a = bit_lib_bytes_to_num_be(keyA[i], KEY_LENGTH); + cfg.keys[i].b = bit_lib_bytes_to_num_be(keyB[i], KEY_LENGTH); } } MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -197,7 +197,7 @@ static bool mizip_parse(const NfcDevice* device, FuriString* parsed_data) { // Verify key MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, cfg.verify_sector); - uint64_t key = nfc_util_bytes2num(sec_tr->key_b.data, 6); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_b.data, 6); if(key != cfg.keys[cfg.verify_sector].b) return false; //Get UID diff --git a/applications/main/nfc/plugins/supported_cards/mykey.c b/applications/main/nfc/plugins/supported_cards/mykey.c index 61619ddf3..8e2d5cf11 100644 --- a/applications/main/nfc/plugins/supported_cards/mykey.c +++ b/applications/main/nfc/plugins/supported_cards/mykey.c @@ -1,6 +1,6 @@ #include "nfc_supported_card_plugin.h" +#include -#include #include #include diff --git a/applications/main/nfc/plugins/supported_cards/myki.c b/applications/main/nfc/plugins/supported_cards/myki.c index 70a696371..4da5d30af 100644 --- a/applications/main/nfc/plugins/supported_cards/myki.c +++ b/applications/main/nfc/plugins/supported_cards/myki.c @@ -5,8 +5,8 @@ * Reference: https://github.com/metrodroid/metrodroid/wiki/Myki */ #include "nfc_supported_card_plugin.h" +#include -#include #include static const MfDesfireApplicationId myki_app_id = {.data = {0x00, 0x11, 0xf2}}; diff --git a/applications/main/nfc/plugins/supported_cards/ndef.c b/applications/main/nfc/plugins/supported_cards/ndef.c index 1a2497f2c..1ed3a6365 100644 --- a/applications/main/nfc/plugins/supported_cards/ndef.c +++ b/applications/main/nfc/plugins/supported_cards/ndef.c @@ -5,11 +5,12 @@ // Made by @Willy-JL #include "nfc_supported_card_plugin.h" +#include -#include -#include #include +#include + #define TAG "NDEF" static bool is_text(const uint8_t* buf, size_t len) { @@ -162,18 +163,18 @@ static void parse_ndef_wifi(FuriString* str, const uint8_t* payload, uint32_t pa size_t i = 0; while(i < payload_len) { - uint16_t field_id = nfc_util_bytes2num(payload + i, 2); + uint16_t field_id = bit_lib_bytes_to_num_be(payload + i, 2); i += 2; - uint16_t field_len = nfc_util_bytes2num(payload + i, 2); + uint16_t field_len = bit_lib_bytes_to_num_be(payload + i, 2); i += 2; if(field_id == CREDENTIAL_FIELD_ID) { furi_string_cat(str, "WiFi\n"); size_t start_position = i; while(i < start_position + field_len) { - uint16_t cfg_id = nfc_util_bytes2num(payload + i, 2); + uint16_t cfg_id = bit_lib_bytes_to_num_be(payload + i, 2); i += 2; - uint16_t cfg_len = nfc_util_bytes2num(payload + i, 2); + uint16_t cfg_len = bit_lib_bytes_to_num_be(payload + i, 2); i += 2; if(i + cfg_len > start_position + field_len) { @@ -196,7 +197,7 @@ static void parse_ndef_wifi(FuriString* str, const uint8_t* payload, uint32_t pa if(cfg_len != AUTH_TYPE_EXPECTED_SIZE) { return; } - short auth_type = nfc_util_bytes2num(payload + i, 2); + short auth_type = bit_lib_bytes_to_num_be(payload + i, 2); i += 2; const char* auth; switch(auth_type) { @@ -318,7 +319,7 @@ static const uint8_t* parse_ndef_message( if(short_record) { payload_len = *cur++; } else { - payload_len = nfc_util_bytes2num(cur, 4); + payload_len = bit_lib_bytes_to_num_be(cur, 4); cur += 4; } @@ -397,7 +398,7 @@ static bool ndef_parse(const NfcDevice* device, FuriString* parsed_data) { cur = end; break; } - len = nfc_util_bytes2num(++cur, 2); + len = bit_lib_bytes_to_num_be(++cur, 2); cur += 2; } if(cur + len >= end) { @@ -439,7 +440,7 @@ static bool ndef_parse(const NfcDevice* device, FuriString* parsed_data) { cur = end; break; } - cur += nfc_util_bytes2num(cur + 1, 2) + 3; // Shift by TLV length + cur += bit_lib_bytes_to_num_be(cur + 1, 2) + 3; // Shift by TLV length } break; diff --git a/applications/main/nfc/plugins/supported_cards/opal.c b/applications/main/nfc/plugins/supported_cards/opal.c index c71635d53..4ec38208c 100644 --- a/applications/main/nfc/plugins/supported_cards/opal.c +++ b/applications/main/nfc/plugins/supported_cards/opal.c @@ -29,13 +29,13 @@ */ #include "nfc_supported_card_plugin.h" - -#include -#include -#include +#include #include +#include +#include + static const MfDesfireApplicationId opal_app_id = {.data = {0x31, 0x45, 0x53}}; static const MfDesfireFileId opal_file_id = 0x07; diff --git a/applications/main/nfc/plugins/supported_cards/plantain.c b/applications/main/nfc/plugins/supported_cards/plantain.c index ba8f34295..ebdc902e8 100644 --- a/applications/main/nfc/plugins/supported_cards/plantain.c +++ b/applications/main/nfc/plugins/supported_cards/plantain.c @@ -1,11 +1,10 @@ #include "nfc_supported_card_plugin.h" +#include -#include - -#include -#include #include +#include + #define TAG "Plantain" typedef struct { @@ -87,7 +86,7 @@ static bool plantain_verify_type(Nfc* nfc, MfClassicType type) { FURI_LOG_D(TAG, "Verifying sector %lu", cfg.data_sector); MfClassicKey key = {0}; - nfc_util_num2bytes(cfg.keys[cfg.data_sector].a, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(cfg.keys[cfg.data_sector].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = @@ -128,9 +127,9 @@ static bool plantain_read(Nfc* nfc, NfcDevice* device) { MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -166,7 +165,8 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) { const MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, cfg.data_sector); - const uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); + const uint64_t key = + bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); if(key != cfg.keys[cfg.data_sector].a) break; // Point to block 0 of sector 4, value 0 diff --git a/applications/main/nfc/plugins/supported_cards/saflok.c b/applications/main/nfc/plugins/supported_cards/saflok.c index 4b59e853e..ba2383f8c 100644 --- a/applications/main/nfc/plugins/supported_cards/saflok.c +++ b/applications/main/nfc/plugins/supported_cards/saflok.c @@ -3,11 +3,11 @@ // FZ plugin by @noproto #include "nfc_supported_card_plugin.h" -#include -#include -#include +#include + #include -#include + +#include #define TAG "Saflok" #define MAGIC_TABLE_SIZE 192 @@ -78,7 +78,7 @@ static bool saflok_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Saflok: Verifying sector %i", CHECK_SECTOR); MfClassicKey key = {0}; - nfc_util_num2bytes(saflok_1k_keys[CHECK_SECTOR].a, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(saflok_1k_keys[CHECK_SECTOR].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = @@ -119,7 +119,7 @@ static bool saflok_read(Nfc* nfc, NfcDevice* device) { uint8_t key[KEY_LENGTH]; generate_saflok_key(uid, key); - uint64_t num_key = nfc_util_bytes2num(key, KEY_LENGTH); + uint64_t num_key = bit_lib_bytes_to_num_be(key, KEY_LENGTH); FURI_LOG_D(TAG, "Saflok: Key generated for UID: %012llX", num_key); for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { @@ -130,9 +130,9 @@ static bool saflok_read(Nfc* nfc, NfcDevice* device) { MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(saflok_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(saflok_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(saflok_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(saflok_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } diff --git a/applications/main/nfc/plugins/supported_cards/social_moscow.c b/applications/main/nfc/plugins/supported_cards/social_moscow.c index 714b4eb95..673a67d4b 100644 --- a/applications/main/nfc/plugins/supported_cards/social_moscow.c +++ b/applications/main/nfc/plugins/supported_cards/social_moscow.c @@ -1,14 +1,10 @@ #include "nfc_supported_card_plugin.h" -#include +#include -#include - -#include -#include -#include #include + +#include #include -#include #define TAG "Social_Moscow" @@ -65,447 +61,6 @@ static const MfClassicKeyPair social_moscow_4k_keys[] = { #define TOPBIT(X) (1 << ((X)-1)) -typedef enum { - BitLibParityEven, - BitLibParityOdd, - BitLibParityAlways0, - BitLibParityAlways1, -} BitLibParity; - -typedef struct { - const char mark; - const size_t start; - const size_t length; -} BitLibRegion; - -void bit_lib_push_bit(uint8_t* data, size_t data_size, bool bit) { - size_t last_index = data_size - 1; - - for(size_t i = 0; i < last_index; ++i) { - data[i] = (data[i] << 1) | ((data[i + 1] >> 7) & 1); - } - data[last_index] = (data[last_index] << 1) | bit; -} - -void bit_lib_set_bit(uint8_t* data, size_t position, bool bit) { - if(bit) { - data[position / 8] |= 1UL << (7 - (position % 8)); - } else { - data[position / 8] &= ~(1UL << (7 - (position % 8))); - } -} - -void bit_lib_set_bits(uint8_t* data, size_t position, uint8_t byte, uint8_t length) { - furi_check(length <= 8); - furi_check(length > 0); - - for(uint8_t i = 0; i < length; ++i) { - uint8_t shift = (length - 1) - i; - bit_lib_set_bit(data, position + i, (byte >> shift) & 1); //-V610 - } -} - -bool bit_lib_get_bit(const uint8_t* data, size_t position) { - return (data[position / 8] >> (7 - (position % 8))) & 1; -} - -uint8_t bit_lib_get_bits(const uint8_t* data, size_t position, uint8_t length) { - uint8_t shift = position % 8; - if(shift == 0) { - return data[position / 8] >> (8 - length); - } else { - // TODO fix read out of bounds - uint8_t value = (data[position / 8] << (shift)); - value |= data[position / 8 + 1] >> (8 - shift); - value = value >> (8 - length); - return value; - } -} - -uint16_t bit_lib_get_bits_16(const uint8_t* data, size_t position, uint8_t length) { - uint16_t value = 0; - if(length <= 8) { - value = bit_lib_get_bits(data, position, length); - } else { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, length - 8); - } - return value; -} - -uint32_t bit_lib_get_bits_32(const uint8_t* data, size_t position, uint8_t length) { - uint32_t value = 0; - if(length <= 8) { - value = bit_lib_get_bits(data, position, length); - } else if(length <= 16) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, length - 8); - } else if(length <= 24) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= bit_lib_get_bits(data, position + 16, length - 16); - } else { - value = (uint32_t)bit_lib_get_bits(data, position, 8) << (length - 8); - value |= (uint32_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= (uint32_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); - value |= bit_lib_get_bits(data, position + 24, length - 24); - } - - return value; -} - -uint64_t bit_lib_get_bits_64(const uint8_t* data, size_t position, uint8_t length) { - uint64_t value = 0; - if(length <= 8) { - value = bit_lib_get_bits(data, position, length); - } else if(length <= 16) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, length - 8); - } else if(length <= 24) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= bit_lib_get_bits(data, position + 16, length - 16); - } else if(length <= 32) { - value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); - value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); - value |= bit_lib_get_bits(data, position + 24, length - 24); - } else { - value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); - value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); - value |= (uint64_t)bit_lib_get_bits(data, position + 24, 8) << (length - 32); - value |= (uint64_t)bit_lib_get_bits(data, position + 32, 8) << (length - 40); - value |= (uint64_t)bit_lib_get_bits(data, position + 40, 8) << (length - 48); - value |= (uint64_t)bit_lib_get_bits(data, position + 48, 8) << (length - 56); - value |= (uint64_t)bit_lib_get_bits(data, position + 56, 8) << (length - 64); - value |= bit_lib_get_bits(data, position + 64, length - 64); - } - - return value; -} - -bool bit_lib_test_parity_32(uint32_t bits, BitLibParity parity) { -#if !defined __GNUC__ -#error Please, implement parity test for non-GCC compilers -#else - switch(parity) { - case BitLibParityEven: - return __builtin_parity(bits); - case BitLibParityOdd: - return !__builtin_parity(bits); - default: - furi_crash("Unknown parity"); - } -#endif -} - -bool bit_lib_test_parity( - const uint8_t* bits, - size_t position, - uint8_t length, - BitLibParity parity, - uint8_t parity_length) { - uint32_t parity_block; - bool result = true; - const size_t parity_blocks_count = length / parity_length; - - for(size_t i = 0; i < parity_blocks_count; ++i) { - switch(parity) { - case BitLibParityEven: - case BitLibParityOdd: - parity_block = bit_lib_get_bits_32(bits, position + i * parity_length, parity_length); - if(!bit_lib_test_parity_32(parity_block, parity)) { - result = false; - } - break; - case BitLibParityAlways0: - if(bit_lib_get_bit(bits, position + i * parity_length + parity_length - 1)) { - result = false; - } - break; - case BitLibParityAlways1: - if(!bit_lib_get_bit(bits, position + i * parity_length + parity_length - 1)) { - result = false; - } - break; - } - - if(!result) break; - } - return result; -} - -size_t bit_lib_add_parity( - const uint8_t* data, - size_t position, - uint8_t* dest, - size_t dest_position, - uint8_t source_length, - uint8_t parity_length, - BitLibParity parity) { - uint32_t parity_word = 0; - size_t j = 0, bit_count = 0; - for(int word = 0; word < source_length; word += parity_length - 1) { - for(int bit = 0; bit < parity_length - 1; bit++) { - parity_word = (parity_word << 1) | bit_lib_get_bit(data, position + word + bit); - bit_lib_set_bit( - dest, dest_position + j++, bit_lib_get_bit(data, position + word + bit)); - } - // if parity fails then return 0 - switch(parity) { - case BitLibParityAlways0: - bit_lib_set_bit(dest, dest_position + j++, 0); - break; // marker bit which should be a 0 - case BitLibParityAlways1: - bit_lib_set_bit(dest, dest_position + j++, 1); - break; // marker bit which should be a 1 - default: - bit_lib_set_bit( - dest, - dest_position + j++, - (bit_lib_test_parity_32(parity_word, BitLibParityOdd) ^ parity) ^ 1); - break; - } - bit_count += parity_length; - parity_word = 0; - } - // if we got here then all the parities passed - // return bit count - return bit_count; -} - -size_t bit_lib_remove_bit_every_nth(uint8_t* data, size_t position, uint8_t length, uint8_t n) { - size_t counter = 0; - size_t result_counter = 0; - uint8_t bit_buffer = 0; - uint8_t bit_counter = 0; - - while(counter < length) { - if((counter + 1) % n != 0) { - bit_buffer = (bit_buffer << 1) | bit_lib_get_bit(data, position + counter); - bit_counter++; - } - - if(bit_counter == 8) { - bit_lib_set_bits(data, position + result_counter, bit_buffer, 8); - bit_counter = 0; - bit_buffer = 0; - result_counter += 8; - } - counter++; - } - - if(bit_counter != 0) { - bit_lib_set_bits(data, position + result_counter, bit_buffer, bit_counter); - result_counter += bit_counter; - } - return result_counter; -} - -void bit_lib_copy_bits( - uint8_t* data, - size_t position, - size_t length, - const uint8_t* source, - size_t source_position) { - for(size_t i = 0; i < length; ++i) { - bit_lib_set_bit(data, position + i, bit_lib_get_bit(source, source_position + i)); - } -} - -void bit_lib_reverse_bits(uint8_t* data, size_t position, uint8_t length) { - size_t i = 0; - size_t j = length - 1; - - while(i < j) { - bool tmp = bit_lib_get_bit(data, position + i); - bit_lib_set_bit(data, position + i, bit_lib_get_bit(data, position + j)); - bit_lib_set_bit(data, position + j, tmp); - i++; - j--; - } -} - -uint8_t bit_lib_get_bit_count(uint32_t data) { -#if defined __GNUC__ - return __builtin_popcountl(data); -#else -#error Please, implement popcount for non-GCC compilers -#endif -} - -void bit_lib_print_bits(const uint8_t* data, size_t length) { - for(size_t i = 0; i < length; ++i) { - printf("%u", bit_lib_get_bit(data, i)); - } -} - -void bit_lib_print_regions( - const BitLibRegion* regions, - size_t region_count, - const uint8_t* data, - size_t length) { - // print data - bit_lib_print_bits(data, length); - printf("\r\n"); - - // print regions - for(size_t c = 0; c < length; ++c) { - bool print = false; - - for(size_t i = 0; i < region_count; i++) { - if(regions[i].start <= c && c < regions[i].start + regions[i].length) { - print = true; - printf("%c", regions[i].mark); - break; - } - } - - if(!print) { - printf(" "); - } - } - printf("\r\n"); - - // print regions data - for(size_t c = 0; c < length; ++c) { - bool print = false; - - for(size_t i = 0; i < region_count; i++) { - if(regions[i].start <= c && c < regions[i].start + regions[i].length) { - print = true; - printf("%u", bit_lib_get_bit(data, c)); - break; - } - } - - if(!print) { - printf(" "); - } - } - printf("\r\n"); -} - -uint16_t bit_lib_reverse_16_fast(uint16_t data) { - uint16_t result = 0; - result |= (data & 0x8000) >> 15; - result |= (data & 0x4000) >> 13; - result |= (data & 0x2000) >> 11; - result |= (data & 0x1000) >> 9; - result |= (data & 0x0800) >> 7; - result |= (data & 0x0400) >> 5; - result |= (data & 0x0200) >> 3; - result |= (data & 0x0100) >> 1; - result |= (data & 0x0080) << 1; - result |= (data & 0x0040) << 3; - result |= (data & 0x0020) << 5; - result |= (data & 0x0010) << 7; - result |= (data & 0x0008) << 9; - result |= (data & 0x0004) << 11; - result |= (data & 0x0002) << 13; - result |= (data & 0x0001) << 15; - return result; -} - -uint8_t bit_lib_reverse_8_fast(uint8_t byte) { - byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4; - byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2; - byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1; - return byte; -} - -uint16_t bit_lib_crc8( - uint8_t const* data, - size_t data_size, - uint8_t polynom, - uint8_t init, - bool ref_in, - bool ref_out, - uint8_t xor_out) { - uint8_t crc = init; - - for(size_t i = 0; i < data_size; ++i) { - uint8_t byte = data[i]; - if(ref_in) bit_lib_reverse_bits(&byte, 0, 8); - crc ^= byte; - - for(size_t j = 8; j > 0; --j) { - if(crc & TOPBIT(8)) { - crc = (crc << 1) ^ polynom; - } else { - crc = (crc << 1); - } - } - } - - if(ref_out) bit_lib_reverse_bits(&crc, 0, 8); - crc ^= xor_out; - - return crc; -} - -uint16_t bit_lib_crc16( - uint8_t const* data, - size_t data_size, - uint16_t polynom, - uint16_t init, - bool ref_in, - bool ref_out, - uint16_t xor_out) { - uint16_t crc = init; - - for(size_t i = 0; i < data_size; ++i) { - uint8_t byte = data[i]; - if(ref_in) byte = bit_lib_reverse_16_fast(byte) >> 8; - - for(size_t j = 0; j < 8; ++j) { - bool c15 = (crc >> 15 & 1); - bool bit = (byte >> (7 - j) & 1); - crc <<= 1; - if(c15 ^ bit) crc ^= polynom; - } - } - - if(ref_out) crc = bit_lib_reverse_16_fast(crc); - crc ^= xor_out; - - return crc; -} - -#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60 -#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60) -#define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24) -#define FURI_HAL_RTC_EPOCH_START_YEAR 1970 -#define FURI_HAL_RTC_IS_LEAP_YEAR(year) \ - ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0)) - -void timestamp_to_datetime(uint32_t timestamp, FuriHalRtcDateTime* datetime) { - uint32_t days = timestamp / FURI_HAL_RTC_SECONDS_PER_DAY; - uint32_t seconds_in_day = timestamp % FURI_HAL_RTC_SECONDS_PER_DAY; - - datetime->year = FURI_HAL_RTC_EPOCH_START_YEAR; - - while(days >= furi_hal_rtc_get_days_per_year(datetime->year)) { - days -= furi_hal_rtc_get_days_per_year(datetime->year); - (datetime->year)++; - } - - datetime->month = 1; - while(days >= furi_hal_rtc_get_days_per_month( - FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year), datetime->month)) { - days -= furi_hal_rtc_get_days_per_month( - FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year), datetime->month); - (datetime->month)++; - } - - datetime->day = days + 1; - datetime->hour = seconds_in_day / FURI_HAL_RTC_SECONDS_PER_HOUR; - datetime->minute = - (seconds_in_day % FURI_HAL_RTC_SECONDS_PER_HOUR) / FURI_HAL_RTC_SECONDS_PER_MINUTE; - datetime->second = seconds_in_day % FURI_HAL_RTC_SECONDS_PER_MINUTE; -} - void from_days_to_datetime(uint16_t days, FuriHalRtcDateTime* datetime, uint16_t start_year) { uint32_t timestamp = days * 24 * 60 * 60; FuriHalRtcDateTime start_datetime = {0}; @@ -513,7 +68,7 @@ void from_days_to_datetime(uint16_t days, FuriHalRtcDateTime* datetime, uint16_t start_datetime.month = 12; start_datetime.day = 31; timestamp += furi_hal_rtc_datetime_to_timestamp(&start_datetime); - timestamp_to_datetime(timestamp, datetime); + furi_hal_rtc_timestamp_to_datetime(timestamp, datetime); } void from_minutes_to_datetime(uint32_t minutes, FuriHalRtcDateTime* datetime, uint16_t start_year) { @@ -523,7 +78,7 @@ void from_minutes_to_datetime(uint32_t minutes, FuriHalRtcDateTime* datetime, ui start_datetime.month = 12; start_datetime.day = 31; timestamp += furi_hal_rtc_datetime_to_timestamp(&start_datetime); - timestamp_to_datetime(timestamp, datetime); + furi_hal_rtc_timestamp_to_datetime(timestamp, datetime); } bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { @@ -671,7 +226,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date) * 24 * 60 + card_start_trip_time, + (card_start_trip_date)*24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -1486,7 +1041,7 @@ static bool social_moscow_verify_type(Nfc* nfc, MfClassicType type) { FURI_LOG_D(TAG, "Verifying sector %lu", cfg.data_sector); MfClassicKey key = {0}; - nfc_util_num2bytes(cfg.keys[cfg.data_sector].a, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(cfg.keys[cfg.data_sector].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = @@ -1527,9 +1082,9 @@ static bool social_moscow_read(Nfc* nfc, NfcDevice* device) { MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -1566,9 +1121,9 @@ static bool social_moscow_parse(const NfcDevice* device, FuriString* parsed_data mf_classic_get_sector_trailer_by_sector(data, cfg.data_sector); const uint64_t key_a = - nfc_util_bytes2num(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); + bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); const uint64_t key_b = - nfc_util_bytes2num(sec_tr->key_b.data, COUNT_OF(sec_tr->key_b.data)); + bit_lib_bytes_to_num_be(sec_tr->key_b.data, COUNT_OF(sec_tr->key_b.data)); if((key_a != cfg.keys[cfg.data_sector].a) || (key_b != cfg.keys[cfg.data_sector].b)) break; uint32_t card_code = bit_lib_get_bits_32(data->block[60].data, 8, 24); diff --git a/applications/main/nfc/plugins/supported_cards/troika.c b/applications/main/nfc/plugins/supported_cards/troika.c index c3f765961..bc3992a39 100644 --- a/applications/main/nfc/plugins/supported_cards/troika.c +++ b/applications/main/nfc/plugins/supported_cards/troika.c @@ -1,14 +1,10 @@ #include "nfc_supported_card_plugin.h" -#include +#include -#include - -#include -#include -#include #include + +#include #include -#include #define TAG "Troika" @@ -66,447 +62,6 @@ static const MfClassicKeyPair troika_4k_keys[] = { #define TOPBIT(X) (1 << ((X)-1)) -typedef enum { - BitLibParityEven, - BitLibParityOdd, - BitLibParityAlways0, - BitLibParityAlways1, -} BitLibParity; - -typedef struct { - const char mark; - const size_t start; - const size_t length; -} BitLibRegion; - -void bit_lib_push_bit(uint8_t* data, size_t data_size, bool bit) { - size_t last_index = data_size - 1; - - for(size_t i = 0; i < last_index; ++i) { - data[i] = (data[i] << 1) | ((data[i + 1] >> 7) & 1); - } - data[last_index] = (data[last_index] << 1) | bit; -} - -void bit_lib_set_bit(uint8_t* data, size_t position, bool bit) { - if(bit) { - data[position / 8] |= 1UL << (7 - (position % 8)); - } else { - data[position / 8] &= ~(1UL << (7 - (position % 8))); - } -} - -void bit_lib_set_bits(uint8_t* data, size_t position, uint8_t byte, uint8_t length) { - furi_check(length <= 8); - furi_check(length > 0); - - for(uint8_t i = 0; i < length; ++i) { - uint8_t shift = (length - 1) - i; - bit_lib_set_bit(data, position + i, (byte >> shift) & 1); //-V610 - } -} - -bool bit_lib_get_bit(const uint8_t* data, size_t position) { - return (data[position / 8] >> (7 - (position % 8))) & 1; -} - -uint8_t bit_lib_get_bits(const uint8_t* data, size_t position, uint8_t length) { - uint8_t shift = position % 8; - if(shift == 0) { - return data[position / 8] >> (8 - length); - } else { - // TODO fix read out of bounds - uint8_t value = (data[position / 8] << (shift)); - value |= data[position / 8 + 1] >> (8 - shift); - value = value >> (8 - length); - return value; - } -} - -uint16_t bit_lib_get_bits_16(const uint8_t* data, size_t position, uint8_t length) { - uint16_t value = 0; - if(length <= 8) { - value = bit_lib_get_bits(data, position, length); - } else { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, length - 8); - } - return value; -} - -uint32_t bit_lib_get_bits_32(const uint8_t* data, size_t position, uint8_t length) { - uint32_t value = 0; - if(length <= 8) { - value = bit_lib_get_bits(data, position, length); - } else if(length <= 16) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, length - 8); - } else if(length <= 24) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= bit_lib_get_bits(data, position + 16, length - 16); - } else { - value = (uint32_t)bit_lib_get_bits(data, position, 8) << (length - 8); - value |= (uint32_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= (uint32_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); - value |= bit_lib_get_bits(data, position + 24, length - 24); - } - - return value; -} - -uint64_t bit_lib_get_bits_64(const uint8_t* data, size_t position, uint8_t length) { - uint64_t value = 0; - if(length <= 8) { - value = bit_lib_get_bits(data, position, length); - } else if(length <= 16) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, length - 8); - } else if(length <= 24) { - value = bit_lib_get_bits(data, position, 8) << (length - 8); - value |= bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= bit_lib_get_bits(data, position + 16, length - 16); - } else if(length <= 32) { - value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); - value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); - value |= bit_lib_get_bits(data, position + 24, length - 24); - } else { - value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); - value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); - value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); - value |= (uint64_t)bit_lib_get_bits(data, position + 24, 8) << (length - 32); - value |= (uint64_t)bit_lib_get_bits(data, position + 32, 8) << (length - 40); - value |= (uint64_t)bit_lib_get_bits(data, position + 40, 8) << (length - 48); - value |= (uint64_t)bit_lib_get_bits(data, position + 48, 8) << (length - 56); - value |= (uint64_t)bit_lib_get_bits(data, position + 56, 8) << (length - 64); - value |= bit_lib_get_bits(data, position + 64, length - 64); - } - - return value; -} - -bool bit_lib_test_parity_32(uint32_t bits, BitLibParity parity) { -#if !defined __GNUC__ -#error Please, implement parity test for non-GCC compilers -#else - switch(parity) { - case BitLibParityEven: - return __builtin_parity(bits); - case BitLibParityOdd: - return !__builtin_parity(bits); - default: - furi_crash("Unknown parity"); - } -#endif -} - -bool bit_lib_test_parity( - const uint8_t* bits, - size_t position, - uint8_t length, - BitLibParity parity, - uint8_t parity_length) { - uint32_t parity_block; - bool result = true; - const size_t parity_blocks_count = length / parity_length; - - for(size_t i = 0; i < parity_blocks_count; ++i) { - switch(parity) { - case BitLibParityEven: - case BitLibParityOdd: - parity_block = bit_lib_get_bits_32(bits, position + i * parity_length, parity_length); - if(!bit_lib_test_parity_32(parity_block, parity)) { - result = false; - } - break; - case BitLibParityAlways0: - if(bit_lib_get_bit(bits, position + i * parity_length + parity_length - 1)) { - result = false; - } - break; - case BitLibParityAlways1: - if(!bit_lib_get_bit(bits, position + i * parity_length + parity_length - 1)) { - result = false; - } - break; - } - - if(!result) break; - } - return result; -} - -size_t bit_lib_add_parity( - const uint8_t* data, - size_t position, - uint8_t* dest, - size_t dest_position, - uint8_t source_length, - uint8_t parity_length, - BitLibParity parity) { - uint32_t parity_word = 0; - size_t j = 0, bit_count = 0; - for(int word = 0; word < source_length; word += parity_length - 1) { - for(int bit = 0; bit < parity_length - 1; bit++) { - parity_word = (parity_word << 1) | bit_lib_get_bit(data, position + word + bit); - bit_lib_set_bit( - dest, dest_position + j++, bit_lib_get_bit(data, position + word + bit)); - } - // if parity fails then return 0 - switch(parity) { - case BitLibParityAlways0: - bit_lib_set_bit(dest, dest_position + j++, 0); - break; // marker bit which should be a 0 - case BitLibParityAlways1: - bit_lib_set_bit(dest, dest_position + j++, 1); - break; // marker bit which should be a 1 - default: - bit_lib_set_bit( - dest, - dest_position + j++, - (bit_lib_test_parity_32(parity_word, BitLibParityOdd) ^ parity) ^ 1); - break; - } - bit_count += parity_length; - parity_word = 0; - } - // if we got here then all the parities passed - // return bit count - return bit_count; -} - -size_t bit_lib_remove_bit_every_nth(uint8_t* data, size_t position, uint8_t length, uint8_t n) { - size_t counter = 0; - size_t result_counter = 0; - uint8_t bit_buffer = 0; - uint8_t bit_counter = 0; - - while(counter < length) { - if((counter + 1) % n != 0) { - bit_buffer = (bit_buffer << 1) | bit_lib_get_bit(data, position + counter); - bit_counter++; - } - - if(bit_counter == 8) { - bit_lib_set_bits(data, position + result_counter, bit_buffer, 8); - bit_counter = 0; - bit_buffer = 0; - result_counter += 8; - } - counter++; - } - - if(bit_counter != 0) { - bit_lib_set_bits(data, position + result_counter, bit_buffer, bit_counter); - result_counter += bit_counter; - } - return result_counter; -} - -void bit_lib_copy_bits( - uint8_t* data, - size_t position, - size_t length, - const uint8_t* source, - size_t source_position) { - for(size_t i = 0; i < length; ++i) { - bit_lib_set_bit(data, position + i, bit_lib_get_bit(source, source_position + i)); - } -} - -void bit_lib_reverse_bits(uint8_t* data, size_t position, uint8_t length) { - size_t i = 0; - size_t j = length - 1; - - while(i < j) { - bool tmp = bit_lib_get_bit(data, position + i); - bit_lib_set_bit(data, position + i, bit_lib_get_bit(data, position + j)); - bit_lib_set_bit(data, position + j, tmp); - i++; - j--; - } -} - -uint8_t bit_lib_get_bit_count(uint32_t data) { -#if defined __GNUC__ - return __builtin_popcountl(data); -#else -#error Please, implement popcount for non-GCC compilers -#endif -} - -void bit_lib_print_bits(const uint8_t* data, size_t length) { - for(size_t i = 0; i < length; ++i) { - printf("%u", bit_lib_get_bit(data, i)); - } -} - -void bit_lib_print_regions( - const BitLibRegion* regions, - size_t region_count, - const uint8_t* data, - size_t length) { - // print data - bit_lib_print_bits(data, length); - printf("\r\n"); - - // print regions - for(size_t c = 0; c < length; ++c) { - bool print = false; - - for(size_t i = 0; i < region_count; i++) { - if(regions[i].start <= c && c < regions[i].start + regions[i].length) { - print = true; - printf("%c", regions[i].mark); - break; - } - } - - if(!print) { - printf(" "); - } - } - printf("\r\n"); - - // print regions data - for(size_t c = 0; c < length; ++c) { - bool print = false; - - for(size_t i = 0; i < region_count; i++) { - if(regions[i].start <= c && c < regions[i].start + regions[i].length) { - print = true; - printf("%u", bit_lib_get_bit(data, c)); - break; - } - } - - if(!print) { - printf(" "); - } - } - printf("\r\n"); -} - -uint16_t bit_lib_reverse_16_fast(uint16_t data) { - uint16_t result = 0; - result |= (data & 0x8000) >> 15; - result |= (data & 0x4000) >> 13; - result |= (data & 0x2000) >> 11; - result |= (data & 0x1000) >> 9; - result |= (data & 0x0800) >> 7; - result |= (data & 0x0400) >> 5; - result |= (data & 0x0200) >> 3; - result |= (data & 0x0100) >> 1; - result |= (data & 0x0080) << 1; - result |= (data & 0x0040) << 3; - result |= (data & 0x0020) << 5; - result |= (data & 0x0010) << 7; - result |= (data & 0x0008) << 9; - result |= (data & 0x0004) << 11; - result |= (data & 0x0002) << 13; - result |= (data & 0x0001) << 15; - return result; -} - -uint8_t bit_lib_reverse_8_fast(uint8_t byte) { - byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4; - byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2; - byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1; - return byte; -} - -uint16_t bit_lib_crc8( - uint8_t const* data, - size_t data_size, - uint8_t polynom, - uint8_t init, - bool ref_in, - bool ref_out, - uint8_t xor_out) { - uint8_t crc = init; - - for(size_t i = 0; i < data_size; ++i) { - uint8_t byte = data[i]; - if(ref_in) bit_lib_reverse_bits(&byte, 0, 8); - crc ^= byte; - - for(size_t j = 8; j > 0; --j) { - if(crc & TOPBIT(8)) { - crc = (crc << 1) ^ polynom; - } else { - crc = (crc << 1); - } - } - } - - if(ref_out) bit_lib_reverse_bits(&crc, 0, 8); - crc ^= xor_out; - - return crc; -} - -uint16_t bit_lib_crc16( - uint8_t const* data, - size_t data_size, - uint16_t polynom, - uint16_t init, - bool ref_in, - bool ref_out, - uint16_t xor_out) { - uint16_t crc = init; - - for(size_t i = 0; i < data_size; ++i) { - uint8_t byte = data[i]; - if(ref_in) byte = bit_lib_reverse_16_fast(byte) >> 8; - - for(size_t j = 0; j < 8; ++j) { - bool c15 = (crc >> 15 & 1); - bool bit = (byte >> (7 - j) & 1); - crc <<= 1; - if(c15 ^ bit) crc ^= polynom; - } - } - - if(ref_out) crc = bit_lib_reverse_16_fast(crc); - crc ^= xor_out; - - return crc; -} - -#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60 -#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60) -#define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24) -#define FURI_HAL_RTC_EPOCH_START_YEAR 1970 -#define FURI_HAL_RTC_IS_LEAP_YEAR(year) \ - ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0)) - -void timestamp_to_datetime(uint32_t timestamp, FuriHalRtcDateTime* datetime) { - uint32_t days = timestamp / FURI_HAL_RTC_SECONDS_PER_DAY; - uint32_t seconds_in_day = timestamp % FURI_HAL_RTC_SECONDS_PER_DAY; - - datetime->year = FURI_HAL_RTC_EPOCH_START_YEAR; - - while(days >= furi_hal_rtc_get_days_per_year(datetime->year)) { - days -= furi_hal_rtc_get_days_per_year(datetime->year); - (datetime->year)++; - } - - datetime->month = 1; - while(days >= furi_hal_rtc_get_days_per_month( - FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year), datetime->month)) { - days -= furi_hal_rtc_get_days_per_month( - FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year), datetime->month); - (datetime->month)++; - } - - datetime->day = days + 1; - datetime->hour = seconds_in_day / FURI_HAL_RTC_SECONDS_PER_HOUR; - datetime->minute = - (seconds_in_day % FURI_HAL_RTC_SECONDS_PER_HOUR) / FURI_HAL_RTC_SECONDS_PER_MINUTE; - datetime->second = seconds_in_day % FURI_HAL_RTC_SECONDS_PER_MINUTE; -} - void from_days_to_datetime(uint16_t days, FuriHalRtcDateTime* datetime, uint16_t start_year) { uint32_t timestamp = days * 24 * 60 * 60; FuriHalRtcDateTime start_datetime = {0}; @@ -514,7 +69,7 @@ void from_days_to_datetime(uint16_t days, FuriHalRtcDateTime* datetime, uint16_t start_datetime.month = 12; start_datetime.day = 31; timestamp += furi_hal_rtc_datetime_to_timestamp(&start_datetime); - timestamp_to_datetime(timestamp, datetime); + furi_hal_rtc_timestamp_to_datetime(timestamp, datetime); } void from_minutes_to_datetime(uint32_t minutes, FuriHalRtcDateTime* datetime, uint16_t start_year) { @@ -524,7 +79,7 @@ void from_minutes_to_datetime(uint32_t minutes, FuriHalRtcDateTime* datetime, ui start_datetime.month = 12; start_datetime.day = 31; timestamp += furi_hal_rtc_datetime_to_timestamp(&start_datetime); - timestamp_to_datetime(timestamp, datetime); + furi_hal_rtc_timestamp_to_datetime(timestamp, datetime); } bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { @@ -620,7 +175,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date) * 24 * 60 + card_start_trip_time, + (card_start_trip_date)*24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -697,7 +252,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date) * 24 * 60 + card_start_trip_time, + (card_start_trip_date)*24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -871,7 +426,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { from_days_to_datetime(card_use_before_date, &card_use_before_date_s, 1992); FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date) * 24 * 60 + card_start_trip_time, + (card_start_trip_date)*24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -952,7 +507,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { from_days_to_datetime(card_use_before_date, &card_use_before_date_s, 1992); FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date) * 24 * 60 + card_start_trip_time, + (card_start_trip_date)*24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -1092,7 +647,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_valid_to_date) * 24 * 60 + card_valid_for_minutes - card_start_trip_neg_minutes, + (card_valid_to_date)*24 * 60 + card_valid_for_minutes - card_start_trip_neg_minutes, &card_start_trip_minutes_s, 2016); //-time furi_string_printf( @@ -1509,7 +1064,7 @@ static bool troika_verify_type(Nfc* nfc, MfClassicType type) { FURI_LOG_D(TAG, "Verifying sector %lu", cfg.data_sector); MfClassicKey key = {0}; - nfc_util_num2bytes(cfg.keys[cfg.data_sector].a, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(cfg.keys[cfg.data_sector].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = @@ -1552,9 +1107,9 @@ static bool troika_read(Nfc* nfc, NfcDevice* device) { .key_b_mask = 0, }; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -1590,7 +1145,8 @@ static bool troika_parse(const NfcDevice* device, FuriString* parsed_data) { const MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, cfg.data_sector); - const uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); + const uint64_t key = + bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); if(key != cfg.keys[cfg.data_sector].a) break; FuriString* metro_result = furi_string_alloc(); diff --git a/applications/main/nfc/plugins/supported_cards/two_cities.c b/applications/main/nfc/plugins/supported_cards/two_cities.c index 7e29cd085..93fd55db7 100644 --- a/applications/main/nfc/plugins/supported_cards/two_cities.c +++ b/applications/main/nfc/plugins/supported_cards/two_cities.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include #define TAG "TwoCities" @@ -45,7 +45,7 @@ bool two_cities_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Verifying sector %u", verify_sector); MfClassicKey key = {}; - nfc_util_num2bytes(two_cities_4k_keys[verify_sector].a, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be(two_cities_4k_keys[verify_sector].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_ctx = {}; MfClassicError error = @@ -78,9 +78,11 @@ static bool two_cities_read(Nfc* nfc, NfcDevice* device) { data->type = type; MfClassicDeviceKeys keys = {}; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(two_cities_4k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be( + two_cities_4k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(two_cities_4k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be( + two_cities_4k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -110,7 +112,7 @@ static bool two_cities_parse(const NfcDevice* device, FuriString* parsed_data) { do { // Verify key MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, 4); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, 6); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6); if(key != two_cities_4k_keys[4].a) return false; // ===== diff --git a/applications/main/nfc/plugins/supported_cards/umarsh.c b/applications/main/nfc/plugins/supported_cards/umarsh.c index bf643d21c..959b2eeb0 100644 --- a/applications/main/nfc/plugins/supported_cards/umarsh.c +++ b/applications/main/nfc/plugins/supported_cards/umarsh.c @@ -23,16 +23,12 @@ * along with this program. If not, see . */ -#include "core/core_defines.h" #include "nfc_supported_card_plugin.h" +#include #include "protocols/mf_classic/mf_classic.h" -#include - -#include -#include -#include +#include #include #define TAG "Umarsh" @@ -63,27 +59,27 @@ static bool umarsh_parse(const NfcDevice* device, FuriString* parsed_data) { // Validate specific for Umarsh ticket sector header const uint8_t* block_start_ptr = &data->block[ticket_sector_start_block_number].data[0]; - const uint32_t header_part_0 = nfc_util_bytes2num(block_start_ptr, 4); - const uint32_t header_part_1 = nfc_util_bytes2num(block_start_ptr + 4, 4); + const uint32_t header_part_0 = bit_lib_bytes_to_num_be(block_start_ptr, 4); + const uint32_t header_part_1 = bit_lib_bytes_to_num_be(block_start_ptr + 4, 4); if((header_part_0 + header_part_1) != 0xFFFFFFFF) break; // Data parsing from block 1 block_start_ptr = &data->block[ticket_sector_start_block_number + 1].data[0]; - const uint16_t expiry_date = nfc_util_bytes2num(block_start_ptr + 1, 2); + const uint16_t expiry_date = bit_lib_bytes_to_num_be(block_start_ptr + 1, 2); const uint8_t region_number = (((block_start_ptr[8] >> 5) & 0x07) << 4) | (block_start_ptr[12] & 0x0F); - const uint8_t refill_counter = nfc_util_bytes2num(block_start_ptr + 7, 1); - const uint32_t card_number = nfc_util_bytes2num(block_start_ptr + 8, 4) & 0x3FFFFFFF; + const uint8_t refill_counter = bit_lib_bytes_to_num_be(block_start_ptr + 7, 1); + const uint32_t card_number = bit_lib_bytes_to_num_be(block_start_ptr + 8, 4) & 0x3FFFFFFF; if(card_number == 0) break; // Data parsing from block 2 block_start_ptr = &data->block[ticket_sector_start_block_number + 2].data[0]; - const uint16_t valid_to = nfc_util_bytes2num(block_start_ptr, 2); - const uint32_t terminal_number = nfc_util_bytes2num(block_start_ptr + 3, 3); - const uint16_t last_refill_date = nfc_util_bytes2num(block_start_ptr + 6, 2); - const uint16_t balance_rub = (nfc_util_bytes2num(block_start_ptr + 8, 2)) & 0x7FFF; - const uint8_t balance_kop = nfc_util_bytes2num(block_start_ptr + 10, 1) & 0x7F; + const uint16_t valid_to = bit_lib_bytes_to_num_be(block_start_ptr, 2); + const uint32_t terminal_number = bit_lib_bytes_to_num_be(block_start_ptr + 3, 3); + const uint16_t last_refill_date = bit_lib_bytes_to_num_be(block_start_ptr + 6, 2); + const uint16_t balance_rub = (bit_lib_bytes_to_num_be(block_start_ptr + 8, 2)) & 0x7FFF; + const uint8_t balance_kop = bit_lib_bytes_to_num_be(block_start_ptr + 10, 1) & 0x7F; FuriHalRtcDateTime expiry_datetime; bool is_expiry_datetime_valid = parse_datetime(expiry_date, &expiry_datetime); diff --git a/applications/main/nfc/plugins/supported_cards/washcity.c b/applications/main/nfc/plugins/supported_cards/washcity.c index 874337ec7..e4610fb94 100644 --- a/applications/main/nfc/plugins/supported_cards/washcity.c +++ b/applications/main/nfc/plugins/supported_cards/washcity.c @@ -19,14 +19,12 @@ * along with this program. If not, see . */ #include "nfc_supported_card_plugin.h" +#include -#include "protocols/mf_classic/mf_classic.h" -#include - -#include -#include #include +#include + #define TAG "WashCity" typedef struct { @@ -63,7 +61,8 @@ static bool washcity_verify(Nfc* nfc) { FURI_LOG_D(TAG, "Verifying sector %u", ticket_sector_number); MfClassicKey key = {0}; - nfc_util_num2bytes(washcity_1k_keys[ticket_sector_number].a, COUNT_OF(key.data), key.data); + bit_lib_num_to_bytes_be( + washcity_1k_keys[ticket_sector_number].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = mf_classic_poller_sync_auth( @@ -101,9 +100,11 @@ static bool washcity_read(Nfc* nfc, NfcDevice* device) { .key_b_mask = 0, }; for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { - nfc_util_num2bytes(washcity_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); + bit_lib_num_to_bytes_be( + washcity_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); FURI_BIT_SET(keys.key_a_mask, i); - nfc_util_num2bytes(washcity_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); + bit_lib_num_to_bytes_be( + washcity_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data); FURI_BIT_SET(keys.key_b_mask, i); } @@ -138,7 +139,8 @@ static bool washcity_parse(const NfcDevice* device, FuriString* parsed_data) { const MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, ticket_sector_number); - const uint64_t key = nfc_util_bytes2num(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); + const uint64_t key = + bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); if(key != washcity_1k_keys[ticket_sector_number].a) break; // Parse data @@ -148,7 +150,7 @@ static bool washcity_parse(const NfcDevice* device, FuriString* parsed_data) { const uint8_t* block_start_ptr = &data->block[start_block_num + ticket_block_number].data[0]; - uint32_t balance = nfc_util_bytes2num(block_start_ptr + 2, 2); + uint32_t balance = bit_lib_bytes_to_num_be(block_start_ptr + 2, 2); uint32_t balance_usd = balance / 100; uint8_t balance_cents = balance % 100; @@ -157,7 +159,7 @@ static bool washcity_parse(const NfcDevice* device, FuriString* parsed_data) { const uint8_t* uid = mf_classic_get_uid(data, &uid_len); // Card Number is printed in HEX (equal to UID) - uint64_t card_number = nfc_util_bytes2num(uid, uid_len); + uint64_t card_number = bit_lib_bytes_to_num_be(uid, uid_len); furi_string_printf( parsed_data, diff --git a/applications/main/nfc/plugins/supported_cards/zolotaya_korona.c b/applications/main/nfc/plugins/supported_cards/zolotaya_korona.c index 2965e7e4f..e1aa9abcf 100644 --- a/applications/main/nfc/plugins/supported_cards/zolotaya_korona.c +++ b/applications/main/nfc/plugins/supported_cards/zolotaya_korona.c @@ -18,15 +18,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "furi_hal_rtc.h" #include "nfc_supported_card_plugin.h" +#include #include "protocols/mf_classic/mf_classic.h" -#include -#include -#include -#include +#include +#include #define TAG "Zolotaya Korona" @@ -40,26 +38,6 @@ static const uint8_t info_sector_signature[] = {0xE2, 0x87, 0x80, 0x8E, 0x20, 0x 0xAE, 0xE0, 0xAE, 0xAD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -uint64_t bytes2num_bcd(const uint8_t* src, uint8_t len_bytes, bool* is_bcd) { - furi_assert(src); - furi_assert(len_bytes <= 9); - - uint64_t result = 0; - *is_bcd = true; - - for(uint8_t i = 0; i < len_bytes; i++) { - if(((src[i] / 16) > 9) || ((src[i] % 16) > 9)) *is_bcd = false; - - result *= 10; - result += src[i] / 16; - - result *= 10; - result += src[i] % 16; - } - - return result; -} - static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_data) { furi_assert(device); @@ -90,12 +68,14 @@ static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_da // INFO SECTOR // block 1 - const uint8_t region_number = bytes2num_bcd(block_start_ptr + 10, 1, &verified); + const uint8_t region_number = bit_lib_bytes_to_num_bcd(block_start_ptr + 10, 1, &verified); // block 2 block_start_ptr = &data->block[start_info_block_number + 2].data[4]; - const uint16_t card_number_prefix = bytes2num_bcd(block_start_ptr, 2, &verified); - const uint64_t card_number_postfix = bytes2num_bcd(block_start_ptr + 2, 8, &verified) / 10; + const uint16_t card_number_prefix = + bit_lib_bytes_to_num_bcd(block_start_ptr, 2, &verified); + const uint64_t card_number_postfix = + bit_lib_bytes_to_num_bcd(block_start_ptr + 2, 8, &verified) / 10; // TRIP SECTOR const uint8_t start_trip_block_number = @@ -104,33 +84,29 @@ static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_da block_start_ptr = &data->block[start_trip_block_number].data[7]; const uint8_t status = block_start_ptr[0] % 16; - const uint16_t sequence_number = nfc_util_bytes2num(block_start_ptr + 1, 2); - const uint8_t discount_code = nfc_util_bytes2num(block_start_ptr + 3, 1); + const uint16_t sequence_number = bit_lib_bytes_to_num_be(block_start_ptr + 1, 2); + const uint8_t discount_code = bit_lib_bytes_to_num_be(block_start_ptr + 3, 1); // block 1: refill block block_start_ptr = &data->block[start_trip_block_number + 1].data[1]; - const uint16_t refill_machine_id = nfc_util_bytes2num_little_endian(block_start_ptr, 2); - const uint32_t last_refill_timestamp = - nfc_util_bytes2num_little_endian(block_start_ptr + 2, 4); - const uint32_t last_refill_amount = - nfc_util_bytes2num_little_endian(block_start_ptr + 6, 4); + const uint16_t refill_machine_id = bit_lib_bytes_to_num_le(block_start_ptr, 2); + const uint32_t last_refill_timestamp = bit_lib_bytes_to_num_le(block_start_ptr + 2, 4); + const uint32_t last_refill_amount = bit_lib_bytes_to_num_le(block_start_ptr + 6, 4); const uint32_t last_refill_amount_rub = last_refill_amount / 100; const uint8_t last_refill_amount_kop = last_refill_amount % 100; - const uint16_t refill_counter = nfc_util_bytes2num_little_endian(block_start_ptr + 10, 2); + const uint16_t refill_counter = bit_lib_bytes_to_num_le(block_start_ptr + 10, 2); FuriHalRtcDateTime last_refill_datetime = {0}; furi_hal_rtc_timestamp_to_datetime(last_refill_timestamp, &last_refill_datetime); // block 2: trip block block_start_ptr = &data->block[start_trip_block_number + 2].data[0]; - const char validator_first_letter = - nfc_util_bytes2num_little_endian(block_start_ptr + 1, 1); - const uint32_t validator_id = bytes2num_bcd(block_start_ptr + 2, 3, &verified); - const uint32_t last_trip_timestamp = - nfc_util_bytes2num_little_endian(block_start_ptr + 6, 4); - const uint8_t track_number = nfc_util_bytes2num_little_endian(block_start_ptr + 10, 1); - const uint32_t prev_balance = nfc_util_bytes2num_little_endian(block_start_ptr + 11, 4); + const char validator_first_letter = bit_lib_bytes_to_num_le(block_start_ptr + 1, 1); + const uint32_t validator_id = bit_lib_bytes_to_num_bcd(block_start_ptr + 2, 3, &verified); + const uint32_t last_trip_timestamp = bit_lib_bytes_to_num_le(block_start_ptr + 6, 4); + const uint8_t track_number = bit_lib_bytes_to_num_le(block_start_ptr + 10, 1); + const uint32_t prev_balance = bit_lib_bytes_to_num_le(block_start_ptr + 11, 4); const uint32_t prev_balance_rub = prev_balance / 100; const uint8_t prev_balance_kop = prev_balance % 100; @@ -143,7 +119,7 @@ static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_da block_start_ptr = &data->block[start_purse_block_number].data[0]; // block 0 - const uint32_t balance = nfc_util_bytes2num_little_endian(block_start_ptr, 4); + const uint32_t balance = bit_lib_bytes_to_num_le(block_start_ptr, 4); uint32_t balance_rub = balance / 100; uint8_t balance_kop = balance % 100; diff --git a/applications/main/nfc/plugins/supported_cards/zolotaya_korona_online.c b/applications/main/nfc/plugins/supported_cards/zolotaya_korona_online.c index eb992763e..3dbd509bb 100644 --- a/applications/main/nfc/plugins/supported_cards/zolotaya_korona_online.c +++ b/applications/main/nfc/plugins/supported_cards/zolotaya_korona_online.c @@ -17,41 +17,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "furi_hal_rtc.h" #include "nfc_supported_card_plugin.h" +#include #include "protocols/mf_classic/mf_classic.h" -#include -#include -#include -#include +#include +#include #define TAG "Zolotaya Korona Online" #define TRIP_SECTOR_NUM (4) #define INFO_SECTOR_NUM (15) -uint64_t bytes2num_bcd(const uint8_t* src, uint8_t len_bytes, bool* is_bcd) { - furi_assert(src); - furi_assert(len_bytes <= 9); - - uint64_t result = 0; - *is_bcd = true; - - for(uint8_t i = 0; i < len_bytes; i++) { - if(((src[i] / 16) > 9) || ((src[i] % 16) > 9)) *is_bcd = false; - - result *= 10; - result += src[i] / 16; - - result *= 10; - result += src[i] % 16; - } - - return result; -} - bool parse_online_card_tariff(uint16_t tariff_num, FuriString* tariff_name) { bool tariff_parsed = false; @@ -111,21 +89,22 @@ static bool zolotaya_korona_online_parse(const NfcDevice* device, FuriString* pa // Validate card number bool is_bcd; - const uint16_t card_number_prefix = bytes2num_bcd(block_start_ptr, 2, &is_bcd); + const uint16_t card_number_prefix = bit_lib_bytes_to_num_bcd(block_start_ptr, 2, &is_bcd); if(!is_bcd) break; if(card_number_prefix != 9643) break; - const uint64_t card_number_postfix = bytes2num_bcd(block_start_ptr + 2, 8, &is_bcd) / 10; + const uint64_t card_number_postfix = + bit_lib_bytes_to_num_bcd(block_start_ptr + 2, 8, &is_bcd) / 10; if(!is_bcd) break; // Parse data FuriString* tariff_name = furi_string_alloc(); block_start_ptr = &data->block[start_info_block_number].data[1]; - const uint16_t tariff = nfc_util_bytes2num(block_start_ptr, 2); + const uint16_t tariff = bit_lib_bytes_to_num_be(block_start_ptr, 2); parse_online_card_tariff(tariff, tariff_name); block_start_ptr = &data->block[start_trip_block_number].data[0]; - const uint8_t region_number = nfc_util_bytes2num(block_start_ptr, 1); + const uint8_t region_number = bit_lib_bytes_to_num_be(block_start_ptr, 1); furi_string_cat_printf( parsed_data, diff --git a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c index 1724eea8d..6d04ca420 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c @@ -1,11 +1,12 @@ #include "../nfc_app_i.h" -#include +#include void nfc_scene_slix_key_input_byte_input_callback(void* context) { NfcApp* instance = context; - SlixPassword password = nfc_util_bytes2num(instance->byte_input_store, sizeof(SlixPassword)); + SlixPassword password = + bit_lib_bytes_to_num_be(instance->byte_input_store, sizeof(SlixPassword)); slix_unlock_set_password(instance->slix_unlock, password); view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventByteInputDone); } diff --git a/applications/services/gui/modules/text_box.c b/applications/services/gui/modules/text_box.c index e23fda09f..c0110806a 100644 --- a/applications/services/gui/modules/text_box.c +++ b/applications/services/gui/modules/text_box.c @@ -117,6 +117,10 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { static void text_box_view_draw_callback(Canvas* canvas, void* _model) { TextBoxModel* model = _model; + if(!model->text) { + return; + } + canvas_clear(canvas); if(model->font == TextBoxFontText) { canvas_set_font(canvas, FontSecondary); diff --git a/furi/core/string.c b/furi/core/string.c index 682c8d409..a09ff953f 100644 --- a/furi/core/string.c +++ b/furi/core/string.c @@ -71,7 +71,8 @@ void furi_string_reserve(FuriString* s, size_t alloc) { } void furi_string_reset(FuriString* s) { - string_reset(s->string); + string_clear(s->string); + string_init(s->string); } void furi_string_swap(FuriString* v1, FuriString* v2) { diff --git a/lib/ReadMe.md b/lib/ReadMe.md index 3adb77018..ed0e4ce88 100644 --- a/lib/ReadMe.md +++ b/lib/ReadMe.md @@ -3,6 +3,7 @@ - `FreeRTOS-Kernel` - FreeRTOS kernel source code - `FreeRTOS-glue` - Extra glue to hold together FreeRTOS kernel and flipper firmware - `app-scened-template` - C++ app library +- `bit_lib` - library for working with bits/bytes directly - `callback-connector` - Callback connector library - `cmsis_core` - CMSIS Core package, contain cortex-m core headers - `cxxheaderparser` - C++ headers parser, used by SDK bundler diff --git a/lib/SConscript b/lib/SConscript index 95f55b37d..7bd00e4e4 100644 --- a/lib/SConscript +++ b/lib/SConscript @@ -42,6 +42,7 @@ libs = env.BuildModules( "nanopb", "update_util", "heatshrink", + "bit_lib", ], ) diff --git a/lib/bit_lib/SConscript b/lib/bit_lib/SConscript new file mode 100644 index 000000000..bf77708a1 --- /dev/null +++ b/lib/bit_lib/SConscript @@ -0,0 +1,22 @@ +Import("env") + +env.Append( + LINT_SOURCES=[ + Dir("."), + ], + CPPPATH=[ + "#/lib/bit_lib", + ], + SDK_HEADERS=[ + File("bit_lib.h"), + ], +) + +libenv = env.Clone(FW_LIB_NAME="bit_lib") +libenv.ApplyLibFlags() + +sources = libenv.GlobRecursive("*.c*") + +lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources) +libenv.Install("${LIB_DIST_DIR}", lib) +Return("lib") diff --git a/lib/lfrfid/tools/bit_lib.c b/lib/bit_lib/bit_lib.c similarity index 69% rename from lib/lfrfid/tools/bit_lib.c rename to lib/bit_lib/bit_lib.c index e0d0ff402..e13ca95d4 100644 --- a/lib/lfrfid/tools/bit_lib.c +++ b/lib/bit_lib/bit_lib.c @@ -78,6 +78,57 @@ uint32_t bit_lib_get_bits_32(const uint8_t* data, size_t position, uint8_t lengt return value; } +uint64_t bit_lib_get_bits_64(const uint8_t* data, size_t position, uint8_t length) { + uint64_t value = 0; + if(length <= 8) { + value = bit_lib_get_bits(data, position, length); + } else if(length <= 16) { + value = bit_lib_get_bits(data, position, 8) << (length - 8); + value |= bit_lib_get_bits(data, position + 8, length - 8); + } else if(length <= 24) { + value = bit_lib_get_bits(data, position, 8) << (length - 8); + value |= bit_lib_get_bits(data, position + 8, 8) << (length - 16); + value |= bit_lib_get_bits(data, position + 16, length - 16); + } else if(length <= 32) { + value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); + value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); + value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); + value |= bit_lib_get_bits(data, position + 24, length - 24); + } else if(length <= 40) { + value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); + value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); + value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); + value |= (uint64_t)bit_lib_get_bits(data, position + 24, 8) << (length - 32); + value |= bit_lib_get_bits(data, position + 32, length - 32); + } else if(length <= 48) { + value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); + value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); + value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); + value |= (uint64_t)bit_lib_get_bits(data, position + 24, 8) << (length - 32); + value |= (uint64_t)bit_lib_get_bits(data, position + 32, 8) << (length - 40); + value |= bit_lib_get_bits(data, position + 40, length - 40); + } else if(length <= 56) { + value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); + value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); + value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); + value |= (uint64_t)bit_lib_get_bits(data, position + 24, 8) << (length - 32); + value |= (uint64_t)bit_lib_get_bits(data, position + 32, 8) << (length - 40); + value |= (uint64_t)bit_lib_get_bits(data, position + 40, 8) << (length - 48); + value |= bit_lib_get_bits(data, position + 48, length - 48); + } else { + value = (uint64_t)bit_lib_get_bits(data, position, 8) << (length - 8); + value |= (uint64_t)bit_lib_get_bits(data, position + 8, 8) << (length - 16); + value |= (uint64_t)bit_lib_get_bits(data, position + 16, 8) << (length - 24); + value |= (uint64_t)bit_lib_get_bits(data, position + 24, 8) << (length - 32); + value |= (uint64_t)bit_lib_get_bits(data, position + 32, 8) << (length - 40); + value |= (uint64_t)bit_lib_get_bits(data, position + 40, 8) << (length - 48); + value |= (uint64_t)bit_lib_get_bits(data, position + 48, 8) << (length - 56); + value |= bit_lib_get_bits(data, position + 56, length - 56); + } + + return value; +} + bool bit_lib_test_parity_32(uint32_t bits, BitLibParity parity) { #if !defined __GNUC__ #error Please, implement parity test for non-GCC compilers @@ -365,3 +416,70 @@ uint16_t bit_lib_crc16( return crc; } + +void bit_lib_num_to_bytes_be(uint64_t src, uint8_t len, uint8_t* dest) { + furi_assert(dest); + furi_assert(len <= 8); + + while(len--) { + dest[len] = (uint8_t)src; + src >>= 8; + } +} + +void bit_lib_num_to_bytes_le(uint64_t src, uint8_t len, uint8_t* dest) { + furi_assert(dest); + furi_assert(len <= 8); + + for(int i = 0; i < len; i++) { + dest[i] = (uint8_t)(src >> (8 * i)); + } +} + +uint64_t bit_lib_bytes_to_num_be(const uint8_t* src, uint8_t len) { + furi_assert(src); + furi_assert(len <= 8); + + uint64_t res = 0; + while(len--) { + res = (res << 8) | (*src); + src++; + } + return res; +} + +uint64_t bit_lib_bytes_to_num_le(const uint8_t* src, uint8_t len) { + furi_assert(src); + furi_assert(len <= 8); + + uint64_t res = 0; + uint8_t shift = 0; + while(len--) { + res |= ((uint64_t)*src) << (8 * shift++); + src++; + } + return res; +} + +uint64_t bit_lib_bytes_to_num_bcd(const uint8_t* src, uint8_t len, bool* is_bcd) { + furi_assert(src); + furi_assert(len <= 9); + + uint64_t res = 0; + uint8_t nibble_1, nibble_2; + *is_bcd = true; + + for(uint8_t i = 0; i < len; i++) { + nibble_1 = src[i] / 16; + nibble_2 = src[i] % 16; + if((nibble_1 > 9) || (nibble_2 > 9)) *is_bcd = false; + + res *= 10; + res += nibble_1; + + res *= 10; + res += nibble_2; + } + + return res; +} \ No newline at end of file diff --git a/lib/lfrfid/tools/bit_lib.h b/lib/bit_lib/bit_lib.h similarity index 81% rename from lib/lfrfid/tools/bit_lib.h rename to lib/bit_lib/bit_lib.h index bae95462d..7d23cf063 100644 --- a/lib/lfrfid/tools/bit_lib.h +++ b/lib/bit_lib/bit_lib.h @@ -90,6 +90,15 @@ uint16_t bit_lib_get_bits_16(const uint8_t* data, size_t position, uint8_t lengt */ uint32_t bit_lib_get_bits_32(const uint8_t* data, size_t position, uint8_t length); +/** + * @brief Get the bits of a data, as uint64_t. + * @param data The data to get the bits from. + * @param position The position of the first bit. + * @param length The length of the bits. + * @return The bits. + */ +uint64_t bit_lib_get_bits_64(const uint8_t* data, size_t position, uint8_t length); + /** * @brief Test parity of given bits * @param bits Bits to test parity of @@ -267,6 +276,54 @@ uint16_t bit_lib_crc16( bool ref_out, uint16_t xor_out); +/** + * @brief Convert number to bytes in big endian order + * + * @param src number to convert + * @param len max used bytes count + * @param dest destination + * @return void + */ +void bit_lib_num_to_bytes_be(uint64_t src, uint8_t len, uint8_t* dest); + +/** + * @brief Convert number to bytes in little endian order + * + * @param src number to convert + * @param len max used bytes count + * @param dest destination + * @return void + */ +void bit_lib_num_to_bytes_le(uint64_t src, uint8_t len, uint8_t* dest); + +/** + * @brief Convert bytes to number in big endian order + * + * @param src byte array + * @param len max used bytes count + * @return uint64_t + */ +uint64_t bit_lib_bytes_to_num_be(const uint8_t* src, uint8_t len); + +/** + * @brief Convert bytes to number in little endian order + * + * @param src byte array + * @param len max used bytes count + * @return uint64_t + */ +uint64_t bit_lib_bytes_to_num_le(const uint8_t* src, uint8_t len); + +/** + * @brief Convert bytes in binary-coded decimal encoding to number + * + * @param src byte array + * @param len max used bytes count + * @param is_bcd will be true if all processed bytes is BCD encoded (no A-F nibbles) + * @return uint64_t + */ +uint64_t bit_lib_bytes_to_num_bcd(const uint8_t* src, uint8_t len, bool* is_bcd); + #ifdef __cplusplus } #endif diff --git a/lib/lfrfid/SConscript b/lib/lfrfid/SConscript index f9431ca75..5b2380bd5 100644 --- a/lib/lfrfid/SConscript +++ b/lib/lfrfid/SConscript @@ -12,7 +12,6 @@ env.Append( File("lfrfid_raw_worker.h"), File("lfrfid_raw_file.h"), File("lfrfid_dict_file.h"), - File("tools/bit_lib.h"), File("protocols/lfrfid_protocols.h"), ], ) diff --git a/lib/lfrfid/lfrfid_dict_file.c b/lib/lfrfid/lfrfid_dict_file.c index 18bf505f0..33a3b09db 100644 --- a/lib/lfrfid/lfrfid_dict_file.c +++ b/lib/lfrfid/lfrfid_dict_file.c @@ -1,7 +1,7 @@ #include "lfrfid_dict_file.h" #include #include -#include +#include #define LFRFID_DICT_FILETYPE "Flipper RFID key" diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 17e42ad97..b0ed99096 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -6,7 +6,7 @@ #include #include #include "tools/varint_pair.h" -#include "tools/bit_lib.h" +#include #define TAG "LfRfidWorker" @@ -605,8 +605,7 @@ static void lfrfid_worker_mode_write_and_set_pass_process(LFRFIDWorker* worker) FURI_LOG_D(TAG, "Data write with pass"); LfRfid* app = worker->cb_ctx; - uint32_t pass = (app->password[0] << 24) | (app->password[1] << 16) | - (app->password[2] << 8) | (app->password[3]); + uint32_t pass = bit_lib_bytes_to_num_be(app->password, 4); request->t5577.mask = 0b10000001; for(uint8_t i = 0; i < request->t5577.blocks_to_write; i++) diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 939627723..914f2f01b 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "lfrfid_protocols.h" #define JITTER_TIME (20) diff --git a/lib/lfrfid/protocols/protocol_fdx_a.c b/lib/lfrfid/protocols/protocol_fdx_a.c index 87daa0eb6..667c4f88d 100644 --- a/lib/lfrfid/protocols/protocol_fdx_a.c +++ b/lib/lfrfid/protocols/protocol_fdx_a.c @@ -3,7 +3,7 @@ #include #include #include "lfrfid_protocols.h" -#include +#include #define JITTER_TIME (20) #define MIN_TIME (64 - JITTER_TIME) diff --git a/lib/lfrfid/protocols/protocol_fdx_b.c b/lib/lfrfid/protocols/protocol_fdx_b.c index a3ab56f25..18ccfa702 100644 --- a/lib/lfrfid/protocols/protocol_fdx_b.c +++ b/lib/lfrfid/protocols/protocol_fdx_b.c @@ -2,7 +2,7 @@ #include "toolbox/level_duration.h" #include "protocol_fdx_b.h" #include -#include +#include #include "lfrfid_protocols.h" #include diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c index 4720d3a4d..15bebb90b 100644 --- a/lib/lfrfid/protocols/protocol_gallagher.c +++ b/lib/lfrfid/protocols/protocol_gallagher.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "lfrfid_protocols.h" #define GALLAGHER_CLOCK_PER_BIT (32) diff --git a/lib/lfrfid/protocols/protocol_hid_ex_generic.c b/lib/lfrfid/protocols/protocol_hid_ex_generic.c index 35500ab59..194e15328 100644 --- a/lib/lfrfid/protocols/protocol_hid_ex_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_ex_generic.c @@ -3,7 +3,7 @@ #include #include #include "lfrfid_protocols.h" -#include +#include #define JITTER_TIME (20) #define MIN_TIME (64 - JITTER_TIME) diff --git a/lib/lfrfid/protocols/protocol_hid_generic.c b/lib/lfrfid/protocols/protocol_hid_generic.c index e07021403..e24b5ade7 100644 --- a/lib/lfrfid/protocols/protocol_hid_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_generic.c @@ -3,7 +3,7 @@ #include #include #include "lfrfid_protocols.h" -#include +#include #define JITTER_TIME (20) #define MIN_TIME (64 - JITTER_TIME) diff --git a/lib/lfrfid/protocols/protocol_idteck.c b/lib/lfrfid/protocols/protocol_idteck.c index 033fcd28c..6de8de206 100644 --- a/lib/lfrfid/protocols/protocol_idteck.c +++ b/lib/lfrfid/protocols/protocol_idteck.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "lfrfid_protocols.h" // Example: 4944544B 351FBE4B diff --git a/lib/lfrfid/protocols/protocol_indala26.c b/lib/lfrfid/protocols/protocol_indala26.c index 8319f0a93..7ce83af7f 100644 --- a/lib/lfrfid/protocols/protocol_indala26.c +++ b/lib/lfrfid/protocols/protocol_indala26.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "lfrfid_protocols.h" #define INDALA26_PREAMBLE_BIT_SIZE (33) diff --git a/lib/lfrfid/protocols/protocol_io_prox_xsf.c b/lib/lfrfid/protocols/protocol_io_prox_xsf.c index 713148568..5cdc9064c 100644 --- a/lib/lfrfid/protocols/protocol_io_prox_xsf.c +++ b/lib/lfrfid/protocols/protocol_io_prox_xsf.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "lfrfid_protocols.h" #define JITTER_TIME (20) diff --git a/lib/lfrfid/protocols/protocol_jablotron.c b/lib/lfrfid/protocols/protocol_jablotron.c index d2c7ea79f..467002c7e 100644 --- a/lib/lfrfid/protocols/protocol_jablotron.c +++ b/lib/lfrfid/protocols/protocol_jablotron.c @@ -2,7 +2,7 @@ #include "toolbox/level_duration.h" #include "protocol_jablotron.h" #include -#include +#include #include "lfrfid_protocols.h" #define JABLOTRON_ENCODED_BIT_SIZE (64) diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index f0a12863e..d994229d9 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "lfrfid_protocols.h" #define KERI_PREAMBLE_BIT_SIZE (33) diff --git a/lib/lfrfid/protocols/protocol_nexwatch.c b/lib/lfrfid/protocols/protocol_nexwatch.c index 3bbbb42f5..938ef273d 100644 --- a/lib/lfrfid/protocols/protocol_nexwatch.c +++ b/lib/lfrfid/protocols/protocol_nexwatch.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "lfrfid_protocols.h" #define NEXWATCH_PREAMBLE_BIT_SIZE (8) diff --git a/lib/lfrfid/protocols/protocol_pac_stanley.c b/lib/lfrfid/protocols/protocol_pac_stanley.c index 11c642402..dc9eaaf49 100644 --- a/lib/lfrfid/protocols/protocol_pac_stanley.c +++ b/lib/lfrfid/protocols/protocol_pac_stanley.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "lfrfid_protocols.h" #define PAC_STANLEY_ENCODED_BIT_SIZE (128) diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c index 26c9b55dc..b716acf7a 100644 --- a/lib/lfrfid/protocols/protocol_paradox.c +++ b/lib/lfrfid/protocols/protocol_paradox.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "lfrfid_protocols.h" #define JITTER_TIME (20) diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index d794bb46e..f0a506eb3 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -3,7 +3,7 @@ #include #include #include "lfrfid_protocols.h" -#include +#include #define JITTER_TIME (20) #define MIN_TIME (64 - JITTER_TIME) diff --git a/lib/lfrfid/protocols/protocol_viking.c b/lib/lfrfid/protocols/protocol_viking.c index 8083f6d91..f5697012a 100644 --- a/lib/lfrfid/protocols/protocol_viking.c +++ b/lib/lfrfid/protocols/protocol_viking.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "lfrfid_protocols.h" #define VIKING_CLOCK_PER_BIT (32) diff --git a/lib/nfc/helpers/nfc_util.c b/lib/nfc/helpers/nfc_util.c index b7a9f5ec9..7bbc9d621 100644 --- a/lib/nfc/helpers/nfc_util.c +++ b/lib/nfc/helpers/nfc_util.c @@ -13,41 +13,6 @@ static const uint8_t nfc_util_odd_byte_parity[256] = { 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1}; -void nfc_util_num2bytes(uint64_t src, uint8_t len, uint8_t* dest) { - furi_assert(dest); - furi_assert(len <= 8); - - while(len--) { - dest[len] = (uint8_t)src; - src >>= 8; - } -} - -uint64_t nfc_util_bytes2num(const uint8_t* src, uint8_t len) { - furi_assert(src); - furi_assert(len <= 8); - - uint64_t res = 0; - while(len--) { - res = (res << 8) | (*src); - src++; - } - return res; -} - -uint64_t nfc_util_bytes2num_little_endian(const uint8_t* src, uint8_t len) { - furi_assert(src); - furi_assert(len <= 8); - - uint64_t res = 0; - uint8_t shift = 0; - while(len--) { - res |= ((uint64_t)*src) << (8 * shift++); - src++; - } - return res; -} - uint8_t nfc_util_even_parity32(uint32_t data) { // data ^= data >> 16; // data ^= data >> 8; diff --git a/lib/nfc/helpers/nfc_util.h b/lib/nfc/helpers/nfc_util.h index 39eb40171..f8e86d865 100644 --- a/lib/nfc/helpers/nfc_util.h +++ b/lib/nfc/helpers/nfc_util.h @@ -6,12 +6,6 @@ extern "C" { #endif -void nfc_util_num2bytes(uint64_t src, uint8_t len, uint8_t* dest); - -uint64_t nfc_util_bytes2num(const uint8_t* src, uint8_t len); - -uint64_t nfc_util_bytes2num_little_endian(const uint8_t* src, uint8_t len); - uint8_t nfc_util_even_parity32(uint32_t data); uint8_t nfc_util_odd_parity8(uint8_t data); diff --git a/lib/nfc/protocols/mf_classic/crypto1.c b/lib/nfc/protocols/mf_classic/crypto1.c index 0758b05fb..e06eae370 100644 --- a/lib/nfc/protocols/mf_classic/crypto1.c +++ b/lib/nfc/protocols/mf_classic/crypto1.c @@ -1,6 +1,7 @@ #include "crypto1.h" #include +#include #include // Algorithm from https://github.com/RfidResearchGroup/proxmark3.git @@ -151,7 +152,7 @@ void crypto1_encrypt_reader_nonce( furi_assert(out); bit_buffer_set_size_bytes(out, 8); - uint32_t nt_num = nfc_util_bytes2num(nt, sizeof(uint32_t)); + uint32_t nt_num = bit_lib_bytes_to_num_be(nt, sizeof(uint32_t)); crypto1_init(crypto, key); if(is_nested) { diff --git a/lib/nfc/protocols/mf_classic/mf_classic.c b/lib/nfc/protocols/mf_classic/mf_classic.c index 27236df4b..361c53c3d 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic.c +++ b/lib/nfc/protocols/mf_classic/mf_classic.c @@ -3,7 +3,7 @@ #include #include -#include +#include #define MF_CLASSIC_PROTOCOL_NAME "Mifare Classic" @@ -121,7 +121,8 @@ static void mf_classic_parse_block(FuriString* block_str, MfClassicData* data, u // Load Key A // Key A mask 0b0000000000111111 = 0x003f if((block_unknown_bytes_mask & 0x003f) == 0) { - uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_a.data, sizeof(MfClassicKey)); + uint64_t key = + bit_lib_bytes_to_num_be(sec_tr_tmp->key_a.data, sizeof(MfClassicKey)); mf_classic_set_key_found(data, sector_num, MfClassicKeyTypeA, key); } // Load Access Bits @@ -132,7 +133,8 @@ static void mf_classic_parse_block(FuriString* block_str, MfClassicData* data, u // Load Key B // Key B mask 0b1111110000000000 = 0xfc00 if((block_unknown_bytes_mask & 0xfc00) == 0) { - uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_b.data, sizeof(MfClassicKey)); + uint64_t key = + bit_lib_bytes_to_num_be(sec_tr_tmp->key_b.data, sizeof(MfClassicKey)); mf_classic_set_key_found(data, sector_num, MfClassicKeyTypeB, key); } } else { @@ -493,7 +495,7 @@ void mf_classic_set_key_found( uint8_t key_arr[6] = {}; MfClassicSectorTrailer* sec_trailer = mf_classic_get_sector_trailer_by_sector(data, sector_num); - nfc_util_num2bytes(key, 6, key_arr); + bit_lib_num_to_bytes_be(key, 6, key_arr); if(key_type == MfClassicKeyTypeA) { memcpy(sec_trailer->key_a.data, key_arr, sizeof(MfClassicKey)); FURI_BIT_SET(data->key_a_mask, sector_num); diff --git a/lib/nfc/protocols/mf_classic/mf_classic_listener.c b/lib/nfc/protocols/mf_classic/mf_classic_listener.c index 9f6f1f85c..7e4f4725b 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_listener.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_listener.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -68,14 +68,15 @@ static MfClassicListenerCommand mf_classic_listener_auth_first_part_handler( MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(instance->data, sector_num); MfClassicKey* key = (key_type == MfClassicKeyTypeA) ? &sec_tr->key_a : &sec_tr->key_b; - uint64_t key_num = nfc_util_bytes2num(key->data, sizeof(MfClassicKey)); + uint64_t key_num = bit_lib_bytes_to_num_be(key->data, sizeof(MfClassicKey)); uint32_t cuid = iso14443_3a_get_cuid(instance->data->iso14443_3a_data); instance->auth_context.key_type = key_type; instance->auth_context.block_num = block_num; furi_hal_random_fill_buf(instance->auth_context.nt.data, sizeof(MfClassicNt)); - uint32_t nt_num = nfc_util_bytes2num(instance->auth_context.nt.data, sizeof(MfClassicNt)); + uint32_t nt_num = + bit_lib_bytes_to_num_be(instance->auth_context.nt.data, sizeof(MfClassicNt)); crypto1_init(instance->crypto, key_num); if(instance->comm_state == MfClassicListenerCommStatePlain) { @@ -88,7 +89,7 @@ static MfClassicListenerCommand mf_classic_listener_auth_first_part_handler( command = MfClassicListenerCommandProcessed; } else { uint8_t key_stream[4] = {}; - nfc_util_num2bytes(nt_num ^ cuid, sizeof(uint32_t), key_stream); + bit_lib_num_to_bytes_be(nt_num ^ cuid, sizeof(uint32_t), key_stream); bit_buffer_copy_bytes( instance->tx_plain_buffer, instance->auth_context.nt.data, sizeof(MfClassicNt)); crypto1_encrypt( @@ -147,11 +148,14 @@ static MfClassicListenerCommand instance->callback(instance->generic_event, instance->context); } - uint32_t nr_num = nfc_util_bytes2num(instance->auth_context.nr.data, sizeof(MfClassicNr)); - uint32_t ar_num = nfc_util_bytes2num(instance->auth_context.ar.data, sizeof(MfClassicAr)); + uint32_t nr_num = + bit_lib_bytes_to_num_be(instance->auth_context.nr.data, sizeof(MfClassicNr)); + uint32_t ar_num = + bit_lib_bytes_to_num_be(instance->auth_context.ar.data, sizeof(MfClassicAr)); crypto1_word(instance->crypto, nr_num, 1); - uint32_t nt_num = nfc_util_bytes2num(instance->auth_context.nt.data, sizeof(MfClassicNt)); + uint32_t nt_num = + bit_lib_bytes_to_num_be(instance->auth_context.nt.data, sizeof(MfClassicNt)); uint32_t secret_poller = ar_num ^ crypto1_word(instance->crypto, 0, 0); if(secret_poller != prng_successor(nt_num, 64)) { FURI_LOG_T( @@ -161,7 +165,7 @@ static MfClassicListenerCommand } uint32_t at_num = prng_successor(nt_num, 96); - nfc_util_num2bytes(at_num, sizeof(uint32_t), instance->auth_context.at.data); + bit_lib_num_to_bytes_be(at_num, sizeof(uint32_t), instance->auth_context.at.data); bit_buffer_copy_bytes( instance->tx_plain_buffer, instance->auth_context.at.data, sizeof(MfClassicAr)); crypto1_encrypt( diff --git a/lib/nfc/protocols/mf_classic/mf_classic_poller.c b/lib/nfc/protocols/mf_classic/mf_classic_poller.c index d846bba69..8c50230ca 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_poller.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_poller.c @@ -73,7 +73,7 @@ static void mf_classic_poller_check_key_b_is_readable( break; MfClassicSectorTrailer* sec_tr = (MfClassicSectorTrailer*)data; - uint64_t key_b = nfc_util_bytes2num(sec_tr->key_b.data, sizeof(MfClassicKey)); + uint64_t key_b = bit_lib_bytes_to_num_be(sec_tr->key_b.data, sizeof(MfClassicKey)); uint8_t sector_num = mf_classic_get_sector_by_block(block_num); mf_classic_set_key_found(instance->data, sector_num, MfClassicKeyTypeB, key_b); } while(false); @@ -456,7 +456,7 @@ NfcCommand mf_classic_poller_handler_request_read_sector_blocks(MfClassicPoller* MfClassicError error = MfClassicErrorNone; if(!sec_read_ctx->auth_passed) { - uint64_t key = nfc_util_bytes2num(sec_read_ctx->key.data, sizeof(MfClassicKey)); + uint64_t key = bit_lib_bytes_to_num_be(sec_read_ctx->key.data, sizeof(MfClassicKey)); FURI_LOG_D( TAG, "Auth to block %d with key %c: %06llx", @@ -530,7 +530,8 @@ NfcCommand mf_classic_poller_handler_auth_a(MfClassicPoller* instance) { instance->state = MfClassicPollerStateAuthKeyB; } else { uint8_t block = mf_classic_get_first_block_num_of_sector(dict_attack_ctx->current_sector); - uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); + uint64_t key = + bit_lib_bytes_to_num_be(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); FURI_LOG_D(TAG, "Auth to block %d with key A: %06llx", block, key); MfClassicError error = mf_classic_poller_auth( @@ -568,7 +569,8 @@ NfcCommand mf_classic_poller_handler_auth_b(MfClassicPoller* instance) { } } else { uint8_t block = mf_classic_get_first_block_num_of_sector(dict_attack_ctx->current_sector); - uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); + uint64_t key = + bit_lib_bytes_to_num_be(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); FURI_LOG_D(TAG, "Auth to block %d with key B: %06llx", block, key); MfClassicError error = mf_classic_poller_auth( @@ -711,7 +713,8 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_a(MfClassicPoller* insta } else { uint8_t block = mf_classic_get_first_block_num_of_sector(dict_attack_ctx->reuse_key_sector); - uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); + uint64_t key = + bit_lib_bytes_to_num_be(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); FURI_LOG_D(TAG, "Key attack auth to block %d with key A: %06llx", block, key); MfClassicError error = mf_classic_poller_auth( @@ -746,7 +749,8 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_b(MfClassicPoller* insta } else { uint8_t block = mf_classic_get_first_block_num_of_sector(dict_attack_ctx->reuse_key_sector); - uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); + uint64_t key = + bit_lib_bytes_to_num_be(dict_attack_ctx->current_key.data, sizeof(MfClassicKey)); FURI_LOG_D(TAG, "Key attack auth to block %d with key B: %06llx", block, key); MfClassicError error = mf_classic_poller_auth( diff --git a/lib/nfc/protocols/mf_classic/mf_classic_poller_i.c b/lib/nfc/protocols/mf_classic/mf_classic_poller_i.c index 16bfb3f72..3f8b93482 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_poller_i.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_poller_i.c @@ -128,7 +128,7 @@ static MfClassicError mf_classic_poller_auth_common( } uint32_t cuid = iso14443_3a_get_cuid(instance->data->iso14443_3a_data); - uint64_t key_num = nfc_util_bytes2num(key->data, sizeof(MfClassicKey)); + uint64_t key_num = bit_lib_bytes_to_num_be(key->data, sizeof(MfClassicKey)); MfClassicNr nr = {}; furi_hal_random_fill_buf(nr.data, sizeof(MfClassicNr)); diff --git a/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h b/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h index 0be42196f..a5af31530 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h +++ b/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h @@ -2,7 +2,7 @@ #include "mf_classic_poller.h" #include -#include +#include #include "crypto1.h" #ifdef __cplusplus diff --git a/lib/nfc/protocols/mf_ultralight/mf_ultralight.c b/lib/nfc/protocols/mf_ultralight/mf_ultralight.c index 3cffa56ff..d4c5ba103 100644 --- a/lib/nfc/protocols/mf_ultralight/mf_ultralight.c +++ b/lib/nfc/protocols/mf_ultralight/mf_ultralight.c @@ -1,6 +1,6 @@ #include "mf_ultralight.h" -#include +#include #include #define MF_ULTRALIGHT_PROTOCOL_NAME "NTAG/Ultralight" @@ -603,10 +603,10 @@ bool mf_ultralight_is_all_data_read(const MfUltralightData* data) { } else { MfUltralightConfigPages* config = NULL; if(mf_ultralight_get_config_page(data, &config)) { - uint32_t pass = - nfc_util_bytes2num(config->password.data, sizeof(MfUltralightAuthPassword)); + uint32_t pass = bit_lib_bytes_to_num_be( + config->password.data, sizeof(MfUltralightAuthPassword)); uint16_t pack = - nfc_util_bytes2num(config->pack.data, sizeof(MfUltralightAuthPack)); + bit_lib_bytes_to_num_be(config->pack.data, sizeof(MfUltralightAuthPack)); all_read = ((pass != 0) || (pack != 0)); } } diff --git a/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c b/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c index f7f814270..0c7f9f803 100644 --- a/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c +++ b/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c @@ -417,7 +417,7 @@ static NfcCommand mf_ultralight_poller_handler_auth(MfUltralightPoller* instance command = instance->callback(instance->general_event, instance->context); if(!instance->mfu_event.data->auth_context.skip_auth) { instance->auth_context.password = instance->mfu_event.data->auth_context.password; - uint32_t pass = nfc_util_bytes2num( + uint32_t pass = bit_lib_bytes_to_num_be( instance->auth_context.password.data, sizeof(MfUltralightAuthPassword)); FURI_LOG_D(TAG, "Trying to authenticate with password %08lX", pass); instance->error = mf_ultralight_poller_auth_pwd(instance, &instance->auth_context); @@ -497,14 +497,14 @@ static NfcCommand mf_ultralight_poller_handler_try_default_pass(MfUltralightPoll config->pack = instance->auth_context.pack; } else if(config->access.authlim == 0) { FURI_LOG_D(TAG, "No limits in authentication. Trying default password"); - nfc_util_num2bytes( + bit_lib_num_to_bytes_be( MF_ULTRALIGHT_DEFAULT_PASSWORD, sizeof(MfUltralightAuthPassword), instance->auth_context.password.data); instance->error = mf_ultralight_poller_auth_pwd(instance, &instance->auth_context); if(instance->error == MfUltralightErrorNone) { FURI_LOG_D(TAG, "Default password detected"); - nfc_util_num2bytes( + bit_lib_num_to_bytes_be( MF_ULTRALIGHT_DEFAULT_PASSWORD, sizeof(MfUltralightAuthPassword), config->password.data); diff --git a/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller_i.h b/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller_i.h index 7c7354b1c..3f8645fe7 100644 --- a/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller_i.h +++ b/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller_i.h @@ -2,7 +2,7 @@ #include "mf_ultralight_poller.h" #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/lib/nfc/protocols/slix/slix_poller_i.c b/lib/nfc/protocols/slix/slix_poller_i.c index 5000efceb..9b0b5ec55 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.c +++ b/lib/nfc/protocols/slix/slix_poller_i.c @@ -1,5 +1,5 @@ #include "slix_poller_i.h" -#include +#include #include @@ -107,7 +107,7 @@ SlixError uint32_t double_rand_num = (rn_h << 24) | (rn_l << 16) | (rn_h << 8) | rn_l; uint32_t xored_password = double_rand_num ^ password; uint8_t xored_password_arr[4] = {}; - nfc_util_num2bytes(xored_password, 4, xored_password_arr); + bit_lib_num_to_bytes_be(xored_password, 4, xored_password_arr); bit_buffer_append_bytes(instance->tx_buffer, xored_password_arr, 4); SlixError error = SlixErrorNone; diff --git a/scripts/toolchain/fbtenv.cmd b/scripts/toolchain/fbtenv.cmd index 186cbf28a..446f04aa7 100644 --- a/scripts/toolchain/fbtenv.cmd +++ b/scripts/toolchain/fbtenv.cmd @@ -24,17 +24,17 @@ set "FBT_TOOLCHAIN_ROOT=%FBT_TOOLCHAIN_PATH%\toolchain\x86_64-windows" set "FBT_TOOLCHAIN_VERSION_FILE=%FBT_TOOLCHAIN_ROOT%\VERSION" if not exist "%FBT_TOOLCHAIN_ROOT%" ( - powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" || exit /b ) if not exist "%FBT_TOOLCHAIN_VERSION_FILE%" ( - powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" || exit /b ) set /p REAL_TOOLCHAIN_VERSION=<"%FBT_TOOLCHAIN_VERSION_FILE%" if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" ( echo FBT: starting toolchain upgrade process.. - powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" %flipper_toolchain_version% "%FBT_TOOLCHAIN_ROOT%" || exit /b set /p REAL_TOOLCHAIN_VERSION=<"%FBT_TOOLCHAIN_VERSION_FILE%" ) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index 73bae42c4..ef7549c87 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -208,9 +208,12 @@ fbtenv_show_unpack_percentage() fbtenv_unpack_toolchain() { echo "Unpacking toolchain to '$FBT_TOOLCHAIN_PATH/toolchain':"; + rm $FBT_TOOLCHAIN_PATH/toolchain/current || true; tar -xvf "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_TAR" -C "$FBT_TOOLCHAIN_PATH/toolchain" 2>&1 | fbtenv_show_unpack_percentage; mkdir -p "$FBT_TOOLCHAIN_PATH/toolchain" || return 1; mv "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_DIR" "$TOOLCHAIN_ARCH_DIR" || return 1; + printf "linking toolchain to 'current'.."; + ln -s "$TOOLCHAIN_ARCH_DIR" "$FBT_TOOLCHAIN_PATH/toolchain/current" || return 1; echo "done"; return 0; } diff --git a/scripts/toolchain/windows-toolchain-download.ps1 b/scripts/toolchain/windows-toolchain-download.ps1 index 9a4d2e18f..11d8a564d 100644 --- a/scripts/toolchain/windows-toolchain-download.ps1 +++ b/scripts/toolchain/windows-toolchain-download.ps1 @@ -18,6 +18,13 @@ if (Test-Path -LiteralPath "$toolchain_target_path") { Remove-Item -LiteralPath "$toolchain_target_path" -Force -Recurse Write-Host "done!" } + +if (Test-path -Path "$toolchain_target_path\..\current") { + Write-Host -NoNewline "Unlinking 'current'.." + Remove-Item -LiteralPath "$toolchain_target_path\..\current" -Force + Write-Host "done!" +} + if (!(Test-Path -Path "$toolchain_zip_temp_path" -PathType Leaf)) { Write-Host -NoNewline "Downloading Windows toolchain.." $wc = New-Object net.webclient @@ -42,6 +49,8 @@ Add-Type -Assembly "System.IO.Compression.Filesystem" Write-Host -NoNewline "moving.." Move-Item -LiteralPath "$toolchain_dist_temp_path" -Destination "$toolchain_target_path" -Force +Write-Host -NoNewline "linking to 'current'.." +cmd /c mklink /J "$toolchain_target_path\..\current" "$toolchain_target_path" Write-Host "done!" Write-Host -NoNewline "Cleaning up temporary files.." diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 2d1ad0883..2a941c9d0 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,55.2,, +Version,+,56.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -37,6 +37,7 @@ Header,+,applications/services/notification/notification_messages.h,, Header,+,applications/services/power/power_service/power.h,, Header,+,applications/services/rpc/rpc_app.h,, Header,+,applications/services/storage/storage.h,, +Header,+,lib/bit_lib/bit_lib.h,, Header,+,lib/digital_signal/digital_sequence.h,, Header,+,lib/digital_signal/digital_signal.h,, Header,+,lib/drivers/cc1101_regs.h,, @@ -574,6 +575,32 @@ Function,+,bit_buffer_starts_with_byte,_Bool,"const BitBuffer*, uint8_t" Function,+,bit_buffer_write_bytes,void,"const BitBuffer*, void*, size_t" Function,+,bit_buffer_write_bytes_mid,void,"const BitBuffer*, void*, size_t, size_t" Function,+,bit_buffer_write_bytes_with_parity,void,"const BitBuffer*, void*, size_t, size_t*" +Function,+,bit_lib_add_parity,size_t,"const uint8_t*, size_t, uint8_t*, size_t, uint8_t, uint8_t, BitLibParity" +Function,+,bit_lib_bytes_to_num_bcd,uint64_t,"const uint8_t*, uint8_t, _Bool*" +Function,+,bit_lib_bytes_to_num_be,uint64_t,"const uint8_t*, uint8_t" +Function,+,bit_lib_bytes_to_num_le,uint64_t,"const uint8_t*, uint8_t" +Function,+,bit_lib_copy_bits,void,"uint8_t*, size_t, size_t, const uint8_t*, size_t" +Function,+,bit_lib_crc16,uint16_t,"const uint8_t*, size_t, uint16_t, uint16_t, _Bool, _Bool, uint16_t" +Function,+,bit_lib_crc8,uint16_t,"const uint8_t*, size_t, uint8_t, uint8_t, _Bool, _Bool, uint8_t" +Function,+,bit_lib_get_bit,_Bool,"const uint8_t*, size_t" +Function,+,bit_lib_get_bit_count,uint8_t,uint32_t +Function,+,bit_lib_get_bits,uint8_t,"const uint8_t*, size_t, uint8_t" +Function,+,bit_lib_get_bits_16,uint16_t,"const uint8_t*, size_t, uint8_t" +Function,+,bit_lib_get_bits_32,uint32_t,"const uint8_t*, size_t, uint8_t" +Function,+,bit_lib_get_bits_64,uint64_t,"const uint8_t*, size_t, uint8_t" +Function,+,bit_lib_num_to_bytes_be,void,"uint64_t, uint8_t, uint8_t*" +Function,+,bit_lib_num_to_bytes_le,void,"uint64_t, uint8_t, uint8_t*" +Function,+,bit_lib_print_bits,void,"const uint8_t*, size_t" +Function,+,bit_lib_print_regions,void,"const BitLibRegion*, size_t, const uint8_t*, size_t" +Function,+,bit_lib_push_bit,void,"uint8_t*, size_t, _Bool" +Function,+,bit_lib_remove_bit_every_nth,size_t,"uint8_t*, size_t, uint8_t, uint8_t" +Function,+,bit_lib_reverse_16_fast,uint16_t,uint16_t +Function,+,bit_lib_reverse_8_fast,uint8_t,uint8_t +Function,+,bit_lib_reverse_bits,void,"uint8_t*, size_t, uint8_t" +Function,+,bit_lib_set_bit,void,"uint8_t*, size_t, _Bool" +Function,+,bit_lib_set_bits,void,"uint8_t*, size_t, uint8_t, uint8_t" +Function,+,bit_lib_test_parity,_Bool,"const uint8_t*, size_t, uint8_t, BitLibParity, uint8_t" +Function,+,bit_lib_test_parity_32,_Bool,"uint32_t, BitLibParity" Function,+,ble_app_get_key_storage_buff,void,"uint8_t**, uint16_t*" Function,+,ble_app_init,_Bool, Function,+,ble_app_thread_stop,void, diff --git a/targets/f18/target.json b/targets/f18/target.json index 7345fceec..a8669f552 100644 --- a/targets/f18/target.json +++ b/targets/f18/target.json @@ -36,7 +36,8 @@ "update_util", "heatshrink", "flipperformat", - "flipper18" + "flipper18", + "bit_lib" ], "excluded_sources": [ "furi_hal_infrared.c", diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index d2a955f92..84bae90ab 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,55.2,, +Version,+,56.0,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -38,6 +38,7 @@ Header,+,applications/services/notification/notification_messages.h,, Header,+,applications/services/power/power_service/power.h,, Header,+,applications/services/rpc/rpc_app.h,, Header,+,applications/services/storage/storage.h,, +Header,+,lib/bit_lib/bit_lib.h,, Header,+,lib/digital_signal/digital_sequence.h,, Header,+,lib/digital_signal/digital_signal.h,, Header,+,lib/drivers/cc1101_regs.h,, @@ -62,7 +63,6 @@ Header,+,lib/lfrfid/lfrfid_raw_file.h,, Header,+,lib/lfrfid/lfrfid_raw_worker.h,, Header,+,lib/lfrfid/lfrfid_worker.h,, Header,+,lib/lfrfid/protocols/lfrfid_protocols.h,, -Header,+,lib/lfrfid/tools/bit_lib.h,, Header,+,lib/libusb_stm32/inc/hid_usage_button.h,, Header,+,lib/libusb_stm32/inc/hid_usage_consumer.h,, Header,+,lib/libusb_stm32/inc/hid_usage_desktop.h,, @@ -648,6 +648,9 @@ Function,+,bit_buffer_write_bytes,void,"const BitBuffer*, void*, size_t" Function,+,bit_buffer_write_bytes_mid,void,"const BitBuffer*, void*, size_t, size_t" Function,+,bit_buffer_write_bytes_with_parity,void,"const BitBuffer*, void*, size_t, size_t*" Function,+,bit_lib_add_parity,size_t,"const uint8_t*, size_t, uint8_t*, size_t, uint8_t, uint8_t, BitLibParity" +Function,+,bit_lib_bytes_to_num_bcd,uint64_t,"const uint8_t*, uint8_t, _Bool*" +Function,+,bit_lib_bytes_to_num_be,uint64_t,"const uint8_t*, uint8_t" +Function,+,bit_lib_bytes_to_num_le,uint64_t,"const uint8_t*, uint8_t" Function,+,bit_lib_copy_bits,void,"uint8_t*, size_t, size_t, const uint8_t*, size_t" Function,+,bit_lib_crc16,uint16_t,"const uint8_t*, size_t, uint16_t, uint16_t, _Bool, _Bool, uint16_t" Function,+,bit_lib_crc8,uint16_t,"const uint8_t*, size_t, uint8_t, uint8_t, _Bool, _Bool, uint8_t" @@ -656,6 +659,9 @@ Function,+,bit_lib_get_bit_count,uint8_t,uint32_t Function,+,bit_lib_get_bits,uint8_t,"const uint8_t*, size_t, uint8_t" Function,+,bit_lib_get_bits_16,uint16_t,"const uint8_t*, size_t, uint8_t" Function,+,bit_lib_get_bits_32,uint32_t,"const uint8_t*, size_t, uint8_t" +Function,+,bit_lib_get_bits_64,uint64_t,"const uint8_t*, size_t, uint8_t" +Function,+,bit_lib_num_to_bytes_be,void,"uint64_t, uint8_t, uint8_t*" +Function,+,bit_lib_num_to_bytes_le,void,"uint64_t, uint8_t, uint8_t*" Function,+,bit_lib_print_bits,void,"const uint8_t*, size_t" Function,+,bit_lib_print_regions,void,"const BitLibRegion*, size_t, const uint8_t*, size_t" Function,+,bit_lib_push_bit,void,"uint8_t*, size_t, _Bool" @@ -2672,10 +2678,7 @@ Function,+,nfc_set_guard_time_us,void,"Nfc*, uint32_t" Function,+,nfc_set_mask_receive_time_fc,void,"Nfc*, uint32_t" Function,+,nfc_start,void,"Nfc*, NfcEventCallback, void*" Function,+,nfc_stop,void,Nfc* -Function,+,nfc_util_bytes2num,uint64_t,"const uint8_t*, uint8_t" -Function,+,nfc_util_bytes2num_little_endian,uint64_t,"const uint8_t*, uint8_t" Function,+,nfc_util_even_parity32,uint8_t,uint32_t -Function,+,nfc_util_num2bytes,void,"uint64_t, uint8_t, uint8_t*" Function,+,nfc_util_odd_parity,void,"const uint8_t*, uint8_t*, uint8_t" Function,+,nfc_util_odd_parity8,uint8_t,uint8_t Function,+,notification_internal_message,void,"NotificationApp*, const NotificationSequence*" diff --git a/targets/f7/target.json b/targets/f7/target.json index 140900269..d63caf90a 100644 --- a/targets/f7/target.json +++ b/targets/f7/target.json @@ -48,6 +48,7 @@ "update_util", "heatshrink", "flipperformat", - "flipper7" + "flipper7", + "bit_lib" ] } \ No newline at end of file