MCU 安全飞地内的推理执行方案设计:利用 TrustZone 保护模型权重和中间特征的安全架构 MCU 安全飞地内的推理执行方案设计利用 TrustZone 保护模型权重和中间特征的安全架构一、边缘推理的核心安全矛盾计算效率与数据保护如何在MCU上共存MCU上运行AI推理已成为趋势——从关键词唤醒到异常震动检测模型被广泛部署在资源极其受限的节点上。但一个根本性矛盾在最近几年愈发突出为了在Cortex-M级别的芯片上跑推理模型权重必须常驻在Flash或SRAM中而物理攻击者可以通过JTAG、调试探针甚至芯片拆解直接读取这些存储介质。更棘手的是推理过程中产生的中间特征图谱同样包含模型的结构信息攻击者可以通过多次注入输入、收集中间特征来实施模型窃取攻击。安全飞地方案试图在同一个物理核心上创建一个可信执行环境TEE将敏感的计算过程和数据进行硬件级隔离。ARM TrustZone for ARMv8-MTrustZone-M是实现这一目标的主要候选。它不增加额外的物理核心而是在现有Cortex-M内核上通过硬件扩展实现安全世界与非安全世界的分区。本文将详细阐述如何利用TrustZone-M构建MCU上的安全推理飞地。二、TrustZone-M 安全推理飞地的架构设计与内存分区策略基于TrustZone-M的安全推理飞地其核心设计思路是将模型权重的存储、加载、推理计算和中间特征的生命周期完全限制在安全世界中。非安全世界只能通过明确定义的API接口向安全世界提交输入数据、获取推理结果而不能接触到模型相关的任何数据。内存分区策略是设计的第一步。以256KB SRAM的Cortex-M33为例安全世界分配64KB用于存储模型权重、中间特征缓冲区和安全堆栈非安全世界分配192KB用于传感器驱动、协议栈和用户应用。IDAUImplementation Defined Attribution Unit和SAUSecurity Attribution Unit共同决定了每个内存地址在运行时的安全属性。graph TB subgraph 非安全世界_NS A1[传感器数据采集br/ADC/I2C驱动] -- A2[输入预处理br/归一化/量化] A2 -- A3[NSC调用接口br/输入数据传递] A5[协议栈/WiFi/BLE] -- A6[结果后处理br/应用逻辑] A6 -- A4[NSC调用接口br/结果获取] end subgraph 安全世界_S B1[SG接口: 安全入口br/指针校验权限检查] B1 -- B2[权重解密模块br/Flash→SRAMbr/AES-CTR解密] B2 -- B3[推理执行引擎br/Conv/FC/Softmaxbr/算子调度] B3 -- B4[中间特征缓冲区br/推理结束后零化] B4 -- B5[结果加密输出br/反量化封装] B5 -- B6[SG出口: 返回结果br/清理寄存器] end A3 -- B1 B6 -- A4 subgraph 物理存储 C1[安全Flash分区br/加密权重签名] C2[安全SRAM分区br/权重明文特征br/SAUSecure] C3[非安全Flashbr/应用固件] C4[非安全SRAMbr/传感器缓冲] end C1 -- B2 C2 -- B3 C3 -- A2 C4 -- A1 subgraph 硬件隔离 D1[SAU/IDAUbr/地址空间分区] D2[总线矩阵过滤br/AHB5安全扩展] end D1 -.-|内存访问属性br/实时判定| B2 D1 -.-|阻止非安全访问| C2 D2 -.-|总线级过滤br/硬件阻止非法访问| C2时序上一次完整的推理调用如下非安全世界采集传感器数据后通过NSCNon-Secure Callable入口调用安全世界。安全世界在入口处首先执行严格的参数校验使用cmse_check_address_range验证指针合法性然后从安全Flash中加载并解密模型权重到安全SRAM执行推理计算将输出结果写入非安全世界可访问的共享缓冲区最后执行安全世界的内存清理——将所有中间特征和权重明文从SRAM中擦除清除通用寄存器内容然后通过BXNS指令返回非安全世界。三、生产级安全推理飞地的完整实现/* * 安全推理飞地核心实现非安全世界通过NSC入口触发推理。 * 该函数编译在安全世界Flash中由IDAU标记为Secure属性。 * 所有内部使用的缓冲区均通过MPU/SAU配置为Secure-only访问。 */ #include arm_cmse.h #define INFERENCE_BUF_SIZE (32768) /* 32KB推理工作缓冲区 */ #define MAX_INPUT_SIZE (1024) /* 最大输入数据1KB */ #define MAX_OUTPUT_SIZE (256) /* 最大输出结果256B */ /* 安全世界内部状态机 */ typedef enum { SEC_STATE_IDLE 0, /* 空闲等待推理请求 */ SEC_STATE_LOADING 1, /* 正在从Flash加载权重 */ SEC_STATE_INFERRING 2, /* 推理执行中 */ SEC_STATE_ERROR 3, /* 错误状态需要复位 */ } SecureInferenceState; /* 非安全世界通过NSC入口调用此函数 */ __attribute__((cmse_nonsecure_entry)) int secure_inference_dispatch( const uint8_t* input_data, /* 非安全世界的输入数据指针 */ uint32_t input_len, uint8_t* output_buf, /* 非安全世界的输出缓冲区 */ uint32_t output_len) { static SecureInferenceState g_state SEC_STATE_IDLE; /* 第1层防护指针安全属性校验 * 非安全世界的代码可能被恶意篡改传入的指针可能指向安全内存区域。 * cmse_check_address_range硬件检查指针指向的地址是否属于非安全区域 * 若不通过则返回NULL后续逻辑拒绝继续执行。 */ if (cmse_check_address_range((void*)input_data, input_len, CMSE_MPU_NONSECURE | CMSE_MPU_READ) NULL) { return SEC_ERR_INVALID_INPUT_PTR; /* -10 */ } if (cmse_check_address_range((void*)output_buf, output_len, CMSE_MPU_NONSECURE | CMSE_MPU_READWRITE) NULL) { return SEC_ERR_INVALID_OUTPUT_PTR; /* -11 */ } /* 输入长度上线校验防止非安全世界传入过大值导致溢出 */ if (input_len 0 || input_len MAX_INPUT_SIZE) { return SEC_ERR_INPUT_SIZE; /* -12 */ } if (output_len 0 || output_len MAX_OUTPUT_SIZE) { return SEC_ERR_OUTPUT_SIZE; /* -13 */ } /* 第2层防护状态机互斥 * 安全世界不支持并发推理同一时间只能有一个推理请求在执行。 * 若上一个请求尚未完成例如安全世界线程未返回拒绝新请求。 */ if (g_state ! SEC_STATE_IDLE) { /* 安全世界正忙可能是上一个请求因异常未完成清理 */ return SEC_ERR_BUSY; /* -14 */ } g_state SEC_STATE_LOADING; /* 第3层安全世界内存分配从安全堆中 */ uint8_t* work_buf sec_heap_alloc(INFERENCE_BUF_SIZE); if (work_buf NULL) { g_state SEC_STATE_ERROR; return SEC_ERR_NO_MEM; /* -15 */ } /* 第4层从安全Flash加载并解密模型权重 * 权重以AES-CTR加密形式存储在安全Flash分区 * 密钥存放在芯片内部密钥存储区外部无法读取。 */ int ret secure_load_weights(work_buf, INFERENCE_BUF_SIZE); if (ret ! 0) { sec_heap_free(work_buf); g_state SEC_STATE_ERROR; return SEC_ERR_WEIGHT_LOAD; /* -16 */ } g_state SEC_STATE_INFERRING; /* 第5层执行推理计算 * 推理过程中所有的中间变量和特征图均存储在安全SRAM中 * SAU/IDAU配置确保非安全世界无法通过DMA或总线窥探访问这些数据。 */ ret secure_run_inference( input_data, input_len, work_buf, INFERENCE_BUF_SIZE, output_buf, output_len); if (ret ! 0) { /* 推理失败安全世界的缓冲区仍需清理 */ secure_wipe_buffer(work_buf, INFERENCE_BUF_SIZE); sec_heap_free(work_buf); g_state SEC_STATE_ERROR; return SEC_ERR_INFERENCE_FAIL; /* -17 */ } /* 第6层推理后安全清理防御内存残留攻击 * 攻击者可能在后续通过非安全世界读取之前分配给安全世界的SRAM地址。 * 推理完成后必须将包含模型权重和中间特征的缓冲区全部零化。 * 使用volatile指针防止编译器将memset优化为无效代码。 */ secure_wipe_buffer(work_buf, INFERENCE_BUF_SIZE); sec_heap_free(work_buf); /* 清除状态机 */ g_state SEC_STATE_IDLE; return 0; } /* 安全世界内部的内存清理函数使用DSB确保写入完成 */ static void secure_wipe_buffer(void* buf, size_t len) { if (buf NULL || len 0) return; volatile uint8_t* p (volatile uint8_t*)buf; for (size_t i 0; i len; i) { p[i] 0x00; } /* * 数据同步屏障(DSB)确保所有内存写入在函数返回前完成 * 而非仅仅刷新到写缓冲区中。防止攻击者在DSB之前读取到未清零的数据。 */ __DSB(); }四、安全飞地方案的架构边界与代价分析内存开销安全飞地需要独立的安全世界堆栈通常512B~2KB以及推理工作缓冲区取决于模型大小以MobileNetV1为例约需32KB。在128KB SRAM的Cortex-M33上安全飞地占用的SRAM约为35%~45%。时延开销TrustZone世界切换的单次开销约为20~30个时钟周期NSC入口15周期BXNS返回10周期在96MHz下约为0.3us。对推理总时延的增量几乎可以忽略。但推理过程中禁用非安全世界中断的时间段需要严格控制在微秒级别。TrustZone-M不可用的场景与替代方案Cortex-M0/M0不支持TrustZone。可使用外置安全芯片ATECC608A做密钥管理配合软件实现的权重混淆作为降级方案Cortex-M4/M7无TrustZone但通常有MPU。可利用MPU做地址空间访问控制但缺乏安全状态隔离超低功耗场景TrustZone的硬件逻辑持续消耗约2-5μA静态电流对纽扣电池供电设备可能有续航影响攻击面的残余风险冷启动攻击SRAM数据在断电后并非立即消失攻击者通过低温冻结芯片可延长残留时间可能读取安全世界残留数据故障注入通过精确的电压毛刺或时钟毛刺可能诱导处理器在安全世界入口检查处跳过校验五、总结利用ARM TrustZone-M构建MCU安全推理飞地可以实现在不增加额外硬件成本的前提下对模型权重、推理过程和中间特征进行硬件级保护。实现方案的核心要素包括合理的内存分区方案建议安全世界不低于64KB SRAM、严格的NSC入口参数校验、推理完毕后对安全世界缓冲区的强制性清理、以及IDAU/SAU配置的出厂锁定。该方案的直接优势在于保护强度与硬件隔离能力但代价是SRAM占用增加约40%和安全启动链的额外构建工作量。对于部署了高价值模型如自研算法、训练投入超过100GPU小时的MCU产品安全飞地方案的工程投入是可接受的。对于模型价值低、设备容易被替换的场景构建完整安全飞地的成本可能不划算。