WIZnet W55MH32 的 TLS 硬件加密功能说明
更新于 2026年9月23日
本篇总结
W55MH32 基于 DES、AES、SHA 硬件加密引擎和 TRNG,通过 SDK 移植的 mbedTLS 库实现 TLS 1.2 安全通信,演示通过 HTTPS 获取百度网页内容。
硬件平台:本例程基于 W55MH32L-EVB 开发板运行。
采购推荐:点击前往 WIZnet 官方淘宝店铺 选购 W55MH32L-EVB
本示例演示 W55MH32 利用内置 AES、SHA、TRNG 硬件加密模块配合 MbedTLS 库实现 TLS 1.2 安全通信,通过 HTTPS 访问百度网站验证加密数据传输功能。
前置工具准备
W55MH32 硬件加密简介
W55MH32 是一款由 WIZnet 设计的增强型 32 位微控制器,拥有 216MHz 处理器核心、1024KB Flash 和 96KB SRAM,内置 DES、AES、SHA 硬件加密算法单元和真随机数发生器(TRNG),可卸载加密计算任务,配合硬连线 TCP/IP 协议栈为 TLS 1.2 安全通信提供硬件加速。
- TLS 握手四阶段:Client Hello(TRNG 随机数 + 密码套件)→ Server Hello(证书 + DH 公钥)→ 密钥交换(SHA 验证证书)→ ChangeCipherSpec + Finished
- 硬件分工:TRNG 生成随机数与密钥,SHA 验证证书签名与计算 MAC,AES 加解密应用数据
- 安全三要素:数据加密保障机密性、消息认证码(MAC)保障完整性、数字证书和签名保障真实性
硬件模块分工
AES 硬件负责对称加密/解密应用数据;SHA 硬件负责证书签名验证和消息认证码计算;TRNG 负责生成真随机数(Client/Server 随机数、预主密钥);TOE 引擎提供底层硬连线 TCP/IP 协议栈支撑。
硬件连接与拓扑
请注意:
测试需要 PC 端和 W55MH32 处于同一网段,且需能访问互联网。
- Micro USB 线连接 DEBUG USB 口到 PC(供电 + 调试串口)
- 网线连接开发板 RJ45 网口 到路由器 LAN 口
│ 路由器(DHCP Server) │
│ 192.168.1.1 │
└────┬──────────────────┬───────────┘
│ │
┌────┴──────┐ ┌────┴──────┐
│ W55MH32 │ │ PC │
│ TLS Client│ │ 百度HTTPS │
│ IP: DHCP │ │ IP: DHCP │
└───────────┘ └───────────┘
↑ ↑
DEBUG USB ──→ WIZ UartTool
工程结构
工程位于 SDK 内 1.SDK\ModuleDemo\WZTOE\TLS\,核心文件如下:
TLS/
├── Project/
│ └── Project.uvprojx ← Keil 工程文件
└── USER/
├── main.c ← 网络初始化 + TLS 连接 + HTTPS 请求
└── wiz_tls.c/h ← TLS 封装函数(wiz_tls_init/connect/read/write)
步骤1:硬件与网络设置
文件:USER/main.c — 初始化 W55MH32 的以太网 MAC 和 PHY 建立物理连接,配置硬件 TCP/IP 协议栈进行网络通信。
/* network information */
wiz_NetInfo default_net_info = {
.mac = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12},
.ip = {10, 0, 1, 140},
.gw = {10, 0, 1, 254},
.sn = {255, 255, 255, 0},
.dns = {8, 8, 8, 8},
.dhcp = NETINFO_DHCP
};定义三个变量:ethernet_buf 作为网络数据收发缓冲区,ssl_target_ip 指定百度服务器的目标 IP 地址,tlsContext 用于维护 TLS 连接的所有状态和配置信息。
uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0};
uint8_t ssl_target_ip[4] = {220, 181, 111, 1}; /* baidu */
wiz_tls_context tlsContext;初始化硬件、加密模块、TRNG、定时器,初始化 wiztoe 并检查 PHY 链接,最后初始化网络。
/* hardware initialization */
rcc_clk_config();
delay_init();
console_usart_init(115200);
printf("W55MH32 TLS Example\r\n");
/* hardware crypt initialization */
*(uint32_t *)(0x400210F0) = 0x01;
*(uint32_t *)(0x40016C00) = 0xCDED3526;
*(uint32_t *)(0x40016CCC) = 0x07;
/* hardware TRNG enable */
TRNG_Out(ENABLE);
tim3_init();
/* wiztoe init */
wiz_toe_init();
getSHAR(default_net_info.mac);
wiz_phy_link_check();
network_init(ethernet_buf, &default_net_info);硬件加密初始化
0x400210F0 = 0x01 开启加密模块时钟,0x40016C00 = 0xCDED3526 解锁 SYSCFG,TRNG_Out(ENABLE) 开启真随机数发生器,tim3_init() 为 MbedTLS 提供定时器支持。
步骤2:TLS 安全连接建立
文件:USER/main.c — 获取加密库版本信息,创建 SSL Socket 并初始化 TLS 上下文,通过 TCP 连接到目标服务器 443 端口,完成 TLS 握手。
uint32_t ver = wiz_crypt_version();
printf("WIZnet CARD Secure Test Demo V1.0, secure lib version is V%02x.%02x.%02x.%02x\n",
ver >> 24, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
printf("WIZnet CARD Crypt Test V1.0 start......\r\n");
/* open socket */
wiz_tls_socket(&tlsContext, SOCKET_SSL_ID, LOCAL_PORT);
/* tls init */
wiz_tls_init(&tlsContext, 2000, (char *)ssl_target_ip, NULL, NULL, NULL);
/* connect server */
connect(tlsContext.socket_fd, (uint8_t *)ssl_target_ip, SSL_TARGET_PORT);
/* tls handshake */
wiz_tls_connect(&tlsContext, (char *)ssl_target_ip, SSL_TARGET_PORT);
printf("W55MH32 MbedTLS Transmission test start......\r\n");步骤3:TLS 初始化与握手
文件:USER/wiz_tls.c — wiz_tls_init 函数初始化 TLS 客户端连接,参数包括 TLS 上下文、接收超时、目标服务器域名/IP、根证书、客户端证书和私钥。
int wiz_tls_init(wiz_tls_context *tlsContext, uint32_t recv_timeout,
char *domain_name, char *root_ca,
char *client_cert, char *pkey)
{
int ret = 1;
const char *pers = "ssl_client1";
/* Initialize session data */
tlsContext->entropy = malloc(sizeof(mbedtls_entropy_context));
tlsContext->ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
tlsContext->ssl = malloc(sizeof(mbedtls_ssl_context));
tlsContext->conf = malloc(sizeof(mbedtls_ssl_config));
tlsContext->cacert = malloc(sizeof(mbedtls_x509_crt));
tlsContext->clicert = malloc(sizeof(mbedtls_x509_crt));
tlsContext->pkey = malloc(sizeof(mbedtls_pk_context));
mbedtls_entropy_init(tlsContext->entropy);
mbedtls_ctr_drbg_init(tlsContext->ctr_drbg);
mbedtls_ssl_init(tlsContext->ssl);
mbedtls_ssl_config_init(tlsContext->conf);
mbedtls_x509_crt_init(tlsContext->cacert);
/* Seed the random number generator */
ret = mbedtls_ctr_drbg_seed(tlsContext->ctr_drbg, mbedtls_entropy_func,
tlsContext->entropy,
(const unsigned char *)pers, strlen(pers));
/* Parse CA root certificate */
if (root_ca != NULL) {
ret = mbedtls_x509_crt_parse(tlsContext->cacert,
(const unsigned char *)root_ca, strlen(root_ca) + 1);
if (ret < 0) {
printf("mbedtls_x509_crt_parse returned -0x%x\r\n", -ret);
return -1;
}
mbedtls_ssl_set_hostname(tlsContext->ssl, domain_name);
tlsContext->root_ca_option = MBEDTLS_SSL_VERIFY_REQUIRED;
} else {
tlsContext->root_ca_option = MBEDTLS_SSL_VERIFY_NONE;
}
/* Configure SSL defaults */
mbedtls_ssl_config_defaults(tlsContext->conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
mbedtls_ssl_conf_authmode(tlsContext->conf, tlsContext->root_ca_option);
mbedtls_ssl_conf_ca_chain(tlsContext->conf, tlsContext->cacert, NULL);
mbedtls_ssl_conf_rng(tlsContext->conf, SSLRandomCB, tlsContext->ctr_drbg);
mbedtls_ssl_conf_read_timeout(tlsContext->conf, recv_timeout);
mbedtls_ssl_setup(tlsContext->ssl, tlsContext->conf);
mbedtls_ssl_set_bio(tlsContext->ssl, (void *)tlsContext->socket_fd,
SSLSendCB, SSLRecvCB, SSLRecvTimeOutCB);
return 1;
}测试中设置了 2 秒超时和目标服务器 IP,但未配置证书验证参数(root_ca、client_cert、pkey 均为 NULL)。
/* tls init */
wiz_tls_init(&tlsContext, 2000, (char *)ssl_target_ip, NULL, NULL, NULL);TLS 握手过程中,TRNG_Out 函数通过开启或关闭 TRNG 模块,为 TLS 握手提供必要的真随机数来源,保障密钥生成等安全操作所需的随机熵源。
/**
* @brief TRNG_Out
* @param NewState: ENABLE or DISABLE
* @retval None
*/
void TRNG_Out(FunctionalState NewState)
{
if (NewState != DISABLE)
{
RCC->RCC_SYSCFG_CONFIG = 0x01;
SYSCFG->SYSCFG_LOCK = 0xCDED3526;
SYSCFG->SSC_CLK_EN |= TRNG_RNG_ENABLE;
}
else
{
RCC->RCC_SYSCFG_CONFIG = 0x00;
SYSCFG->SSC_CLK_EN &= ~TRNG_RNG_ENABLE;
}
}wiz_tls_connect 是 TLS 客户端核心函数,通过循环调用 mbedtls_ssl_handshake 处理握手流程,握手成功后输出协商的加密套件。
int wiz_tls_connect(wiz_tls_context *tlsContext, char *addr, unsigned int port)
{
int ret;
uint32_t flags;
printf(" Performing the SSL/TLS handshake...\r\n");
while ((ret = mbedtls_ssl_handshake(tlsContext->ssl)) != 0)
{
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf(" failed! mbedtls_ssl_handshake returned -0x%x\n\r", -ret);
return (-1);
}
delay_ms(10);
}
if (tlsContext->root_ca_option == MBEDTLS_SSL_VERIFY_REQUIRED)
{
printf(" . Verifying peer X.509 certificate...\r\n");
if ((flags = mbedtls_ssl_get_verify_result(tlsContext->ssl)) != 0)
{
char vrfy_buf[512];
printf("failed\r\n");
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
printf("%s\r\n", vrfy_buf);
return -1;
}
else
{
printf("ok\r\n");
}
}
printf(" ok\n\r [ Ciphersuite is %s ]\n\r",
mbedtls_ssl_get_ciphersuite(tlsContext->ssl));
return (0);
}mbedtls_ssl_handshake 是 mbedTLS 库中执行 SSL/TLS 握手协议的核心实现,通过循环调用握手步骤函数完成加密参数协商、密钥交换和身份验证等过程。
/*
* Perform the SSL handshake
*/
int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl)
{
int ret = 0;
/* Sanity checks */
if (ssl == NULL || ssl->conf == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
/* Main handshake loop */
while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
ret = mbedtls_ssl_handshake_step(ssl);
if (ret != 0) break;
}
return ret;
}步骤4:安全通信
文件:USER/wiz_tls.c — 握手完成后,所有数据通过加密通道收发。核心是调用 wiz_tls_write(加密发送)和 wiz_tls_read(加密接收),AES 和 SHA 硬件处理加密解密和完整性检查。
unsigned int wiz_tls_read(wiz_tls_context *tlsContext, unsigned char *readbuf, unsigned int len)
{
return mbedtls_ssl_read(tlsContext->ssl, readbuf, len);
}
unsigned int wiz_tls_write(wiz_tls_context *tlsContext, unsigned char *writebuf, unsigned int len)
{
return mbedtls_ssl_write(tlsContext->ssl, writebuf, len);
}通过已建立的 TLS 安全连接向百度服务器发送 HTTP GET 请求获取网页内容,并在无限循环中持续接收和打印服务器返回的响应数据。
printf("W55MH32 get baidu.com html content......\r\n");
mbedtls_ssl_conf_read_timeout(tlsContext.conf, 200);
sprintf(ethernet_buf,
"GET / HTTP/1.1\r\nHost: www.baidu.com\r\n"
"User-Agent: W55MH32/1.0\r\nAccept: text/html\r\n"
"Connection: close\r\n\r\n");
wiz_tls_write(&tlsContext, (unsigned char *)ethernet_buf, strlen(ethernet_buf));
while (1)
{
recv_len = wiz_tls_read(&tlsContext, ethernet_buf, ETHERNET_BUF_MAX_SIZE - 1);
if (recv_len > 0)
{
printf("recv_len:%d\r\n", recv_len);
ethernet_buf[recv_len] = '\0';
printf("Received: %s", ethernet_buf);
}
}数据通信流程
应用数据使用 AES 硬件模块进行加密,使用 SHA 硬件和会话 MAC 密钥计算消息认证码(MAC)。加密后的数据和 MAC 被发送给另一方,接收方使用 AES 硬件解密数据,并使用 SHA 硬件验证 MAC,验证成功保证了数据的完整性和真实性。
运行验证
通过例程测试使用 HTTPS 获取百度网页信息,通过串口打印显示 W55MH32 PHY 链路正常、DHCP 获网成功,加载加密库后完成 TLS 握手(套件 TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256),发送请求并接收百度响应。打开 WIZ UartTool V1.0,连接 DEBUG USB 对应 COM 口(115200 / 8N1),典型输出如下:
W55MH32 TLS Example
PHY link
The current Mbtis speed : 100Mbps
The current Duplex Mode : Full-Duplex
DHCP running
DHCP success!
====================================================================================================
W55MH32 network configuration : DHCP
MAC : 00:08:DC:12:22:12
IP : 192.168.1.7
Subnet Mask : 255.255.255.0
Gateway : 192.168.1.1
DNS : 192.168.1.1
====================================================================================================
WIZnet CARD Secure Test Demo V1.0, secure lib version is V03.01.04.00
WIZnet CARD Crypt Test V1.0 start......
TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256
TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
TLS-RSA-WITH-AES-256-CBC-SHA256
TLS-RSA-WITH-AES-128-GCM-SHA256
TLS-RSA-WITH-AES-128-CBC-SHA256
socket_fd = 1
return 1
Performing the SSL/TLS handshake...
ok
[ Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 ]
W55MH32 MbedTLS Transmission test start......
W55MH32 get baidu.com html content......
recv_len:1179
Received: HTTP/1.1 200 OK ...


TLS 握手报文分析
通过 Wireshark 进行抓包展示了从 TCP 三次握手建立连接,接着开展 TLS 握手(涵盖 Client Hello、Server Hello、密钥交换等操作)以构建安全通信通道并传输应用数据。在 Wireshark 的显示过滤器中输入表达式 ip.addr == 192.168.1.7 and tls 过滤出 TLS 协议数据包,W55MH32 为客户端(192.168.1.7)访问百度服务器(220.181.111.1)。
TLS 四次握手流程
| 阶段 | 方向 | TLS消息 |
|---|---|---|
| 第一次握手 | W55MH32 -> 百度 | Client Hello(TLS版本、密码套件列表、客户端随机数) |
| 第二次握手 | 百度 -> W55MH32 | Server Hello、Certificate、Server Hello Done |
| 第三次握手 | W55MH32 -> 百度 | Client Key Exchange、Change Cipher Spec、Encrypted Handshake Message |
| 第四次握手 | 百度 -> W55MH32 | Change Cipher Spec、Encrypted Handshake Message |
从抓包中可以看到当前通信安全层协议版本(Version)为 TLS 1.2。TLS 共有 4 个版本:
- TLS 1.3:发布于 2018 年,大幅简化握手过程,引入 0-RTT 握手减少延迟,删除不安全算法
- TLS 1.2:发布于 2008 年,引入更强的加密算法和灵活的密码套件选择,是目前广泛使用的版本(本例百度网站使用)
- TLS 1.1:发布于 2006 年,对 CBC 模式安全性改进,但仍存在已知安全问题
- TLS 1.0:1999 年发布,SSL 3.0 的升级版本,仍存在安全问题
密码套件格式
格式为「密钥交换算法 + 签名算法(认证算法) + 对称加密算法 + 摘要算法」。例如 TLS_RSA_WITH_AES_128_GCM_SHA256 表示:RSA 密钥交换与认证、AES-128-GCM 对称加密、SHA256 摘要算法。密钥交换算法和签名算法可以相同时合二为一。
握手完成后,客户端与服务端的所有通信内容均被加密。服务器遵循 TLS 协议规范发出关闭警报(close_notify),随即发送 TCP RST 报文以快速释放连接资源。

常见问题
Q: W55MH32 硬件加密相比软件加密有什么优势
硬件加密将计算密集型的加密运算(AES、SHA)从主 CPU 卸载到专用硬件模块执行,大幅降低 CPU 占用率,提高整体性能。同时 TRNG 提供真正的随机熵源,比软件伪随机数生成器更安全。这使得主 CPU 能够专注于应用逻辑,在 216MHz 的处理能力下实现高性能安全通信。
Q: TLS 握手过程中 W55MH32 的硬件如何参与
TRNG 在 Client Hello 阶段生成 32 字节客户端随机数,在密钥交换阶段生成预主密钥或临时 DH 密钥对。SHA 硬件用于验证服务器证书的数字签名、计算 Finished 消息的握手哈希值以及数据传输时的消息认证码(MAC)。AES 硬件在握手完成后负责所有应用数据的加密和解密操作。
Q: 如何配置证书验证
在调用 wiz_tls_init 时传入 root_ca 参数(根证书字符串),函数会通过 mbedtls_x509_crt_parse 解析证书并设置 root_ca_option 为 MBEDTLS_SSL_VERIFY_REQUIRED。若 root_ca 为 NULL,则设为 MBEDTLS_SSL_VERIFY_NONE(不验证证书)。生产环境中建议启用证书验证以确保安全性。
Q: 支持哪些密码套件
W55MH32 通过 MbedTLS 库支持多种密码套件,包括 TLS_RSA_WITH_AES_128_GCM_SHA256、TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 等。套件由密钥交换算法(DHE/RSA)、认证算法(RSA)、对称加密算法(AES-128/256-GCM)和摘要算法(SHA256/384)组合而成。握手时客户端发送支持的套件列表,服务器从中选择双方都支持的最安全套件。
总结
- 专用硬件加速:内置 AES、SHA 加密算法单元和 TRNG 真随机数发生器,将加密计算从 CPU 卸载
- TLS 1.2 全流程支持:通过 MbedTLS 库配合硬件模块实现完整的 TLS 握手和加密数据传输
- 核心 API:wiz_tls_init 初始化上下文,wiz_tls_connect 执行握手,wiz_tls_read/write 进行加密通信
- 硬件角色:TRNG 生成随机数和密钥,SHA 验证证书和计算 MAC,AES 加解密应用数据
- 应用场景:适用于 IoT 设备的安全网络通信,如 HTTPS 客户端、MQTTS、邮件安全传输等