From 022315e93d3325c68328326075fea0fc6fe5c728 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 12 Oct 2022 04:18:29 +0300 Subject: [PATCH] Improve keeloq, add JCM support, fix Nice Smilo, MHouse, and more now manufacturer name is saved into file, and will not change randomly, added support for JCM fixed Nice Smilo, MHouse --- ReadMe.md | 13 ++- applications/main/subghz/subghz_i.c | 2 +- applications/main/unirfremix/unirfremix_app.c | 2 +- assets/resources/subghz/assets/keeloq_mfcodes | 96 +++++++++---------- lib/subghz/protocols/keeloq.c | 37 +++++++ lib/subghz/protocols/star_line.c | 31 ++++++ 6 files changed, 126 insertions(+), 55 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index d4357336f..c4464bff1 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -44,13 +44,16 @@ Our Discord Community: Also check changelog in releases for latest updates! ### Current modified and new SubGHz protocols list: -- HCS101 -- An-Motors +- Keeloq [Not ALL systems supported for decode or emulation yet!] - [Supported manufacturers list](https://0bin.net/paste/VwR2lNJY#WH9vnPgvcp7w6zVKucFCuNREKAcOij8KsJ6vqLfMn3b) +- Keeloq: HCS101 +- Keeloq: An-Motors +- Keeloq: JCM Tech +- Keeloq: MHouse +- Keeloq: Nice Smilo - CAME Atomo -- FAAC SLH (Spa) [External seed calculation required] -- BFT Mitto [External seed calculation required] -- Keeloq [Not ALL systems supported yet!] - Nice Flor S +- FAAC SLH (Spa) [External seed calculation required (For info conatct me in Discord: Nano#8998)] +- BFT Mitto [External seed calculation required (For info conatct me in Discord: Nano#8998)] - Security+ v1 & v2 - Star Line (saving only) diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 1b6496bbc..e3d22ed73 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -431,7 +431,7 @@ bool subghz_save_protocol_to_file( do { //removing additional fields flipper_format_delete_key(flipper_format, "Repeat"); - flipper_format_delete_key(flipper_format, "Manufacture"); + //flipper_format_delete_key(flipper_format, "Manufacture"); // Create subghz folder directory if necessary if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) { diff --git a/applications/main/unirfremix/unirfremix_app.c b/applications/main/unirfremix/unirfremix_app.c index 6d0fa60b4..6fee8ebd9 100644 --- a/applications/main/unirfremix/unirfremix_app.c +++ b/applications/main/unirfremix/unirfremix_app.c @@ -562,7 +562,7 @@ bool unirfremix_save_protocol_to_file(FlipperFormat* fff_file, const char* dev_f path_extract_dirname(dev_file_name, file_dir); do { flipper_format_delete_key(fff_file, "Repeat"); - flipper_format_delete_key(fff_file, "Manufacture"); + //flipper_format_delete_key(fff_file, "Manufacture"); if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) { FURI_LOG_E(TAG, "(save) Cannot mkdir"); diff --git a/assets/resources/subghz/assets/keeloq_mfcodes b/assets/resources/subghz/assets/keeloq_mfcodes index 0c0e15a62..06078ffb1 100644 --- a/assets/resources/subghz/assets/keeloq_mfcodes +++ b/assets/resources/subghz/assets/keeloq_mfcodes @@ -1,51 +1,51 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 2A 34 F1 5A AF 6F F5 1A 83 A6 1E DA DE B7 3D F1 -06B63DF24AE073A2F2B19C55CA9E8364FBECD26E49C551990153F6513BDE5267 -6139C78C74C341EB7474085CF1D047BD6FB005F80A72AF3EF3F89D58EF5DF500 -D85F11689020ECA47FBE9C2B67EE41A81E1F06DE2A35AF958965E3ECE29EA701 -1AE9073A42FE0E439544FE6945F6B33CF15A7A4A279020B5E0B3BE33FD189A7E -E161F007854BB33E0056FA09A2E2DEE66789B5C87C8D6D3DE2C8C1BD2B48983EB9D1C5697CA6E95996918F7C47B761B0 -59AE4644DCB3D720C38B5115F230DA58E7BE0A697907F6174BB05AB7886ACDB1 -634DF0BCC185C4C1F7E1B1594B4438D051ABAE092433078963063B51D961D08C -1EBEBCB49E498B9BE977D53EC21B9A546155B627737BD0AA832D496035729346 -4DFA93E639197772D57E8ACE04512CEFC045B8CC965C175A25ED525B630CBB63 -C2D5235D1014A319B249EAE8A5EE350F18D5AB8A498EF222704BD4EB1435F388 -F66D1937160E1392197F463A52E87FCE938A92070892113443C348D7553327A5715CF615CE2F2C96284F47759E043419 -841D29E7CBE040188E2283BFBA9F26EF2F65CCB085B56C3515E8C46C3F20BD75BAA963550869435FDAF509CEEE66A2C4 -7D87E24487D307635E7A17B989B8547EE11F3BF3468D055F0B44633B631BA42C -B4916043973501B95A82B329196D6EBA69FBBC3AF8FD914583104E0E18CE82F6 -E4649F9C2A5465D2EA6F3E9724DD06CD6962FE2BAEB14F1453C14D1559232AE1 -96E15D890DF7FD348441F5E429A875754C6BF0520A787F8E9D8C5415674783CC -CB52005EDED47B57F795BC92FB0522EAB18D23EE028B8D10ED57828C250EB285BFEC6E4A4BE8DABCE0D57ECAA20D90C3 -8E5A50C7D5C374445E88752301D20F0B3D6E4988B61D90FD63779B0EDEF9C60D -49D6CB276A0E5FF134A38062503F01351F44CD6455708B50B5F07D03FC477C33 -CB45B56613DF208E79E4E10A6510F07DC1AA49210C7B94E8BBAECD2C35EC6ABC99FB10FD7C96DD6BB6A6685E9FAD93FB -0743F3CC51200F763C242F1956B4D775C092ADF1A5C19ACAE96EB60C2990CF214F8FEA8FC6749286F6BDAB67657C479A -E5608B28A058787D64A145F0362DEFD98CAE0B5A0F22C6DA7C6D278C7B5F95E3 -D4C113D43E7FB6D2EFA9E87471AA76A61B26872607B4AF5B87F9D72113835CE6 -2DC502800BFD21B76126390CA64A08C5432A2254E822F214CDE1EA11430084C5 -CA22C73010B0F1CB8009601BE2AF0B3674D83D5880E4A26C2A3FF0EA0A098CEA -E53B2B102FDB000E9BB747F957156976E5A0C0E3898AA844C13AE8A9CEE7013B -EFB27324B5661419265804ABD130C13DC9DF9CD4D2AC2011CB4FD43D56304AD1 -491D75A82ACE8CE216FBE4F0D2D0133BAC7EA8F4A5304337D5E8611AD9C72523 -BBFA2B00827E0BCC8AC5CE12C972BB58DFA2EA59DFEFF5A538398FCF970F58A7 -6BAF9C855926B683BEDC11883543B2C0E0866FF6B06C46CC09B3C4E1200E7716 -B35A4D25FF4D5CFF93B9C4C07B78FCF7E2646138DAB7C090A938C8055CCCE3D8 -71CC3C0180771E6B304CE984F5A9962EB35D1965CB78EBAE6F4DDFA44E5E02A2 -3DCF52C549FEFCCE2831DB74579AA2C157A4BEE70C43905664C9A6491A171F5D -F7E45AF200F7663DCCE54C14118D2CDFD1228ED0BFF7F70CFBCE15B6F9DF3D40 -C44E048AD5C003E68DCF0111317D109CF2B7DD79299692CDA7DA2A12EC9A295A -2B3E6778A97B251A5FEB190991B8AE8EC48F5FC6E94C2ECB8DFADFDD9D8E21FEE5DCCEDD9A1EB8C5212DEAE36FBBDF92 -1DD4756E681528CBBDBA6C7BF8833DF556D41E5EA4E4DE52CAD3544C946CD8CA -F903D388CF2016B40B492494F7475E71C50E9FDD63304558212DAF6FBC4E1BA4 -9E9F24951DB27917668CD6366795052306022F6F8BA11B08A970691C6857E6C5 -C88461104FA0EAA68001B0C2D0483D1A53D6AE04F4CB291C76CEF3A1A5C5DC10 -8345B2B9F08B018FEAC2F74D76747FF30DBF426C9B390ACD42AD48104C12042E -087269DC66C76E1D6449831A2C3B6F0006C0F8B1861062B95708C6B222C58A9C -4D31DE05DB12E552D43B1017C68AF3F52B6FE8063E4AD82CB568CDAF22950BCC26FF21EE968FB57650111B617A84DEF7 -769BAA780F84797431B6E9DD5180AF3848E03C942C67040B39CC6384E2A8F4C6 -1844AAAAD6A6AFB2623DF1452DF940715E6EB92F54C49F408872EC4B2156DDB2 -23EB39CD7F3921081199BA8B63D4C19F74365F8D8E71D486576DC900E5EFEEA3 -45958B93A16A73CA2578ADCFB1EADAA983BB7015321B0592B67CDF573B084194 +IV: 3B 23 A4 2B B1 5D D3 2C 45 B7 3D AF AE B1 D8 53 +FA10AAD920563C9F593B7CDDBB544A0F3F2D372854A3A9AB69D10199E7CCFA54 +92423F7ED2493A8015BE619D2983056022FC634B68F17EB1260670497FDFB189 +6AB9C91E650D048078F87D7DACB278F52EC84CA7F2AECC4338D6A6B456BDE934 +84EF6BCCB35F1FCCE0EAC6344D4E4E37A263F04B1FDE79A1D0884BE1FCB8A664 +BEC8FBBE9CB4C8C894DD8F2D63A49E76F0363203154710FE8762592858CAD6AF47B9E4BC7ADA14D77F8A82BF9BACE6C6 +FB558B51A1DCAB34D119C9D3AC0B0F681E152ED3F9D00E3D40C4B868EEEF8F73 +A6E060649AB62907D3B584F1AAC27C2BA1D4BC964BE527A5B901A46C5CADD9BB +7E2E6B38427BFCDB5CD9ED52CF342181446EA6B61192DF28928B64440364F77D +0E3F30701EA2071F9291FA3783149181B27E7B83FF8E259AB458ED3997EE649B +A8ABE616CFF13397BA3D21992C14E43B42FE496C84B97CB7FF0FD4611DAEC8A3 +EBBB491879A73FD43718C6851855F621B0AE986C728A8F8D99359F882406132BFB2CF9811BA464D878F36E5712759869 +ED4EEF947C6E3475F5FF9905352C7D78F153C65A9AB418892069202C6677002EA2AFC55462797DEE0B69375283D84A26 +A27B11AD0DDB5E96B68EB1A016598152FE27C966CF675F7BF17990DEAFF58B62 +0BF77CB175A18ADCBDAEA31EAF80ABD886D6BF5034088A25722BC8BB6F7E65FD +66B3C2C98F8154F0B54887B251F8C583199D06ADE895DCEE324213EF3701A44D +A00342176255312C795DD2048087E5B93C28A11BE39E44E2F60B27A1D1B0532F +E6C8A79585A0E091C17E3633ED3074FFA3A5093142B5FB0921873B006257C5F7258B7094F38ACC0D77EA01F31967D2CB +0A2D80FFD35E8D0FD9D728594E91FC8930C7F28EDF59DA2EC896F76A7D71AAF3 +0520C7F9BB04EADAF8A74CF89E8EF7AF2B445EB30E5044448B6B8E58CB2467CB +1B7A5310AA25A22042320874ABDF28A7C49432B8364CBF8AB4F04B954D7198C4274F684E4265F82317AB46ACAEA4E849 +F0B462179B43E94C50CA2AC75D8C37C0FB606FB0A5380E2BE9F7C5BF24EF3CEFE12E36B41961626F83F9458735AE0A28 +9D3A735349C6D83E22C84088DE19EDAD877CBF8E485ED20D25019580354B51B5 +4285797E07FF121D73926DFB11B4CE0E7914FD7AECD62381F45A26091ED1EB3D +63787A106DB07DBECB108A45959E15F7DEB04858989DE536483DA06D3F0D1509 +A64DF8135E264E799DFB8C8063F665890BDE3CE671FC9878E96516386B1421DB +CCF9B4EF4D817F0A38D023937AD4CE201B0A84AF480CB9FC797AFE8AE9D7C50A +D8DDE6F46CDC89283BAB72171A0F0E470A434F3973CC5FD5617E3F9E0B469048 +F08C5ECAC04171983A3923CFFC22BA5CC0C9EECA20D7D5EB2D9495FB9F3B7E80 +5AEB9E25A24FA3BF5715D264610E0A6D68197B376555470DA19743569B2CA52C +95E621103E87C52397A53053045FE7B916E43B153F9140144DEEB840F2C43D02 +12DFA9AFC04287DE60E540EA46472BE1283012646F3614A501CEA416B591BB89 +9375214B3188DE8E4FBA9BB746323B10862B906B8250B6F49E6A3E6400AC5DA6 +047BA7E96986B6054F44F2A20AA338C145FE53099BE77481A635D6E73CEC97FB +42115D1C01E03A411D4940644472FC6F6BC85D90305995D00B1839D5FA6B18CC +A962C5FA4F0D5443C8E7555C1F9563588D206B0EA60886B0C44E6EB1EC733971 +62E66CDD2FE2ABCA8997D8D8DE24F81C8051C9371F2DB7C8BB6E8DC54A342F9FB09E896133D7F50B8DC058812C90A122 +B6E6DEEA620F723D2F7E0325F558F4590DB33553E7680447FA17EEDC1B7C37DF +15621585B61B3EF2858777E0649801F9AE45FEEBC350786E015E8B669E40453F +60D5FEABB8D4C371BF8F700A2C06B15E26CA940FF7990892DDED3D1898787D03 +AB0B79C7F5B7BA414E5091CEE9E7F186185A04A9C2E89B4F7C0FA1EB2212EA8C +96065C37BD3B8FBCAA987E8242DB2BDEDE97B3A0F9D7B4C5E753B77989FDE01F +9B9F6302870EF6724F9F7501BC69D4A994485639FB5C437A1461A79D5700D6EF +2D0042C0215561D6E991EDC884477ABA85800D60714CC05FB964A756F2EB05E8 +61B88BBB34E93B215CC17C39F2B848AA3CC37EF946FBC467C53873E79985276DB86FF1508972758FE7FC9047B87A7C91 +02401832ACADB1DC195902ABD1219965DBA9D38FF651553D18F158A54D98562F +BB5E86C8CB07ACA72B27DCBE578C71080AA1D4071E088E0A6E5CD3DBB0BBB95E +0E86D4024CDBF883C701CBCEA75501158FCB442E0EC30FB592D2F8BBCBF24F4F diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index b43a60e4d..65927d7b1 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -28,6 +28,8 @@ struct SubGhzProtocolDecoderKeeloq { uint16_t header_count; SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; struct SubGhzProtocolEncoderKeeloq { @@ -38,6 +40,8 @@ struct SubGhzProtocolEncoderKeeloq { SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; typedef enum { @@ -113,12 +117,16 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; + + instance->manufacture_from_file = furi_string_alloc(); + return instance; } void subghz_protocol_encoder_keeloq_free(void* context) { furi_assert(context); SubGhzProtocolEncoderKeeloq* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance->encoder.upload); free(instance); } @@ -143,6 +151,13 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc instance->manufacture_name = ""; } + // Nice Smilo, MHouse, JCM has 8bit serial - simple learning + if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || + (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || + (strcmp(instance->manufacture_name, "JCM_Tech") == 0)) { + decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; + } + if(strcmp(instance->manufacture_name, "Unknown") == 0) { code_found_reverse = subghz_protocol_blocks_reverse_key( instance->generic.data, instance->generic.data_count_bit); @@ -347,6 +362,16 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Wrong number of bits in key"); break; } + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); + } + uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; @@ -415,6 +440,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_keeloq; instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); + instance->manufacture_from_file = furi_string_alloc(); return instance; } @@ -422,6 +448,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { void subghz_protocol_decoder_keeloq_free(void* context) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance); } @@ -950,6 +977,16 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Rewind error"); break; } + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); + } + uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index d6c9c0ae0..f91e9ad18 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -28,6 +28,8 @@ struct SubGhzProtocolDecoderStarLine { uint16_t header_count; SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; struct SubGhzProtocolEncoderStarLine { @@ -38,6 +40,8 @@ struct SubGhzProtocolEncoderStarLine { SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; typedef enum { @@ -109,16 +113,20 @@ void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); + instance->manufacture_from_file = furi_string_alloc(); + instance->encoder.repeat = 10; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; + return instance; } void subghz_protocol_encoder_star_line_free(void* context) { furi_assert(context); SubGhzProtocolEncoderStarLine* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance->encoder.upload); free(instance); } @@ -274,6 +282,15 @@ bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat* break; } + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); + } + subghz_protocol_star_line_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); @@ -331,6 +348,9 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { SubGhzProtocolDecoderStarLine* instance = malloc(sizeof(SubGhzProtocolDecoderStarLine)); instance->base.protocol = &subghz_protocol_star_line; instance->generic.protocol_name = instance->base.protocol->name; + + instance->manufacture_from_file = furi_string_alloc(); + instance->keystore = subghz_environment_get_keystore(environment); return instance; @@ -339,6 +359,7 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { void subghz_protocol_decoder_star_line_free(void* context) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance); } @@ -705,6 +726,16 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Deserialize error"); break; } + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); + } + res = true; } while(false);