SubGhz: Add new man key (#817)
* SubGhz: fix kelog pattern * SubGhz: add Keloog Secure Learning * SubGhz: add man NICE_Smilo, NICE_MHOUSE, DEA, Genius, FAAC_RC,XT, Came_Space, DTM Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
22e8da7108
commit
6792e24b6e
@ -23,5 +23,10 @@ C38CBE29F22D0E83E58A52E94AA2485DA8E702FBDB89D27249473CB8A19AEF61
|
|||||||
9F0EB580F7474985E8460E1682451E213778B77A9CAB4734B75C5386851050BF
|
9F0EB580F7474985E8460E1682451E213778B77A9CAB4734B75C5386851050BF
|
||||||
2364EBB8237363B21226565675B9F478482CADAE41E795C27287E26137797C10
|
2364EBB8237363B21226565675B9F478482CADAE41E795C27287E26137797C10
|
||||||
775C9A28BA50D759FB438D0200121F01F7DB11986D44D3960F745EAA1E7A2CE2AD92AD718AFCD98BC3269C39F65ADC53
|
775C9A28BA50D759FB438D0200121F01F7DB11986D44D3960F745EAA1E7A2CE2AD92AD718AFCD98BC3269C39F65ADC53
|
||||||
6911E7EAFFAC15B4E3ABDAD271E92EAEFE1F2E288789EC7599AAA32986273306
|
80F637A04446BF1FBEF3399307527403A15031FC4030F7C1E8217A2367B21A52
|
||||||
5387D67534234AFD8BAB90DC74BA39598B938526CBFAF14F75AA36A29C13836A31897A86D2E1178AE66191E771A7FEA4
|
1E3EC8CCECC14E8898D13BB2EEEC1EABABCD83D6930DBB8D381D8378EC5FAF22
|
||||||
|
46A68DD969BFF20ADFAC767AFA87D3CA98AE6C056B0B4D43A5A24A7ABBD88D57
|
||||||
|
FEC591F298259129A9EC9BE66D903C2D5D94A17D38CD889C878664FC3C118FDA
|
||||||
|
2BC0AA2C0909417140615C7E901566A9AD2F88BCF500A0AF82A79BE4C0B013CE
|
||||||
|
D9C9119FE35EB25800F60C2D5D2F018D43CC888147D469BF26F86A8DBABB2DCB
|
||||||
|
6FFECFF334702D6E32B55B5CDE4191176D2D3CC3A3CE10E880425BD7FC262193
|
||||||
|
@ -49,6 +49,20 @@ void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance) {
|
|||||||
free(instance);
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool subghz_protocol_keeloq_check_decrypt(
|
||||||
|
SubGhzProtocolKeeloq* instance,
|
||||||
|
uint32_t decrypt,
|
||||||
|
uint8_t btn,
|
||||||
|
uint32_t end_serial) {
|
||||||
|
furi_assert(instance);
|
||||||
|
if((decrypt >> 28 == btn) && (((((uint16_t)(decrypt >> 16)) & 0xFF) == end_serial) ||
|
||||||
|
((((uint16_t)(decrypt >> 16)) & 0xFF) == 0))) {
|
||||||
|
instance->common.cnt = decrypt & 0x0000FFFF;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Checking the accepted code against the database manafacture key
|
/** Checking the accepted code against the database manafacture key
|
||||||
*
|
*
|
||||||
* @param instance SubGhzProtocolKeeloq instance
|
* @param instance SubGhzProtocolKeeloq instance
|
||||||
@ -60,10 +74,15 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
|||||||
SubGhzProtocolKeeloq* instance,
|
SubGhzProtocolKeeloq* instance,
|
||||||
uint32_t fix,
|
uint32_t fix,
|
||||||
uint32_t hop) {
|
uint32_t hop) {
|
||||||
uint16_t end_serial = (uint16_t)(fix & 0x3FF);
|
// protocol HCS300 uses 10 bits in discriminator, HCS200 uses 8 bits, for backward compatibility, we are looking for the 8-bit pattern
|
||||||
|
// HCS300 -> uint16_t end_serial = (uint16_t)(fix & 0x3FF);
|
||||||
|
// HCS200 -> uint16_t end_serial = (uint16_t)(fix & 0xFF);
|
||||||
|
|
||||||
|
uint16_t end_serial = (uint16_t)(fix & 0xFF);
|
||||||
uint8_t btn = (uint8_t)(fix >> 28);
|
uint8_t btn = (uint8_t)(fix >> 28);
|
||||||
uint32_t decrypt = 0;
|
uint32_t decrypt = 0;
|
||||||
uint64_t man_normal_learning;
|
uint64_t man_learning;
|
||||||
|
uint32_t seed = 0;
|
||||||
|
|
||||||
for
|
for
|
||||||
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
|
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
|
||||||
@ -71,36 +90,36 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
|||||||
case KEELOQ_LEARNING_SIMPLE:
|
case KEELOQ_LEARNING_SIMPLE:
|
||||||
// Simple Learning
|
// Simple Learning
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||||
if((decrypt >> 28 == btn) &&
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
|
|
||||||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
|
|
||||||
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
instance->common.cnt = decrypt & 0x0000FFFF;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEELOQ_LEARNING_NORMAL:
|
case KEELOQ_LEARNING_NORMAL:
|
||||||
// Normal_Learning
|
// Normal_Learning
|
||||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||||
man_normal_learning =
|
man_learning =
|
||||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning);
|
||||||
if((decrypt >> 28 == btn) &&
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEELOQ_LEARNING_SECURE:
|
||||||
|
man_learning = subghz_protocol_keeloq_common_secure_learning(
|
||||||
|
fix, seed, manufacture_code->key);
|
||||||
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning);
|
||||||
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
instance->common.cnt = decrypt & 0x0000FFFF;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEELOQ_LEARNING_UNKNOWN:
|
case KEELOQ_LEARNING_UNKNOWN:
|
||||||
// Simple Learning
|
// Simple Learning
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||||
if((decrypt >> 28 == btn) &&
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
|
|
||||||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
|
|
||||||
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
instance->common.cnt = decrypt & 0x0000FFFF;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Check for mirrored man
|
// Check for mirrored man
|
||||||
@ -111,40 +130,42 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
|||||||
man_rev = man_rev | man_rev_byte << (56 - i);
|
man_rev = man_rev | man_rev_byte << (56 - i);
|
||||||
}
|
}
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
|
||||||
if((decrypt >> 28 == btn) &&
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
|
|
||||||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
|
|
||||||
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
instance->common.cnt = decrypt & 0x0000FFFF;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//###########################
|
//###########################
|
||||||
// Normal_Learning
|
// Normal_Learning
|
||||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||||
man_normal_learning =
|
man_learning =
|
||||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning);
|
||||||
if((decrypt >> 28 == btn) &&
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
|
|
||||||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
|
|
||||||
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
instance->common.cnt = decrypt & 0x0000FFFF;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Check for mirrored man
|
man_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
|
||||||
man_rev = 0;
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning);
|
||||||
man_rev_byte = 0;
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
for(uint8_t i = 0; i < 64; i += 8) {
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
|
return 1;
|
||||||
man_rev = man_rev | man_rev_byte << (56 - i);
|
}
|
||||||
}
|
|
||||||
man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
|
// Secure Learning
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
|
man_learning = subghz_protocol_keeloq_common_secure_learning(
|
||||||
if((decrypt >> 28 == btn) &&
|
fix, seed, manufacture_code->key);
|
||||||
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning);
|
||||||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for mirrored man
|
||||||
|
|
||||||
|
man_learning = subghz_protocol_keeloq_common_secure_learning(fix, seed, man_rev);
|
||||||
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning);
|
||||||
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
instance->manufacture_name = string_get_cstr(manufacture_code->name);
|
||||||
instance->common.cnt = decrypt & 0x0000FFFF;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -214,7 +235,7 @@ uint64_t subghz_protocol_keeloq_gen_key(void* context) {
|
|||||||
uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 |
|
uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 |
|
||||||
instance->common.cnt;
|
instance->common.cnt;
|
||||||
uint32_t hop = 0;
|
uint32_t hop = 0;
|
||||||
uint64_t man_normal_learning = 0;
|
uint64_t man_learning = 0;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
for
|
for
|
||||||
@ -228,9 +249,9 @@ uint64_t subghz_protocol_keeloq_gen_key(void* context) {
|
|||||||
break;
|
break;
|
||||||
case KEELOQ_LEARNING_NORMAL:
|
case KEELOQ_LEARNING_NORMAL:
|
||||||
//Simple Learning
|
//Simple Learning
|
||||||
man_normal_learning =
|
man_learning =
|
||||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning);
|
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_learning);
|
||||||
break;
|
break;
|
||||||
case KEELOQ_LEARNING_UNKNOWN:
|
case KEELOQ_LEARNING_UNKNOWN:
|
||||||
hop = 0; //todo
|
hop = 0; //todo
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key) {
|
inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key) {
|
||||||
uint32_t x = data, r;
|
uint32_t x = data, r;
|
||||||
for(r = 0; r < 528; r++)
|
for(r = 0; r < 528; r++)
|
||||||
x = (x>>1)^((bit(x,0)^bit(x,16)^(uint32_t)bit(key,r&63)^bit(KEELOQ_NLF,g5(x,1,9,20,26,31)))<<31);
|
x = (x >> 1) ^ ((bit(x, 0) ^ bit(x, 16) ^ (uint32_t)bit(key, r & 63) ^
|
||||||
|
bit(KEELOQ_NLF, g5(x, 1, 9, 20, 26, 31)))
|
||||||
|
<< 31);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +27,8 @@ inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const
|
|||||||
inline uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key) {
|
inline uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key) {
|
||||||
uint32_t x = data, r;
|
uint32_t x = data, r;
|
||||||
for(r = 0; r < 528; r++)
|
for(r = 0; r < 528; r++)
|
||||||
x = (x<<1)^bit(x,31)^bit(x,15)^(uint32_t)bit(key,(15-r)&63)^bit(KEELOQ_NLF,g5(x,0,8,19,25,30));
|
x = (x << 1) ^ bit(x, 31) ^ bit(x, 15) ^ (uint32_t)bit(key, (15 - r) & 63) ^
|
||||||
|
bit(KEELOQ_NLF, g5(x, 0, 8, 19, 25, 30));
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,3 +50,23 @@ inline uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, con
|
|||||||
|
|
||||||
return ((uint64_t)k2 << 32) | k1; // key - shifrovanoya
|
return ((uint64_t)k2 << 32) | k1; // key - shifrovanoya
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Secure Learning
|
||||||
|
* @param data - serial number (28bit)
|
||||||
|
* @param seed - serial number (32bit)
|
||||||
|
* @param key - manufacture (64bit)
|
||||||
|
* @return manufacture for this serial number (64bit)
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline uint64_t subghz_protocol_keeloq_common_secure_learning(
|
||||||
|
uint32_t data,
|
||||||
|
uint32_t seed,
|
||||||
|
const uint64_t key) {
|
||||||
|
uint32_t k1, k2;
|
||||||
|
|
||||||
|
data &= 0x0FFFFFFF;
|
||||||
|
k1 = subghz_protocol_keeloq_common_decrypt(data, key);
|
||||||
|
k2 = subghz_protocol_keeloq_common_decrypt(seed, key);
|
||||||
|
|
||||||
|
return ((uint64_t)k1 << 32) | k2;
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
#include "subghz_protocol_common.h"
|
#include "subghz_protocol_common.h"
|
||||||
#include "file-worker.h"
|
#include "file-worker.h"
|
||||||
|
|
||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -14,7 +13,8 @@
|
|||||||
|
|
||||||
#define KEELOQ_NLF 0x3A5C742E
|
#define KEELOQ_NLF 0x3A5C742E
|
||||||
#define bit(x, n) (((x) >> (n)) & 1)
|
#define bit(x, n) (((x) >> (n)) & 1)
|
||||||
#define g5(x,a,b,c,d,e) (bit(x,a)+bit(x,b)*2+bit(x,c)*4+bit(x,d)*8+bit(x,e)*16)
|
#define g5(x, a, b, c, d, e) \
|
||||||
|
(bit(x, a) + bit(x, b) * 2 + bit(x, c) * 4 + bit(x, d) * 8 + bit(x, e) * 16)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* KeeLoq learning types
|
* KeeLoq learning types
|
||||||
@ -25,7 +25,6 @@
|
|||||||
#define KEELOQ_LEARNING_NORMAL 2u
|
#define KEELOQ_LEARNING_NORMAL 2u
|
||||||
#define KEELOQ_LEARNING_SECURE 3u
|
#define KEELOQ_LEARNING_SECURE 3u
|
||||||
|
|
||||||
|
|
||||||
/** Simple Learning Encrypt
|
/** Simple Learning Encrypt
|
||||||
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
|
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
|
||||||
* @param key - manufacture (64bit)
|
* @param key - manufacture (64bit)
|
||||||
@ -46,3 +45,13 @@ uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64
|
|||||||
* @return manufacture for this serial number (64bit)
|
* @return manufacture for this serial number (64bit)
|
||||||
*/
|
*/
|
||||||
uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key);
|
uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key);
|
||||||
|
|
||||||
|
/** Secure Learning
|
||||||
|
* @param data - serial number (28bit)
|
||||||
|
* @param seed - serial number (32bit)
|
||||||
|
* @param key - manufacture (64bit)
|
||||||
|
* @return manufacture for this serial number (64bit)
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
subghz_protocol_keeloq_common_secure_learning(uint32_t data, uint32_t seed, const uint64_t key);
|
Loading…
x
Reference in New Issue
Block a user