From abbf3fc3cd27458a009b4c08dacdcd9370f66022 Mon Sep 17 00:00:00 2001 From: Mentalflow <312902918@qq.com> Date: Sat, 24 Feb 2024 23:42:47 +0800 Subject: [PATCH] ZigBee: Fix the pkg length overflow. --- app_source/dlln3x/DLLN3X.cpp | 7 +++-- app_source/include/crypto.h | 4 +-- app_source/include/protocol.h | 10 +++---- app_source/include/protocol_data.h | 10 +++---- app_source/qml/components/TabBar.qml | 4 +-- app_source/source/crypto.cpp | 41 +++++++++++++++++----------- app_source/source/protocol.cpp | 20 ++++++-------- app_source/source/zigbeeparser.cpp | 12 ++++---- 8 files changed, 57 insertions(+), 51 deletions(-) diff --git a/app_source/dlln3x/DLLN3X.cpp b/app_source/dlln3x/DLLN3X.cpp index 32ca55d..b2246f7 100644 --- a/app_source/dlln3x/DLLN3X.cpp +++ b/app_source/dlln3x/DLLN3X.cpp @@ -61,9 +61,10 @@ ZigbeeFrame DLLN3X::recv(bool non_blocked) bool DLLN3X::send(ZigbeeFrame zf) { bool status = false; - if (zf.getSrcPort() < 0x80) + uint8_t len = zf.size(); + if (zf.getSrcPort() < 0x80 || (len + 4) > 63) return false; - status = _DSerial->write((char *)zf.data(),zf.size()); + status = _DSerial->write((char *)zf.data(),len); status = _DSerial->flush(); return status; } @@ -71,7 +72,7 @@ bool DLLN3X::send(ZigbeeFrame zf) bool DLLN3X::send_cmd(uint8_t des_port, uint8_t arg, uint8_t* data, uint8_t data_length) { ZigbeeFrame zf(0x80, des_port, 0x0000); - if (data_length - 4 > 63 - 1) + if (data_length + 4 > 63) return false; zf.append(arg); zf.addData(data, data_length); diff --git a/app_source/include/crypto.h b/app_source/include/crypto.h index 1b85353..ba68a6d 100644 --- a/app_source/include/crypto.h +++ b/app_source/include/crypto.h @@ -24,8 +24,8 @@ public: static void SM2_sign(u8 *pri, u8 *data, u32 datalen, u8 *out); static bool SM2_verify(u8 *pub, u8 *data, u32 data_len, u8 *sig); static void SM3_HMAC(u8 *key, int keylen,u8 *input, int ilen,u8 output[32] ); - static bool SM4_encrypt(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len); - static bool SM4_decrypt(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len); + static bool SM4_encrypt(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc = true); + static bool SM4_decrypt(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc = true); static uint8_t get_rand(); private: Crypto(); diff --git a/app_source/include/protocol.h b/app_source/include/protocol.h index 4b4ef93..ca5e74f 100644 --- a/app_source/include/protocol.h +++ b/app_source/include/protocol.h @@ -22,12 +22,12 @@ public: void (*sendToserver)(ZigbeeFrame &data), void (*SM3_HMAC)(u8 *key, int keylen,u8 *input, int ilen,u8 output[32] )); void HMAC_changeVerifykey(u8 key[16], device* self, device *node, void (*sendTonode)(ZigbeeFrame &data), - bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len)); - void zigbee_data_encrypt(data_frame *data, crypto_zdata_frame *zdata, - bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len), + bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc)); + void zigbee_data_encrypt(uint8_t *data, uint8_t data_len, crypto_zdata_frame *zdata, + bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc), QString en_key = ""); - bool zigbee_data_dectypt(data_frame *data, crypto_zdata_frame *zdata, - bool (* SM4_decrypt)(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len), + bool zigbee_data_dectypt(uint8_t *data, uint8_t *data_len, crypto_zdata_frame *zdata, + bool (* SM4_decrypt)(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc), QString en_key = ""); QString hmac_verify_key = "11223344556677888877665544332211"; QStringList pre_hmac_verify_key; diff --git a/app_source/include/protocol_data.h b/app_source/include/protocol_data.h index f68a53d..7c00823 100644 --- a/app_source/include/protocol_data.h +++ b/app_source/include/protocol_data.h @@ -183,13 +183,13 @@ typedef struct login_resp }login_resp; #define SENSOR_DATA_TYPE 1 -#define SENSOR_DATA_LENGTN sizeof(double)*4 +#define SENSOR_DATA_LENGTN sizeof(float)*4 typedef struct sensor_data { - double ppm; - double temp; - double humi; - double flare; + float ppm; + float temp; + float humi; + float flare; }sensor_data; #define THRESHOLD_DATA_TYPE 2 diff --git a/app_source/qml/components/TabBar.qml b/app_source/qml/components/TabBar.qml index df53be3..b9f3254 100644 --- a/app_source/qml/components/TabBar.qml +++ b/app_source/qml/components/TabBar.qml @@ -373,8 +373,8 @@ RibbonTabBar { } let repeat_count = 16 - let t = `FF 29 ${get_rand_byte()}${get_rand_byte()} 83 23 32 `+ - `AA AD 23 32 52 48 23 32 01 00 17 00 00 00 AA AA 01 10 00 FF FF ` + let t = `FF 29 ${get_rand_byte()}${get_rand_byte()} 83 56 56 `+ + `AA AD 56 56 52 48 23 32 01 00 17 00 00 00 AA AA 01 10 00 FF FF ` for (let j=0;jget_rand(); // 使用随机数IV,如果想节省时间可以注释 + for (int i = 0; i < 16; i++) + { + iv[i] = Crypto::getInstance()->get_rand(); // 使用随机数IV,如果想节省时间可以注释 + } } if (key_len > 16) { free(in); @@ -180,28 +183,31 @@ bool Crypto::SM4_encrypt(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, } fix_len = 16 - key_len; memcpy(key, key_origin, key_len); - for (int i = 0; i < 16; i++) + if (use_real_cbc) { - in[i] = Crypto::getInstance()->get_rand(); // 首填充 + for (int i = 0; i < 16; i++) + { + in[i] = Crypto::getInstance()->get_rand(); // 首填充 + } } - memcpy(in + 16, in_origin, in_len); + memcpy(in + (use_real_cbc ? 16 : 0), in_origin, in_len); if (key_len < 16) { for (int i = key_len; i < 16; i++) { key[i] = fix_len; } } if (in_len % 16 != 0) { - max_len = ceil(in_len / 16.0)* 16 + 16; - fix_len = max_len - 16 - in_len; - for (u32 i = in_len + 16; i < max_len; i++) { + max_len = ceil(in_len / 16.0)* 16 + (use_real_cbc ? 16 : 0); + fix_len = max_len - (use_real_cbc ? 16 : 0) - in_len; + for (u32 i = in_len + (use_real_cbc ? 16 : 0); i < max_len; i++) { in[i] = fix_len; } in_len = max_len; } else { - for (u32 i = in_len + 16; i < in_len + 16 * 2; i++) { + for (u32 i = in_len + (use_real_cbc ? 16 : 0); i < in_len + 16 + (use_real_cbc ? 16 : 0); i++) { in[i] = 16; } - in_len += 16 * 2; + in_len += 16 + (use_real_cbc ? 16 : 0); } *out_len = in_len; sm4_cbc_encrypt(&a, key, iv, in, in_len, out); @@ -209,7 +215,7 @@ bool Crypto::SM4_encrypt(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, return true; } -bool Crypto::SM4_decrypt(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len) +bool Crypto::SM4_decrypt(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc) { struct sm4_ctx b; u32 fix_len; @@ -217,9 +223,12 @@ bool Crypto::SM4_decrypt(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *ou u8 iv[17] = { 0x21, 0xBC, 0xC1, 0xEA, 0x0D, 0xB8, 0x54, 0x6D, 0xCE, 0xE4, 0xDB, 0x3C, 0xFA, 0xC1, 0x3C, 0xEF }; // 此处为省时才用固定IV,实际上此处IV必须是随机的才可真正保证SM4 CBC模式下加解密的强度 u8* out_buf = (u8* )malloc(in_len * sizeof(u8)); // 为保证C兼容性,不使用智能指针 - for (int i = 0; i < 16; i++) + if (use_real_cbc) { - iv[i] = Crypto::getInstance()->get_rand(); // 使用随机数IV,如果想节省时间可以注释 + for (int i = 0; i < 16; i++) + { + iv[i] = Crypto::getInstance()->get_rand(); // 使用随机数IV,如果想节省时间可以注释 + } } if (key_len > 16) { free(out_buf); @@ -243,8 +252,8 @@ bool Crypto::SM4_decrypt(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *ou free(out_buf); return false; } - *out_len = in_len - fix_len - 16; - memcpy(out, out_buf + 16, *out_len); + *out_len = in_len - fix_len - (use_real_cbc ? 16 : 0); + memcpy(out, out_buf + (use_real_cbc ? 16 : 0), *out_len); free(out_buf); return true; } diff --git a/app_source/source/protocol.cpp b/app_source/source/protocol.cpp index d307483..aa4820a 100644 --- a/app_source/source/protocol.cpp +++ b/app_source/source/protocol.cpp @@ -159,19 +159,19 @@ bool Protocol::data_frame_verify(data_frame *frame) return true; } -void Protocol::zigbee_data_encrypt(data_frame *data, crypto_zdata_frame *zdata, - bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len), +void Protocol::zigbee_data_encrypt(uint8_t *data, uint8_t data_len, crypto_zdata_frame *zdata, + bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc), QString en_key) { u32 len; zdata->head=CRYPTO_ZDATA_FRAME_HEAD; QByteArray key = QByteArray::fromHex(en_key == "" ? hmac_verify_key.toLatin1() : en_key.toLatin1()); - SM4_encrypt((u8 *)key.data(), 16, (u8 *)data, data->data_length + DATA_FRAME_PREFIX_LEN, zdata->data,&len); + SM4_encrypt((u8 *)key.data(), 16, data, data_len, zdata->data,&len,false); zdata->length = len + CRYPTO_ZDATA_FRAME_PREFIX_LEN; } -bool Protocol::zigbee_data_dectypt(data_frame *data, crypto_zdata_frame *zdata, - bool (* SM4_decrypt)(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len), +bool Protocol::zigbee_data_dectypt(uint8_t *data, uint8_t *data_len, crypto_zdata_frame *zdata, + bool (* SM4_decrypt)(u8 *key_origin, u32 key_len, u8 *in, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc), QString en_key) { int total_len = zdata->length; @@ -179,7 +179,8 @@ bool Protocol::zigbee_data_dectypt(data_frame *data, crypto_zdata_frame *zdata, return false; u32 len, msglen = total_len - CRYPTO_ZDATA_FRAME_PREFIX_LEN; QByteArray key = QByteArray::fromHex(en_key == "" ? hmac_verify_key.toLatin1() : en_key.toLatin1()); - SM4_decrypt((u8 *)key.data(), 16, zdata->data, msglen, (u8 *)data, &len); + SM4_decrypt((u8 *)key.data(), 16, zdata->data, msglen, data, &len,false); + *data_len = len; return true; } @@ -209,15 +210,12 @@ void Protocol::HMAC_identify(device *self, device *node, hmac_frame *hframe, } void Protocol::HMAC_changeVerifykey(u8 key[16], device* self, device *node, void (*sendTonode)(ZigbeeFrame &data), - bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len)) + bool (* SM4_encrypt)(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc)) { ZigbeeFrame zf(0x82,0x82,node->addr); - new_data_frame(16) data; - memset(&data, 0, sizeof(data)); - protocal_wrapper((data_frame *)&data, 0, 16, key, 0); new_crypto_zdata_frame(48) zdata; memset(&zdata, 0, sizeof(zdata)); - zigbee_data_encrypt((data_frame *)&data, (crypto_zdata_frame *)&zdata, SM4_encrypt); + zigbee_data_encrypt(key, 16, (crypto_zdata_frame *)&zdata, SM4_encrypt); new_base_frame(48 + BASE_FRAME_PREFIX_LEN) bframe; memset(&bframe, 0, sizeof(bframe)); base_frame_maker(&zdata, (base_frame *)&bframe, node->addr, self); diff --git a/app_source/source/zigbeeparser.cpp b/app_source/source/zigbeeparser.cpp index 0197024..8022ddf 100644 --- a/app_source/source/zigbeeparser.cpp +++ b/app_source/source/zigbeeparser.cpp @@ -149,12 +149,9 @@ void ZigBeeParser::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is if (_protocol->bytecmp(hframe->hmac,hmac,32)) { zigbee_protocol::ZigbeeFrame zf(0x82,0x82,node->first.addr); - new_data_frame(16) dframe; - memset(&dframe, 0, sizeof(dframe)); - _protocol->protocal_wrapper((data_frame *)&dframe, 0, 16, (u8*)latest_key.data(), 0); - new_crypto_zdata_frame(sizeof(dframe)) zdata; + new_crypto_zdata_frame(32) zdata; memset(&zdata, 0, sizeof(zdata)); - _protocol->zigbee_data_encrypt((data_frame *)&dframe, (crypto_zdata_frame *)&zdata, Crypto::SM4_encrypt, key_str); + _protocol->zigbee_data_encrypt((u8*)latest_key.data(), 16, (crypto_zdata_frame *)&zdata, Crypto::SM4_encrypt, key_str); new_base_frame(sizeof(zdata) + BASE_FRAME_PREFIX_LEN) bframe; memset(&bframe, 0, sizeof(bframe)); _protocol->base_frame_maker(&zdata, (base_frame *)&bframe, node->first.addr, &node->second); @@ -223,11 +220,12 @@ void ZigBeeParser::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is { zigbee_protocol::ZigbeeFrame dzf = zframe; new_data_frame(72) ndata; + uint8_t data_len = 0; memset(&ndata,0,sizeof(ndata)); if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD) { czdata = (crypto_zdata_frame*)frame; - _protocol->zigbee_data_dectypt((data_frame*)&ndata, czdata, Crypto::SM4_decrypt); + _protocol->zigbee_data_dectypt((uint8_t*)&ndata, &data_len, czdata, Crypto::SM4_decrypt); dzf.setData((char*)&ndata,ndata.data_length + DATA_FRAME_PREFIX_LEN); zdata = QByteArray((char *)dzf.data(), dzf.size()); object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper()))); @@ -237,7 +235,7 @@ void ZigBeeParser::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is object.insert("note_text",QJsonValue("收到节点0x"+sender+"发送的数据")); object.insert("recieved", true); object.insert("type","zigbee_recv_data"); - if (QRandomGenerator::global()->bounded(2) && is_demo) + if (QRandomGenerator::global()->bounded(2)!=0 && is_demo) object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper()))); _bus->push_data("zigbee_recv_data_view",object); }