From c6a14e1a6779ded87b848b06b2cbc51a147f96b3 Mon Sep 17 00:00:00 2001 From: pborsutzki Date: Sat, 2 Dec 2023 08:27:58 +0100 Subject: [PATCH 1/5] Fixed a zero allocation error when reading an iso15693 nfc tag with no additional blocks. (#3229) Co-authored-by: gornekich --- .../iso15693_3/iso15693_3_poller_i.c | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c index 917f7dbb8..ca6f5435e 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c @@ -108,28 +108,30 @@ Iso15693_3Error iso15693_3_poller_activate(Iso15693_3Poller* instance, Iso15693_ break; } - // Read blocks: Optional command - simple_array_init(data->block_data, system_info->block_count * system_info->block_size); - ret = iso15693_3_poller_read_blocks( - instance, - simple_array_get_data(data->block_data), - system_info->block_count, - system_info->block_size); - if(ret != Iso15693_3ErrorNone) { - ret = iso15693_3_poller_filter_error(ret); - break; + if(system_info->block_count > 0) { + // Read blocks: Optional command + simple_array_init( + data->block_data, system_info->block_count * system_info->block_size); + ret = iso15693_3_poller_read_blocks( + instance, + simple_array_get_data(data->block_data), + system_info->block_count, + system_info->block_size); + if(ret != Iso15693_3ErrorNone) { + ret = iso15693_3_poller_filter_error(ret); + break; + } + + // Get block security status: Optional command + simple_array_init(data->block_security, system_info->block_count); + + ret = iso15693_3_poller_get_blocks_security( + instance, simple_array_get_data(data->block_security), system_info->block_count); + if(ret != Iso15693_3ErrorNone) { + ret = iso15693_3_poller_filter_error(ret); + break; + } } - - // Get block security status: Optional command - simple_array_init(data->block_security, system_info->block_count); - - ret = iso15693_3_poller_get_blocks_security( - instance, simple_array_get_data(data->block_security), system_info->block_count); - if(ret != Iso15693_3ErrorNone) { - ret = iso15693_3_poller_filter_error(ret); - break; - } - } while(false); return ret; From eb6fe0a4dbe2e6d3776483e6a191de2307b0060e Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Sat, 2 Dec 2023 11:34:02 +0400 Subject: [PATCH 2/5] SubGhz: fix count bit for detect gate_tx protocol (#3253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/subghz/protocols/gate_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 51a424fed..2ebd6bb03 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -227,7 +227,7 @@ void subghz_protocol_decoder_gate_tx_feed(void* context, bool level, uint32_t du if(duration >= ((uint32_t)subghz_protocol_gate_tx_const.te_short * 10 + subghz_protocol_gate_tx_const.te_delta)) { instance->decoder.parser_step = GateTXDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_gate_tx_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; From ec99b70b38319065a4d6bb39663ab1bca64b2074 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 2 Dec 2023 23:55:05 +0300 Subject: [PATCH 3/5] upd changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d16d3a7cf..2dd99b183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,11 +19,15 @@ * SubGHz: Fixed feature naming in menu * SubGHz: Added honeywell protocol [(by @htotoo)](https://github.com/Flipper-XFW/Xtreme-Firmware/commit/ceee551befa0cb8fd8514a4f8a1250fd9e0997ee) * SubGHz: Add 303.9 Mhz to default frequency list +* SubGHz: Fix Keeloq decoding order bug (random switch to HCS101 or anmotors) * API: Add new get function for varitemlist (by @Willy-JL) * Misc code cleanup * Apps: **Bluetooth Remote / USB Keyboard & Mouse** - `Movie` and `PTT` modes by @hryamzik * Apps: **BLE Spam app** updated to latest version (New devices support, + Menu by holding Start) (by @Willy-JL) -> (app can be found in builds ` `, `e`, `n`, `r`) * Apps: **Check out Apps updates by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) +* OFW: SubGhz: fix count bit for detect gate_tx protocol +* OFW: Fixed a zero allocation error when reading an iso15693 nfc tag with no additional blocks. +* OFW: Ntag21x write * OFW: Mifare Classic nested auth support * OFW: ST25TB poller refining + write support * OFW: Libraries cleanup; u2f crypto rework to use mbedtls From c477d1321af5a25df57d1cbbf709c9853f768f78 Mon Sep 17 00:00:00 2001 From: Honghao Zeng Date: Sun, 3 Dec 2023 20:00:46 +0900 Subject: [PATCH 4/5] nfc: m1k-based Aime (non-AIC) card support (#3241) Co-authored-by: gornekich --- applications/main/nfc/application.fam | 9 + .../main/nfc/plugins/supported_cards/aime.c | 164 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 applications/main/nfc/plugins/supported_cards/aime.c diff --git a/applications/main/nfc/application.fam b/applications/main/nfc/application.fam index 9a98b57c8..07e97c0c9 100644 --- a/applications/main/nfc/application.fam +++ b/applications/main/nfc/application.fam @@ -74,6 +74,15 @@ App( sources=["plugins/supported_cards/two_cities.c"], ) +App( + appid="aime_parser", + apptype=FlipperAppType.PLUGIN, + entry_point="aime_plugin_ep", + targets=["f7"], + requires=["nfc"], + sources=["plugins/supported_cards/aime.c"], +) + App( appid="nfc_start", targets=["f7"], diff --git a/applications/main/nfc/plugins/supported_cards/aime.c b/applications/main/nfc/plugins/supported_cards/aime.c new file mode 100644 index 000000000..1db89ffd6 --- /dev/null +++ b/applications/main/nfc/plugins/supported_cards/aime.c @@ -0,0 +1,164 @@ +#include "nfc_supported_card_plugin.h" + +#include + +#include +#include +#include + +#define TAG "Aime" + +static const uint64_t aime_key = 0x574343467632; + +bool aime_verify(Nfc* nfc) { + bool verified = false; + + do { + const uint8_t verify_sector = 0; + uint8_t block_num = mf_classic_get_first_block_num_of_sector(verify_sector); + FURI_LOG_D(TAG, "Verifying sector %u", verify_sector); + + MfClassicKey key = {}; + nfc_util_num2bytes(aime_key, COUNT_OF(key.data), key.data); + + MfClassicAuthContext auth_ctx = {}; + MfClassicError error = + mf_classic_poller_sync_auth(nfc, block_num, &key, MfClassicKeyTypeA, &auth_ctx); + + if(error != MfClassicErrorNone) { + FURI_LOG_D(TAG, "Failed to read block %u: %d", block_num, error); + break; + } + + verified = true; + } while(false); + + return verified; +} + +static bool aime_read(Nfc* nfc, NfcDevice* device) { + furi_assert(nfc); + furi_assert(device); + + bool is_read = false; + + MfClassicData* data = mf_classic_alloc(); + nfc_device_copy_data(device, NfcProtocolMfClassic, data); + + do { + MfClassicType type = MfClassicType1k; + MfClassicError error = mf_classic_poller_sync_detect_type(nfc, &type); + if(error != MfClassicErrorNone) break; + + 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); + FURI_BIT_SET(keys.key_a_mask, i); + nfc_util_num2bytes(aime_key, sizeof(MfClassicKey), keys.key_b[i].data); + FURI_BIT_SET(keys.key_b_mask, i); + } + + error = mf_classic_poller_sync_read(nfc, &keys, data); + if(error != MfClassicErrorNone) { + FURI_LOG_W(TAG, "Failed to read data"); + break; + } + + nfc_device_set_data(device, NfcProtocolMfClassic, data); + + is_read = true; + } while(false); + + mf_classic_free(data); + + return is_read; +} + +static bool aime_parse(const NfcDevice* device, FuriString* parsed_data) { + furi_assert(device); + + const MfClassicData* data = nfc_device_get_data(device, NfcProtocolMfClassic); + + bool parsed = false; + + 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); + if(key != aime_key) break; + + // Aime Magic is stored at block 1, starts from byte 0, len 4 bytes + const uint8_t* aime_magic = &data->block[1].data[0]; + + // verify aime magic + if(aime_magic[0] != 'S' || aime_magic[1] != 'B' || aime_magic[2] != 'S' || + aime_magic[3] != 'D') + break; + + // Aime checksum is stored at block 1, starts from byte 13, len 3 bytes + // seems like only old games checks this? e.g., old versions of Chunithm + const uint8_t* aime_checksum = &data->block[1].data[13]; + + // Aime access code is stored as decimal hex representation in block 2, starts from byte 6, len 10 bytes + const uint8_t* aime_accesscode = &data->block[2].data[6]; + + char aime_accesscode_str[24 + 1]; + snprintf( + aime_accesscode_str, + sizeof(aime_accesscode_str), + "%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x", + aime_accesscode[0], + aime_accesscode[1], + aime_accesscode[2], + aime_accesscode[3], + aime_accesscode[4], + aime_accesscode[5], + aime_accesscode[6], + aime_accesscode[7], + aime_accesscode[8], + aime_accesscode[9]); + + // validate decimal hex representation + for(int i = 0; i < 24; i++) { + if(aime_accesscode_str[i] == ' ') continue; + if(aime_accesscode_str[i] < '0' || aime_accesscode_str[i] > '9') return false; + } + + // Note: Aime access code has some other self-check algorithms that are not public. + // This parser does not try to verify the number. + + furi_string_printf( + parsed_data, + "\e#Aime Card\nAccess Code: \n%s\nChecksum: %02X%02X%02X\n", + aime_accesscode_str, + aime_checksum[0], + aime_checksum[1], + aime_checksum[2]); + + parsed = true; + + } while(false); + + return parsed; +} + +/* Actual implementation of app<>plugin interface */ +static const NfcSupportedCardsPlugin aime_plugin = { + .protocol = NfcProtocolMfClassic, + .verify = aime_verify, + .read = aime_read, + .parse = aime_parse, +}; + +/* Plugin descriptor to comply with basic plugin specification */ +static const FlipperAppPluginDescriptor aime_plugin_descriptor = { + .appid = NFC_SUPPORTED_CARD_PLUGIN_APP_ID, + .ep_api_version = NFC_SUPPORTED_CARD_PLUGIN_API_VERSION, + .entry_point = &aime_plugin, +}; + +/* Plugin entry point - must return a pointer to const descriptor */ +const FlipperAppPluginDescriptor* aime_plugin_ep() { + return &aime_plugin_descriptor; +} From 9bf8f1015d6b4bc03478cbc8ad9e761ab3cc0be4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 3 Dec 2023 18:41:28 +0300 Subject: [PATCH 5/5] fix keeloq null pointer if unknown --- lib/subghz/protocols/keeloq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 464f27ac5..700f1f6d0 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -979,6 +979,13 @@ static void subghz_protocol_keeloq_check_remote_controller( // If we are in BFT / Aprimatic programming mode we will set previous remembered counter and skip mf keys check ProgMode prog_mode = subghz_custom_btn_get_prog_mode(); if(prog_mode == PROG_MODE_OFF) { + if(keystore->mfname == 0x0) { + keystore->mfname = ""; + } + if(*manufacture_name == 0x0) { + *manufacture_name = ""; + } + // Case when we have no mf name means that we are checking for the first time and we have to check all conditions if((strlen(keystore->mfname) < 1) && strlen(*manufacture_name) < 1) { // Check key AN-Motors