Funpack5-2 - 安全触摸验证平台
该项目使用了EV41C56A开发板、PTC 功能,实现了安全触摸的设计,它的主要功能为:安全 UART 通信进行远程命令,敏感操作需要用户在设备端完成 PTC 触摸确认的验证模型。
标签
Funpack活动
开发板
触摸
trustzone
clr
更新2026-06-17
45

一、 项目介绍

EV41C56A 基于 PIC32CM 微控制器,适合验证低功耗触摸交互与嵌入式安全控制。开发板结合MCU 内置的 PTC 功能,并设计了 QTouch 触摸按键,配合 driven shield 设计,可用于实现可靠的电容触摸检测、触摸确认、按键唤醒和人机交互控制。


在安全方面,PIC32CM LS00 系列支持 Arm TrustZone 硬件隔离,可将关键代码、密钥和外设访问划分到安全域中运行;同时具备安全启动、安全密钥存储、安全固件升级、硬件隔离、篡改防护以及对称/非对称加密能力。结合触摸输入,EV41C56A 非常适合构建“需要用户物理确认”的安全应用原型,例如安全解锁、加密通信确认、可信控制面板和防克隆外设认证。


项目目标:

  • 加密通信:上位机通过安全 UART 帧向 MCU 发送命令
  • 本地触摸确认:敏感操作需要用户在设备端完成 PTC 触摸确认;利用 QTouch 库实现电容触摸检测,支持触摸点亮/熄灭 LED、触摸状态查询。
  • LED 控制:通过 TCC0 WO5(PA15 引脚)PWM 驱动 LED,支持开/关、占空比调节和呼吸灯特效。
  • TrustZone 安全架构:密钥存储、加密运算、协议解析均在安全世界执行;非安全世界仅负责主循环调度和触摸库调用,通过 veneer 函数跨域通信。
  • 数字签名:PC 发送签名请求后,设备进入等待状态(LED 呼吸灯指示),用户双击触摸传感器确认后,设备使用 HMAC-SHA256 对请求数据(含 16 字节随机 nonce)签名并返回,PC 本地验签。


二. 设计思路


**安全通信协议设计:**
采用二进制帧格式 `SYNC(0x7E) + SEQ(2B) + LEN(2B) + ENVELOPE(N)`,其中 ENVELOPE`IV(16B) + CT(Zero-padded) + HMAC(32B)`。每条指令先用 AES-128-CBC 加密,再用 HMAC-SHA256 做完整性校验,实现 Encrypt-then-MAC 模式。

**序列号(SEQ)防重放机制:**
协议使用 16 位单调递增序列号实现防重放保护,具体策略如下:
- **发送端(host_tool)**:每次发送帧时 SEQ 自增 1(从 1 起始,到达 0xFFFF 后归 1)。序列号持久化存储在本地 `.host_tool_seq.json` 文件中,即使上位机重启也能从上次的 SEQ 继续递增,避免与设备端已记录的 SEQ 冲突。
- **接收端(设备)**:维护 `g_last_rx_seq` 变量记录最后一次成功解密的帧 SEQ。收到新帧时,若 `seq <= g_last_rx_seq && g_last_rx_seq != 0`,则判定为重放帧,直接返回 `RSP_ERROR(0x10)` 并丢弃,不执行任何操作。
- **仅解密成功后才更新**`g_last_rx_seq` 仅在 HMAC 校验和 AES 解密均成功后才更新为当前 SEQ。若解密失败(密钥错误、数据篡改),SEQ 不推进,确保攻击者无法通过发送无效帧来"消耗"序列号。
- **双向保护**:设备响应帧同样携带 SEQ(与请求帧相同),上位机可校验响应 SEQ 与请求 SEQ 是否一致,防止中间人替换响应。

三重防护协同工作:HMAC 保证数据完整性(防篡改),AES-CBC 保证机密性(防窃听),SEQ 单调递增保证新鲜性(防重放)。

**触摸签名流程:**
PC 发送 CMD_SIGN + nonce(16B) + data -> 设备 ACK -> LED 呼吸灯进入等待状态 -> 用户双击触摸传感器 -> 设备计算 HMAC-SHA256(CMD_SIGN || nonce || data) -> 返回 nonce(16B) + signature(32B) -> PC 验签。nonce 保证每次签名唯一,防止重放。

软件流程图:


Snipaste_2026-06-13_17-56-50.png


Snipaste_2026-06-13_17-58-25.png

三、实现过程

3.1 开发环境搭建

安装 MPLAB X IDE,和芯片对应的 xc 32 编译器,还有对应的mcc库(touch library等)


P5.png

3.2 外设配置与代码生成

将non-secure 工程设为main工程,MCC 添加所需要的所有库(如没有通过MC 添加):


Snipaste_2026-06-13_17-16-25.png

在plugin中配置引脚:查阅开发板schematic,得出需要使用的引脚:LED, 触摸引脚, driven shield 引脚 还有 UART 引脚(SERCOM3)。

Snipaste_2026-06-14_23-32-42.png


在 touch configuration 中配置 PTC 触摸按钮:添加圆形button,并设置对应的引脚,需要特别注意 PTC 时钟的 prescaler,蓝色为推荐值,确保实际采样值不会偏大。

Snipaste_2026-06-13_17-16-46.png

过低的 prescalear 会导致采样周期过短

Snipaste_2026-06-13_17-17-46.png

可选配置 driven shield pin 来获得更好的抗干扰能力


Snipaste_2026-06-13_17-20-15.png

LED PWM 为 TCC0 channel 1 控制:

Snipaste_2026-06-13_17-21-47.png

安全区域的调整在 trustzone plugin 中配置,默认都是在安全区域,通过 nonsecure_entry.h 中的函数进行调用。

最后通过 "generate" 自动生成代码。

3.3 主要代码实现

3.3.1 UART RX 状态机

帧格式 SYNC + SEQ(2) + LEN(2) + ENVELOPE 需要正确解析 5 字节帧头。早期版本跳过了 SEQ 字节,导致 LEN 被错误解析,host_tool 从未收到有效响应。

`c
#define S_IDLE 0u
#define S_SEQ_H 1u
#define S_SEQ_L 2u
#define S_LEN_H 3u
#define S_LEN_L 4u
#define S_DATA 5u


// 状态机轮询
while (uart_rx_ready()) {
uint8_t b = uart_rx_byte();
switch (g_proto_state) {
case S_IDLE:
if (b == FRAME_SYNC) { g_rx_pos = 0u; g_proto_state = S_SEQ_H; }
break;
case S_SEQ_H:
g_rx_seq = (uint16_t)b << 8; g_proto_state = S_SEQ_L; break;
case S_SEQ_L:
g_rx_seq |= (uint16_t)b; g_proto_state = S_LEN_H; break;
case S_LEN_H:
g_rx_target = (uint16_t)b << 8; g_proto_state = S_LEN_L; break;
case S_LEN_L:
g_rx_target |= (uint16_t)b;
if (g_rx_target == 0u || g_rx_target > FRAME_BUF_MAX)
g_proto_state = S_IDLE;
else { g_rx_pos = 0u; g_proto_state = S_DATA; }
break;
case S_DATA:
g_rx_buf[g_rx_pos++] = b;
if (g_rx_pos >= g_rx_target) process_frame();
break;
}
}
`


3.3.2 加密通信

所有通信使用 Encrypt-then-MAC 模式:先 AES-128-CBC 加密(Zero 填充),再 HMAC-SHA256 校验。

`c
uint32_t secure_encrypt_then_mac(
    const uint8_t *aes_key, const uint8_t *hmac_key, uint32_t hmac_key_len,
    const uint8_t *pt, uint32_t pt_len, uint8_t *out)
{
    uint8_t iv[16];  crya_random(iv);           // 硬件 TRNG 生成 IV
    uint32_t padded_len = ((pt_len + 15u) / 16u) * 16u;
    memcpy(out, iv, 16);                         // IV 在前
    crya_aes_encrypt_cbc(aes_key, 128, iv, pt, padded_len, out + 16);  // CT
    uint32_t ct_total = 16u + padded_len;
    crya_sha256(hmac_key, hmac_key_len, out, ct_total, out + ct_total); // HMAC
    return ct_total + 32u;
}
`


3.3.3 双击触摸检测 + 签名

签名等待期间 LED 呼吸灯指示,通过上升沿检测双击:

`c
if (g_sign_tap_count >= SIGN_TAPS_REQUIRED) {
uint8_t sig[32];
secure_hmac_sha256(DEV_HMAC_KEY, SESSION_HMAC_KEY_LEN,
g_sign_data, g_sign_data_len, sig);


    uint8_t resp_pt[49];
    resp_pt[0] = RSP_FLAG | CMD_SIGN;
    memcpy(&resp_pt[1], &g_sign_data[1], 16u);   // 回传 nonce
    memcpy(&resp_pt[17], sig, 32u);               // 签名
    // ... 加密发送 ...


}
`


3.3.4 共享触摸状态架构

为避免 touch_process() 被重复调用导致标志位丢失,引入安全/非安全共享变量:

`c
// secure_protocol.c - 安全世界定义
volatile uint8_t g_touch_raw_state;
volatile uint16_t g_touch_signal, g_touch_reference, g_touch_cc;


void secure_touch_update(void) {
if (measurement_done_touch != 0u) {
measurement_done_touch = 0u;
g_touch_raw_state = get_sensor_state(0u);
g_touch_signal = get_sensor_node_signal(0u);
}
}


// nonsecure_entry.c - 非安全世界调用
bool SECURE_Touch_TaskDebug(void) {
touch_process(); // 唯一调用点
secure_touch_update(); // 更新共享状态
return ((g_touch_raw_state & KEY_TOUCHED_MASK) != 0u);
}
`


3.3.5 呼吸灯实现(正弦波 LUT 查表)

采用正弦波查找表实现平滑呼吸效果,比三角波更自然。LUT 存储 48 个采样点,对应 duty = normalized(1 + sin(x)) 的一个完整周期,由 2*pi/3 到 2*pi 的正弦曲线生成。运行时根据 elapsed_ms 在 LUT 中线性插值索引,避免浮点运算

```c
/* duty = normalized (1 + sin(x)), x from 2*pi/3 to 2*pi */
static const uint16_t g_breath_lut[] = {
    2999u, 2922u, 2834u, 2737u, 2631u, 2517u, 2395u, 2267u,
    2134u, 1997u, 1857u, 1715u, 1571u, 1428u, 1287u, 1148u,
    1013u, 882u, 758u, 639u, 529u, 427u, 335u, 252u,
    181u, 121u, 72u, 36u, 12u, 1u, 2u, 17u,
    44u, 83u, 135u, 198u, 272u, 357u, 452u, 556u,
    668u, 788u, 914u, 1046u, 1183u, 1322u, 1464u, 1607u
};


static void update_breathing_led(uint32_t elapsed_ms) {
    uint32_t pos = elapsed_ms % BREATH_PERIOD_MS;  // 2000ms 周期
    uint32_t lut_count = sizeof(g_breath_lut) / sizeof(g_breath_lut[0]);
    uint32_t index = (pos * (lut_count - 1u)) / (BREATH_PERIOD_MS - 1u);
    led_set_duty(g_breath_lut[index]);  // 查表取 duty,无浮点运算
}
`


4 测试结果

4.1 安全通信测试

ping/led_on/led_off/status 等命令均通过加密通道通信,设备返回加密响应并由上位机解密验证,seq增加 防止重放。

image.png

4.2 触摸检测

触摸传感器时,LED 点亮;松开后 LED 熄灭

image.png

双击后锁定点亮 LED 等,再双击取消

image.png

4.3 数字签名(双击确认 + Nonce 防重放)

签名过程:设备 LED 呼吸灯指示等待状态 -> 用户双击触摸确认 -> 设备对 CMD_SIGN + nonce + data 计算 HMAC-SHA256 -> 返回 nonce + 签名 -> 上位机验签通过。

image.png


5 总结

本项目将电容触摸、PWM 控制、加密通信、数字签名、TrustZone 安全架构等多个技术点有机整合,形成了一个功能完整、安全可靠的嵌入式安全触摸签名系统。这次重点尝试了 microchip 的触摸功能的配置,重点在于控制采样原始值,让触摸时的电容变化足够显著。后续还可以在安全固件、安全启动等方面进行加固。


附件下载
touch.zip
源码
host_tool.zip
工具
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号