嵌入式系统安全编码规范(V1.2)
一、数据安全规范
1.1 变量初始化
规则编号 | 要求 | 示例代码(正确/错误) |
---|---|---|
DS-001 | 所有变量必须显式初始化 | int count = 0; ✔️ int count; ❌ |
DS-002 | 敏感数据使用后立即清零 | memset_s(pwd, sizeof(pwd), 0, sizeof(pwd)); ✔️ |
1.2 类型安全
c
// 错误示例:隐式类型转换
uint16_t a = 50000;
int16_t b = a; // 导致溢出 ❌
// 正确做法:显式范围检查
if (a <= INT16_MAX) {
b = (int16_t)a;
}
二、控制流安全
2.1 循环控制
c
// 错误示例:浮点循环控制
for (float f = 0.0; f != 10.0; f += 0.1) {} // 精度问题 ❌
// 正确做法:整数控制循环
for (int i = 0; i < 100; ++i) {
float f = i * 0.1f; // ✔️
}
2.2 分支预测安全
c
// 关键安全判断禁用优化
__attribute__((optimize("O0")))
bool is_system_safe(void) {
return check_sensors() && validate_state();
}
三、内存安全规范
3.1 静态内存分配
场景 | 配置方法 | 示例 |
---|---|---|
固定大小缓冲 | 使用sizeof计算长度 | char buf[64]; memset(buf, 0, sizeof(buf)); |
共享内存 | 添加magic number校验 | struct { uint32_t magic; ... } shm; |
3.2 栈保护机制
GCC栈保护配置:
makefile
CFLAGS += -fstack-protector-strong
CFLAGS += -Wstack-usage=1024 # 限制栈空间≤1KB
四、输入验证规范
4.1 数据来源验证
c
// ADC采样数据验证
#define ADC_MAX 4095 // 12-bit ADC
uint16_t validate_adc(uint16_t raw) {
if (raw > ADC_MAX) {
log_error("ADC溢出");
return ADC_MAX;
}
return raw;
}
4.2 消息协议验证
c
typedef struct {
uint8_t header[2]; // 0xAA 0x55
uint16_t crc;
uint8_t data[32];
} msg_packet_t;
bool validate_packet(const msg_packet_t *pkt) {
return (pkt->header[0] == 0xAA) &&
(pkt->header[1] == 0x55) &&
(crc16(pkt->data) == pkt->crc);
}
五、加密安全规范
5.1 密钥管理
存储位置 | 保护措施 |
---|---|
静态存储 | 芯片安全存储区(OTP/NVM) |
运行时内存 | 加密后存储,使用后立即清除 |
5.2 安全随机数
c
// 使用硬件TRNG生成密钥
uint32_t gen_secure_random(void) {
while (!RNG->SR & RNG_SR_DRDY); // 等待数据就绪
return RNG->DR;
}
六、工具链安全配置
6.1 编译器加固选项
makefile
# ARM GCC安全编译选项
CFLAGS += -Wformat-overflow=2 -Wformat-truncation=2
CFLAGS += -D_FORTIFY_SOURCE=2
LDFLAGS += -Wl,-z,now -Wl,-z,relro
6.2 静态分析配置
Cppcheck参数示例:
bash
cppcheck --enable=warning,style,performance,portability \
--suppress=unusedFunction \
--inline-suppr \
--force \
--std=c11 \
./src/
七、安全测试规范
7.1 单元测试要求
c
// 使用Unity测试框架示例
void test_buffer_overflow(void) {
char buf[4];
TEST_ASSERT_EQUAL(ERR_OK, safe_strcpy(buf, "test", sizeof(buf)));
TEST_ASSERT_EQUAL(ERR_OVERFLOW, safe_strcpy(buf, "overflow", sizeof(buf)));
}
7.2 模糊测试配置
python
# 使用AFL++进行协议模糊测试
afl_fuzz -i testcases/ -o findings/ \
-m 256 -t 50 \
-- \
./protocol_parser @@
八、安全异常处理
8.1 看门狗配置
c
// 安全喂狗模式
void critical_operation(void) {
IWDG->KR = 0xAAAA; // 喂狗
perform_operation();
IWDG->KR = 0xAAAA;
}
8.2 崩溃日志记录
c
__attribute__((noreturn))
void hard_fault_handler(void) {
struct CrashInfo {
uint32_t lr, pc, psr;
};
// 保存寄存器到非易失存储
save_crash_log((CrashInfo*)get_registers());
NVIC_SystemReset();
}
附录A:安全编码检查清单
- 所有数组访问都有边界检查
- 指针使用前验证非空
- 禁用危险函数(gets, sprintf等)
- 加密操作使用经过验证的库
- 安全敏感操作记录审计日志
附录B:参考标准
- MISRA C:2012 Amendment 1
- CERT C Secure Coding Standard
- ISO 26262-6:2018 软件安全要求
- UL 2900-1 网络安全标准
本规范应与《嵌入式系统安全设计指南》配合使用,所有安全关键项目必须通过TÜV功能安全认证。