simple_encryption.h
源文件路径:
common/simple_encryption.h所属模块:common(通用工具库) 代码行数:23
1. 文件职责
本文件是 common/simple_encryption.c 的对外接口头文件,声明 EMS 自有的轻量流式加解密函数 Encrypt / decrypt 及三个算法常量。它服务于「局域网/私有服务器明文传输」这一场景:当 EMS 连接到自建/测试服务器(NET_PRIVATE_ENCRYPTED,见 midware/ethernt/ethernet.c:1609-1619 的服务器表)时,网络层用一个固定的私有密钥对协议帧的数据域做逐字节混淆,作为 TLS 之外的最低成本私密性保护。本文件被中间件以太网发送侧(midware/ethernt/ethernet.c)与网络应用层接收侧(net/server.c)成对使用,只处理数据域,帧头与 CRC 保持明文。本文件不含实现、不含状态,只提供宏与原型;它还会通过 #include "chip.h" 把 GD32 寄存器定义间接引入包含者。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
__SIMPLE_ENCRYPTION_H__ | 宏 | include guard(第 9-10 行) |
SIMPLE_KEY_C1 | 宏 | 26529,密钥递推乘数(第 15 行)。奇数,保证模 2^32 映射为双射;属算法常量而非「密钥」,代码里是硬编码明文 |
SIMPLE_KEY_C2 | 宏 | 87282,密钥递推加数(第 16 行) |
SIMPLE_KEY_CRYPTKEY | 宏 | 42529,密钥初值(第 17 行),加解密双方必须一致 |
Encrypt | 函数原型 | void Encrypt(char *src, char *dst, int len),加密,定义于 simple_encryption.c:29 |
decrypt | 函数原型 | void decrypt(char *src, char *dst, int len),解密,定义于 simple_encryption.c:56 |
本文件不定义结构体、枚举、联合体、位域。三个宏都是裸整型常量,没有括号包裹(如 (26529)),作为算术操作数参与运算时(乘法、加法)不会产生优先级问题,但不符合「宏参数加括号」的惯例。
3. 函数清单
| 函数名 | 作用域 | 说明 |
|---|---|---|
Encrypt | 全局(原型声明) | 流式加密,逐字节异或 + 状态递推,支持就地操作 |
decrypt | 全局(原型声明) | 流式解密,与 Encrypt 对称,支持就地操作 |
共 2 个原型声明,分别对应 simple_encryption.c 的两个全局定义;本头文件没有 static 函数、没有宏函数。
4. 核心逻辑解析
本文件是纯声明文件,无可执行逻辑、无状态机、无定时器、不涉及 uCOS-II。要点在接口契约:
4.1 命名与用途的错配
加密函数名是首字母大写的 Encrypt,解密函数名是全小写的 decrypt(第 20-21 行),与工程普遍使用的大驼峰/下划线风格都不一致,且两者不成对。头文件的注释模板里 @author :Alpha g_stEMSInfo Team 中的 g_stEMSInfo 被误写成文档名,说明该文件是从别处拷贝改名而来。
4.2 固定密钥、无协商机制
三个宏(乘数、加数、初值)全部硬编码在头文件里,所有 EMS 设备共用同一套密钥,不存在按设备 SN 派生或在线协商的过程(对比 common/aes.c 的 PUBLIC_KEY + 一机一密私钥流程)。因此该加密只能抵御「无意的文本可读性」,不能抵御知道固件的人。
4.3 就地(in-place)调用的接口约定
两个函数的 src / dst 允许指向同一缓冲。工程内 3 处调用点全部是就地调用:
midware/ethernt/ethernet.c:581:Encrypt(&msg->pu8Info[7], &msg->pu8Info[7], (msg->u32Len - 9))midware/ethernt/ethernet.c:796:同上(无线通道分支)net/server.c:6414:decrypt((char *)&g_au8NetRecvPack[7], (char *)&g_au8NetRecvPack[7], (l_u32PackLen - 9))
这条「就地安全」的性质由实现保证(读先于写),但头文件里没有注释说明,属隐式契约,改动实现时极易破坏。
4.4 长度语义
len 是数据域字节数,不等于整帧长度:调用方统一用 总长度 - 9 计算,即扣掉 7 字节帧头与 2 字节 Modbus CRC。头文件没有给出这个约定,len 与协议帧结构的关系完全靠调用方维护。
5. 对外接口
本文件导出(供谁调用)
- 宏:
SIMPLE_KEY_C1、SIMPLE_KEY_C2、SIMPLE_KEY_CRYPTKEY - 函数:
Encrypt、decrypt - 调用方:
midware/ethernt/ethernet.c:581、:796(发送方向加密,#include见第 25 行)net/server.c:6414(接收方向解密,#include见第 45 行)data/resume_data/flash/flash_data_store.c:26(仅#include,文件中未调用Encrypt/decrypt,属无用 include)
本文件调用的外部函数/变量
- 无。头文件只 include
chip.h。
6. 依赖关系
- 依赖:
system/sys/chip.h(第 13 行),后者又 includegd32f4xx.h。也就是说,任何包含simple_encryption.h的 .c 都会被强制引入 GD32F4xx 全量寄存器定义;对net/、data/这类应该与硬件解耦的层来说是不必要的耦合。 - 被依赖:
common/simple_encryption.c、midware/ethernt/ethernet.c、net/server.c、data/resume_data/flash/flash_data_store.c(仅 include)。工程 Keil 目标user/EMS_3_0.uvprojx中包含simple_encryption.c,参与编译。
7. 备注与风险点
chip.h是无谓依赖:本文件的接口只用char/int,不需要任何 GD32 类型或寄存器定义;#include "chip.h"会把gd32f4xx.h灌进每一个包含者,拉长编译时间并让通用工具层反向依赖硬件层。若需要u8等短类型,用includes.h或直接内建类型更合适。- 密钥硬编码、全机共用(第 15-17 行):任何拿到固件的人都能解密私有服务器通道。属设计层面的已知弱点,不是笔误。
- 命名不成对:
Encrypt与decrypt大小写风格不一致,静态检索时容易漏掉一个;建议统一为simple_encrypt/simple_decrypt或Encrypt/Decrypt。 - 宏未加括号:三个宏都是裸数字,当前只参与
*与+,无实际风险;但与工程其它头文件(如SIMPLE_KEY_C1同目录的crc.h无宏、aes.h的Nb也无括号)风格一致地「宽松」,属集体习惯问题。 @author注释残留错误:/ @author :Alpha g_stEMSInfo Team中g_stEMSInfo是变量名而非团队名,说明该注释由变量替换误产生。- 无数据长度上限与缓冲长度参数:接口只有
len,没有dstSize,无法在函数内部防止越界写;安全性完全依赖调用方传入的len正确(见simple_encryption.c第 7 节)。