ZigBee: Fix the pkg length overflow.

This commit is contained in:
Mentalflow 2024-02-24 23:42:47 +08:00
parent 21caf338eb
commit abbf3fc3cd
Signed by: Mentalflow
GPG Key ID: 5AE68D4401A2EE71
8 changed files with 57 additions and 51 deletions

View File

@ -61,9 +61,10 @@ ZigbeeFrame DLLN3X::recv(bool non_blocked)
bool DLLN3X::send(ZigbeeFrame zf) bool DLLN3X::send(ZigbeeFrame zf)
{ {
bool status = false; bool status = false;
if (zf.getSrcPort() < 0x80) uint8_t len = zf.size();
if (zf.getSrcPort() < 0x80 || (len + 4) > 63)
return false; return false;
status = _DSerial->write((char *)zf.data(),zf.size()); status = _DSerial->write((char *)zf.data(),len);
status = _DSerial->flush(); status = _DSerial->flush();
return status; 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) bool DLLN3X::send_cmd(uint8_t des_port, uint8_t arg, uint8_t* data, uint8_t data_length)
{ {
ZigbeeFrame zf(0x80, des_port, 0x0000); ZigbeeFrame zf(0x80, des_port, 0x0000);
if (data_length - 4 > 63 - 1) if (data_length + 4 > 63)
return false; return false;
zf.append(arg); zf.append(arg);
zf.addData(data, data_length); zf.addData(data, data_length);

View File

@ -24,8 +24,8 @@ public:
static void SM2_sign(u8 *pri, u8 *data, u32 datalen, u8 *out); 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 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 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_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); 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(); static uint8_t get_rand();
private: private:
Crypto(); Crypto();

View File

@ -22,12 +22,12 @@ public:
void (*sendToserver)(ZigbeeFrame &data), void (*sendToserver)(ZigbeeFrame &data),
void (*SM3_HMAC)(u8 *key, int keylen,u8 *input, int ilen,u8 output[32] )); 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), 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)); 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(data_frame *data, crypto_zdata_frame *zdata, 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 (* 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 = ""); QString en_key = "");
bool zigbee_data_dectypt(data_frame *data, crypto_zdata_frame *zdata, 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 (* 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 en_key = "");
QString hmac_verify_key = "11223344556677888877665544332211"; QString hmac_verify_key = "11223344556677888877665544332211";
QStringList pre_hmac_verify_key; QStringList pre_hmac_verify_key;

View File

@ -183,13 +183,13 @@ typedef struct login_resp
}login_resp; }login_resp;
#define SENSOR_DATA_TYPE 1 #define SENSOR_DATA_TYPE 1
#define SENSOR_DATA_LENGTN sizeof(double)*4 #define SENSOR_DATA_LENGTN sizeof(float)*4
typedef struct sensor_data typedef struct sensor_data
{ {
double ppm; float ppm;
double temp; float temp;
double humi; float humi;
double flare; float flare;
}sensor_data; }sensor_data;
#define THRESHOLD_DATA_TYPE 2 #define THRESHOLD_DATA_TYPE 2

View File

@ -373,8 +373,8 @@ RibbonTabBar {
} }
let repeat_count = 16 let repeat_count = 16
let t = `FF 29 ${get_rand_byte()}${get_rand_byte()} 83 23 32 `+ let t = `FF 29 ${get_rand_byte()}${get_rand_byte()} 83 56 56 `+
`AA AD 23 32 52 48 23 32 01 00 17 00 00 00 AA AA 01 10 00 FF FF ` `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;j<repeat_count;j++){ for (let j=0;j<repeat_count;j++){
t+=` ${get_rand_byte()}${get_rand_byte()}` t+=` ${get_rand_byte()}${get_rand_byte()}`
} }

View File

@ -163,16 +163,19 @@ void Crypto::SM3_HMAC(u8 *key, int keylen, u8 *input, int ilen, u8 *output)
sm3_hmac(key, keylen, input, ilen, output); sm3_hmac(key, keylen, input, ilen, output);
} }
bool Crypto::SM4_encrypt(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len) bool Crypto::SM4_encrypt(u8 *key_origin, u32 key_len, u8 *in_origin, u32 in_len, u8 *out, u32 *out_len, bool use_real_cbc)
{ {
struct sm4_ctx a; struct sm4_ctx a;
u32 max_len; u32 max_len;
u8 key[17] = { 0 }, *in = (u8 *)malloc(sizeof(u8) * (in_len + 16 * 2 + 1)); // 为保证C兼容性不使用智能指针 两个16分别是为首末尾填充留足留足空间1是冗余量 u8 key[17] = { 0 }, *in = (u8 *)malloc(sizeof(u8) * (in_len + 16 * 2 + 1)); // 为保证C兼容性不使用智能指针 两个16分别是为首末尾填充留足留足空间1是冗余量
u8 iv[17] = { u8 iv[17] = {
0x21, 0xBC, 0xC1, 0xEA, 0x0D, 0xB8, 0x54, 0x6D, 0xCE, 0xE4, 0xDB, 0x3C, 0xFA, 0xC1, 0x3C, 0xEF }, fix_len; // 此处为省时才用固定IV实际上此处IV必须是随机的才可真正保证SM4 CBC模式下加解密的强度 0x21, 0xBC, 0xC1, 0xEA, 0x0D, 0xB8, 0x54, 0x6D, 0xCE, 0xE4, 0xDB, 0x3C, 0xFA, 0xC1, 0x3C, 0xEF }, fix_len; // 此处为省时才用固定IV实际上此处IV必须是随机的才可真正保证SM4 CBC模式下加解密的强度
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) { if (key_len > 16) {
free(in); 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; fix_len = 16 - key_len;
memcpy(key, key_origin, 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) { if (key_len < 16) {
for (int i = key_len; i < 16; i++) { for (int i = key_len; i < 16; i++) {
key[i] = fix_len; key[i] = fix_len;
} }
} }
if (in_len % 16 != 0) { if (in_len % 16 != 0) {
max_len = ceil(in_len / 16.0)* 16 + 16; max_len = ceil(in_len / 16.0)* 16 + (use_real_cbc ? 16 : 0);
fix_len = max_len - 16 - in_len; fix_len = max_len - (use_real_cbc ? 16 : 0) - in_len;
for (u32 i = in_len + 16; i < max_len; i++) { for (u32 i = in_len + (use_real_cbc ? 16 : 0); i < max_len; i++) {
in[i] = fix_len; in[i] = fix_len;
} }
in_len = max_len; in_len = max_len;
} else { } 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[i] = 16;
} }
in_len += 16 * 2; in_len += 16 + (use_real_cbc ? 16 : 0);
} }
*out_len = in_len; *out_len = in_len;
sm4_cbc_encrypt(&a, key, iv, in, in_len, out); 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; 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; struct sm4_ctx b;
u32 fix_len; 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] = { u8 iv[17] = {
0x21, 0xBC, 0xC1, 0xEA, 0x0D, 0xB8, 0x54, 0x6D, 0xCE, 0xE4, 0xDB, 0x3C, 0xFA, 0xC1, 0x3C, 0xEF }; // 此处为省时才用固定IV实际上此处IV必须是随机的才可真正保证SM4 CBC模式下加解密的强度 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兼容性不使用智能指针 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) { if (key_len > 16) {
free(out_buf); 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); free(out_buf);
return false; return false;
} }
*out_len = in_len - fix_len - 16; *out_len = in_len - fix_len - (use_real_cbc ? 16 : 0);
memcpy(out, out_buf + 16, *out_len); memcpy(out, out_buf + (use_real_cbc ? 16 : 0), *out_len);
free(out_buf); free(out_buf);
return true; return true;
} }

View File

@ -159,19 +159,19 @@ bool Protocol::data_frame_verify(data_frame *frame)
return true; return true;
} }
void Protocol::zigbee_data_encrypt(data_frame *data, crypto_zdata_frame *zdata, 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 (* 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) QString en_key)
{ {
u32 len; u32 len;
zdata->head=CRYPTO_ZDATA_FRAME_HEAD; zdata->head=CRYPTO_ZDATA_FRAME_HEAD;
QByteArray key = QByteArray::fromHex(en_key == "" ? hmac_verify_key.toLatin1() : en_key.toLatin1()); 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; zdata->length = len + CRYPTO_ZDATA_FRAME_PREFIX_LEN;
} }
bool Protocol::zigbee_data_dectypt(data_frame *data, crypto_zdata_frame *zdata, 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 (* 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 en_key)
{ {
int total_len = zdata->length; int total_len = zdata->length;
@ -179,7 +179,8 @@ bool Protocol::zigbee_data_dectypt(data_frame *data, crypto_zdata_frame *zdata,
return false; return false;
u32 len, msglen = total_len - CRYPTO_ZDATA_FRAME_PREFIX_LEN; u32 len, msglen = total_len - CRYPTO_ZDATA_FRAME_PREFIX_LEN;
QByteArray key = QByteArray::fromHex(en_key == "" ? hmac_verify_key.toLatin1() : en_key.toLatin1()); 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; 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), 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); 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; new_crypto_zdata_frame(48) zdata;
memset(&zdata, 0, sizeof(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; new_base_frame(48 + BASE_FRAME_PREFIX_LEN) bframe;
memset(&bframe, 0, sizeof(bframe)); memset(&bframe, 0, sizeof(bframe));
base_frame_maker(&zdata, (base_frame *)&bframe, node->addr, self); base_frame_maker(&zdata, (base_frame *)&bframe, node->addr, self);

View File

@ -149,12 +149,9 @@ void ZigBeeParser::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is
if (_protocol->bytecmp(hframe->hmac,hmac,32)) if (_protocol->bytecmp(hframe->hmac,hmac,32))
{ {
zigbee_protocol::ZigbeeFrame zf(0x82,0x82,node->first.addr); zigbee_protocol::ZigbeeFrame zf(0x82,0x82,node->first.addr);
new_data_frame(16) dframe; new_crypto_zdata_frame(32) zdata;
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;
memset(&zdata, 0, sizeof(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; new_base_frame(sizeof(zdata) + BASE_FRAME_PREFIX_LEN) bframe;
memset(&bframe, 0, sizeof(bframe)); memset(&bframe, 0, sizeof(bframe));
_protocol->base_frame_maker(&zdata, (base_frame *)&bframe, node->first.addr, &node->second); _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; zigbee_protocol::ZigbeeFrame dzf = zframe;
new_data_frame(72) ndata; new_data_frame(72) ndata;
uint8_t data_len = 0;
memset(&ndata,0,sizeof(ndata)); memset(&ndata,0,sizeof(ndata));
if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD) if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD)
{ {
czdata = (crypto_zdata_frame*)frame; 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); dzf.setData((char*)&ndata,ndata.data_length + DATA_FRAME_PREFIX_LEN);
zdata = QByteArray((char *)dzf.data(), dzf.size()); zdata = QByteArray((char *)dzf.data(), dzf.size());
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper()))); 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("note_text",QJsonValue("收到节点0x"+sender+"发送的数据"));
object.insert("recieved", true); object.insert("recieved", true);
object.insert("type","zigbee_recv_data"); 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()))); object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
_bus->push_data("zigbee_recv_data_view",object); _bus->push_data("zigbee_recv_data_view",object);
} }