3. 实现AES-128加密通信
任务定义
在MCU与外部主机之间的串口通信链路上,使用HSM模块的硬件AES-128引擎对应用层数据进行加解密。MCU发送方向:将明文数据通过HSM加密后经UART发出;接收方向:将UART收到的密文通过HSM解密还原为明文。本案例聚焦HSM加解密API的正确调用与数据格式组织,不涉及密钥协商与安全存储(密钥以固定数组形式预置)。
硬件连接与数据流
测试拓扑:MCU (HSM集成) UART_TX/RX ←→ USB-TTL ←→ PC串口助手
验证观测点:PC发送16字节密文→MCU解密后回传明文;PC发送16字节明文→MCU加密后回传密文。
验证观测点:PC发送16字节密文→MCU解密后回传明文;PC发送16字节明文→MCU加密后回传密文。
代码实现
以下代码基于STM32H5系列HSM驱动框架,使用固定测试密钥。核心函数hsm_aes_ecb_crypt完成单块加解密,主循环通过UART接收命令字节决定执行加密或解密操作。
/* hsm_aes_demo.c - HSM硬件AES-128 ECB加解密示例 */
#include "hsm_driver.h" /* HSM底层驱动 */
#include "uart_driver.h" /* UART收发驱动 */
#include <string.h>
/* 固定测试密钥(16字节 = AES-128) */
static const uint8_t test_key[16] = {
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};
/* HSM加解密函数封装
* mode: 0=加密, 1=解密
* in/out: 各16字节数据块
* 返回: 0成功, 非0失败
*/
static int hsm_aes_ecb_crypt(uint8_t mode, const uint8_t *in, uint8_t *out)
{
hsm_handle_t hsm;
hsm_status_t st;
/* 打开HSM会话 */
st = hsm_open(&hsm);
if (st != HSM_OK) return -1;
/* 加载密钥到HSM密钥槽 */
st = hsm_load_key(hsm, 0, test_key, 16);
if (st != HSM_OK) {
hsm_close(hsm);
return -2;
}
/* 执行硬件加解密 */
st = hsm_aes_ecb(hsm, 0, mode, in, out);
hsm_close(hsm);
return (st == HSM_OK) ? 0 : -3;
}
/* 主函数 */
int main(void)
{
uint8_t rx_buf[16];
uint8_t result[16];
uint8_t cmd;
int ret;
uart_init(115200);
hsm_init();
while (1) {
/* 等待接收1字节命令: 0x01=加密, 0x02=解密 */
if (uart_receive_byte(&cmd, 1000) != UART_OK) continue;
/* 接收16字节数据块 */
if (uart_receive_bytes(rx_buf, 16, 2000) != UART_OK) {
uart_send_string("ERR:TIMEOUT\r\n");
continue;
}
if (cmd == 0x01) {
ret = hsm_aes_ecb_crypt(0, rx_buf, result); /* 加密 */
} else if (cmd == 0x02) {
ret = hsm_aes_ecb_crypt(1, rx_buf, result); /* 解密 */
} else {
uart_send_string("ERR:CMD\r\n");
continue;
}
if (ret == 0) {
uart_send_bytes(result, 16); /* 回传处理结果 */
uart_send_string("\r\nOK\r\n");
} else {
uart_send_string("ERR:HSM\r\n");
}
}
}
编译与烧录
# 使用STM32CubeIDE或arm-none-eabi-gcc编译
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -O2 \
-I./drivers -I./hsm \
hsm_aes_demo.c ./drivers/uart_driver.c ./hsm/hsm_driver.c \
-o hsm_aes_demo.elf
# 通过ST-Link烧录
st-flash write hsm_aes_demo.elf 0x08000000
验证方法与判定标准
测试准备:PC安装串口助手(如SSCOM),配置115200-8-N-1。MCU上电后,HSM初始化完成即可开始测试。
加密验证:发送十六进制数据 01 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF(首字节0x01为加密命令,后16字节为明文)。预期MCU回传16字节密文后跟\r\nOK\r\n。使用相同密钥的软件AES工具(如OpenSSL)计算同一明文的ECB加密结果,应与回传密文完全一致。
解密验证:发送 02 + 上述加密得到的16字节密文。预期MCU回传原始明文 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF,证明解密正确。
判定标准:
- 加密回传密文与OpenSSL AES-128-ECB计算结果逐字节一致;
- 解密回传明文与最初发送的明文完全一致;
- 发送错误命令(如0x03)时,MCU回传
ERR:CMD; - 发送长度不足时,MCU回传
ERR:TIMEOUT。
预期输出示例(基于给定密钥与上述明文,由AES-128-ECB算法唯一确定):
加密命令发送: 01 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
MCU回传密文: 3A D7 7B B4 0D 7A 36 60 A8 9E CA F3 24 66 EF 97
解密命令发送: 02 3A D7 7B B4 0D 7A 36 60 A8 9E CA F3 24 66 EF 97
MCU回传明文: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
注:以上密文为算法确定性输出,实际运行时若密钥或明文不同则结果不同。