mbed TLS 开发指南
本文档以 HiDiTingV100 SDK 的 mbed TLS v3.6.5 组件为对象,介绍 mbed TLS、mbedtls_port 与 mbedtls_harden_ex 的分层设计、硬件加速宏的自动传播机制、硬化源码锚点,并给出 HASH、AES、ECC、RSA、TLS 的上游示例参考和最小 API 使用片段。
本文所称“上游源码”特指 Mbed TLS 官方 mbedtls 开源仓库的 mbedtls-3.6.5 标签。SDK 的 /src/open_source/mbedtls/mbedtls_v3.6.5 是该版本在 SDK 中的集成目录。SDK 当前裁剪了上游 programs/**/*.c 和 tests/suites/**,因此文中“上游示例”用于说明上游源码的位置与调用方式;如需构建这些示例,应使用同版本完整上游源码。
mbed TLS 模块背景知识
模块工作原理
mbed TLS 是面向嵌入式系统的密码库和 TLS/DTLS 协议库。HiDiTingV100 的应用代码只调用标准 mbedtls_* API;SDK 通过 porting 配置选择算法,通过 ALT(Alternative implementation)将部分密码操作转发给统一安全驱动和硬件。
需要区分协议控制与算法计算:TLS/DTLS 状态机、X.509 解析、证书校验与多数协议控制仍在原生 mbed TLS 中执行;HASH、AES/AEAD、ECC、部分大数模幂、KDF 等底层算法可由硬件加速。因此,调用 mbedtls_ssl_handshake() 不代表整个 TLS 流程都在硬件中执行,实际硬化取决于协商套件和已打开的 ALT 宏。
| 模块 | SDK 位置 | 主要职责 | 应用是否直接调用 |
|---|---|---|---|
| 原生 mbed TLS | /src/open_source/mbedtls/mbedtls_v3.6.5 | mbed TLS v3.6.5 公共头文件、算法库与 TLS/DTLS 状态机。 | 是,调用 mbedtls_* 公共 API。 |
mbedtls_port |
mbedtls porting 目录 | 发布 mbed TLS 配置文件宏,提供硬件熵源 mbedtls_hardware_poll()。 |
否。 |
mbedtls_harden_ex |
/src/middleware/utils/mbedtls_harden | 实现 mbed TLS ALT,调用安全驱动的 TRNG、SYMC、HASH、PKE、KDF 等能力。 | 否。 |
mbedtls_v3.6.5_harden 在 /src/build/config/target_config/common_config.py 中展开为 mbedtls_v3.6.5、mbedtls_port、mbedtls_harden_ex;默认目标在 /src/build/config/target_config/3322/target_config.py 中选择该组件集。

系统启动过程会调用 uapi_drv_cipher_env_init 初始化安全驱动、通道与全局资源。应用不应自行重复初始化或去初始化安全驱动。
为什么选择硬化组件
选择 mbedtls_v3.6.5_harden 是构建期组件选择,不是业务代码额外调用的运行步骤。构建系统自动定义 MBEDTLS_HARDEN_OPEN,再由用户配置头打开相应的 ALT 宏;应用继续调用标准 mbedtls_* API。
| 目标 | 硬化带来的作用 | 需要关注的条件 |
|---|---|---|
| 提升性能 | HASH、AES/AEAD、ECC、KDF 和大数模幂等操作可由安全硬件执行,减少 CPU 在密码计算上的负载,通常能提升吞吐或缩短计算时间。 | 小报文、频繁切换、通道竞争、缓存维护和驱动调用开销会影响实际收益;应以目标板上的端到端性能数据为准。 |
| 降低代码尺寸 | 当前 SDK 的硬化组件配置已验证可降低最终 code size:当 MBEDTLS_SHA256_ALT、MBEDTLS_AES_ALT、MBEDTLS_GCM_ALT 等宏生效时,/src/open_source/mbedtls/mbedtls_v3.6.5/library/sha256.c、/src/open_source/mbedtls/mbedtls_v3.6.5/library/aes.c、/src/open_source/mbedtls/mbedtls_v3.6.5/library/gcm.c 中受 ALT 宏保护的软件实现主体会被排除。 |
使用同一目标、同一功能集的链接映像或 map 文件量化实际减少量;修改启用算法或链接优化后应重新比较。 |
| 保持业务接口稳定 | ALT 在库内部替换实现,业务仍使用 mbedtls_sha256()、mbedtls_gcm_*()、mbedtls_ecdsa_*() 等公开 API。 |
应用、porting、硬化库必须来自同一组件集,不能在单个组件中补定义 ALT 宏。 |
mbedtls_v3.6.5_soft 用于不选择硬化组件的场景:密码算法走软件实现;随机熵源仍按 porting 配置使用 TRNG。性能、CPU 占用和代码尺寸应在相同功能集下与 harden 组件集进行对比。
操作流程
使用 mbed TLS 的标准流程如下:
- 选择组件集:产品目标选择
mbedtls_v3.6.5_harden或mbedtls_v3.6.5_soft,不要在单个应用中手工补宏。 - 系统安全初始化:系统完成 uapi_drv_cipher_env_init 后,TRNG、HASH、SYMC、PKE 等硬件资源可供 ALT 使用。
- 准备上下文:应用调用 mbed TLS 的
*_init();需要随机数的算法再初始化 entropy/CTR-DRBG。 - 调用公共 API:应用使用
mbedtls_sha256()、mbedtls_gcm_*()、mbedtls_ecdsa_*()、mbedtls_rsa_*()、mbedtls_ssl_*()等标准 API。 - 按配置分流:原生库根据
MBEDTLS_*_ALT选择 ALT 实现或软件实现;ALT 通过安全驱动 API 进入硬件,例如 HASH SHA-256 start、SYMC GCM setup 或 PKE ECDSA sign。 - 检查返回值和释放资源:所有 mbed TLS API 均应检查返回值,并在结束路径调用对应
*_free()。
硬化组件和宏的自动传播
使用 mbedtls_v3.6.5_harden 时,MBEDTLS_HARDEN_OPEN 由构建系统自动定义。开发者不需要也不应在应用 CMake 或源文件中手工定义此宏。

关键代码如下:
# src/middleware/utils/mbedtls_harden/CMakeLists.txt
set(PUBLIC_DEFINES
MBEDTLS_HARDEN_OPEN
)
# mbedtls_port CMakeLists.txt(配置宏示意)
set(PUBLIC_DEFINES
MBEDTLS_CONFIG_FILE="目标配置头文件"
MBEDTLS_USER_CONFIG_FILE="目标用户配置头文件"
)
mbedtls_harden_ex CMakeLists.txt 发布 MBEDTLS_HARDEN_OPEN,mbedtls_port CMakeLists.txt 发布配置文件宏。随后 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/build_info.h 先包含 MBEDTLS_CONFIG_FILE,再包含 MBEDTLS_USER_CONFIG_FILE,使用户配置头文件中的 #if defined(MBEDTLS_HARDEN_OPEN) 自动生效。
选择 mbedtls_v3.6.5_soft 时,组件集不包含 mbedtls_harden_ex,MBEDTLS_HARDEN_OPEN 和用户配置中受其控制的 ALT 宏均不会打开。HASH、AES/CCM/GCM、CMAC、HKDF、大数、ECP/ECDSA/ECDH 等算法随即使用 open_source/mbedtls 的原生软件实现;它们不会进入 mbedtls_harden 的硬件调用路径。
这不等同于“所有内容都不使用硬件”:MBEDTLS_ENTROPY_HARDWARE_ALT 由 porting 层在 MBEDTLS_HARDEN_OPEN 判断之外定义,soft 组件集中的 /src/drivers/chips/3322/porting/mbedtls/entropy_poll_alt.c 仍会通过 uapi_drv_cipher_trng_get_random_bytes 获取 TRNG 熵。因此,soft 的密码算法行为为软件实现,随机熵源仍由安全驱动/TRNG 提供。在 soft 组件集中手工定义该宏会使头文件选择 ALT 上下文、最终却链接不到 ALT 实现,属于错误配置。
算法、配置和 API 接口列表
用户配置头文件在硬化组件生效后打开 ALT 宏;XTS_SUPPORT 会关闭 HASH(SHA-256/SHA-512)、AES/GCM ALT,并使 ECP restartable,从而关闭 ECP/ECDSA/ECDH ALT。
快速验证 mbed TLS 组件
功能说明
本节通过 mbed TLS 公共接口计算 SHA-256 标准测试向量,同时验证 mbedtls_v3.6.5、mbedtls_port、mbedtls_harden_ex 的构建集成和目标板运行链路。示例源码为 /samples/native_samples/security/security_demo_mbedtls.c。该文件不是上游 programs 示例,而是 HiDiTingV100 security_sample 的板端回归用例;CONFIG_ENABLE_SECURITY_SAMPLE 负责将组件编入 diting-community,security_demo.c 负责注册 AT+SECMBEDTLS。
编译
说明:本文示例命令以一站式 CLI 为主。实际开发可从以下三种环境中选择,推荐使用一站式 CLI。
| 开发环境 | 适用场景 | 使用指南 |
|---|---|---|
| 一站式 CLI(推荐) | 快速完成目标选择、构建、烧录和串口监视 | 一站式 CLI 开发环境使用指南 |
| HiSpark Studio for VS Code | 图形化编辑、编译、烧录和调试 | HiSpark Studio for VS Code 开发环境使用指南 |
| WSL 与 Docker | 在 Windows 上使用一致的 Linux 容器构建环境 | WSL 与 Docker 环境使用指南 |
按一站式 CLI 环境完成配置后,在 SDK 根目录执行单目标构建:
cd <SDK_ROOT>
$env:FBB_SDK_DIR = "$PWD\src"
fbb doctor
fbb set-target diting-community
fbb build --clean
如需生成烧录用完整固件包,构建目标组而非把单目标输出误认为 fwpkg:
pack_diting_community 包含 diting-community 和打包所需的其他目标;成功后从 <SDK_ROOT>/src/output/<芯片目录>/fwpkg/ 获取固件包。
使用方式
-
使用一站式 CLI 烧写并监视 UART2 串口。以下为 Windows USB DFU 示例;将
COM3替换为实际日志串口,其他平台和串口烧写参数参见一站式 CLI 开发环境使用指南。 -
在 UART2 串口执行:
-
示例通过
mbedtls_sha256()计算字符串abc的 SHA-256,随后将 32 字节结果与标准向量比对。需要同时回归其他安全能力时,再执行AT+SECDEMOALL。
核心调用与当前示例一致:
static const uint8_t message[] = {'a', 'b', 'c'};
uint8_t digest[32] = {0};
ret = mbedtls_sha256(message, sizeof(message), digest, 0);
passed = (ret == 0) &&
(memcmp(digest, expected_digest, sizeof(digest)) == 0);
最后一个参数为 0 表示 SHA-256;接口返回 0 且摘要与标准向量一致时才打印 PASS。
预期结果
| 验证项 | 预期结果 |
|---|---|
diting-community 单目标构建 |
mbed TLS、porting、harden 三个组件参与构建与链接。 |
pack_diting_community 目标组构建 |
在输出目录生成可烧录的 fwpkg。 |
AT+SECMBEDTLS |
依次输出 [SEC][PASS] mbedTLS SHA-256 vector、[SEC][MBEDTLS] PASS 和 OK。 |
AT+SECDEMOALL |
输出 [SEC][ALL] AES-GCM=PASS HASH=PASS PKE=PASS KEY=PASS MBEDTLS=PASS 和 [SEC][ALL] PASS,最后返回 OK。 |
文件结构与代码走读
文件结构
src/
├── open_source/mbedtls/mbedtls_v3.6.5/
│ ├── include/mbedtls/ # 公共 API 与 build_info.h
│ ├── library/ # 原生算法与 TLS 状态机
│ └── programs/Makefile # 保留的上游示例构建目标清单
├── drivers/chips/<芯片目录>/porting/mbedtls/
│ ├── CMakeLists.txt # 发布配置文件宏
│ ├── entropy_poll_alt.c # TRNG 熵源适配
│ ├── 目标配置头文件 # 基础算法与协议配置
│ └── 目标用户配置头文件 # ALT 宏配置
└── middleware/utils/mbedtls_harden/
├── CMakeLists.txt # 发布 MBEDTLS_HARDEN_OPEN
├── include/ # ALT 上下文与配置检查
└── library/ # HASH/AES/ECC/KDF 等硬化实现
samples/native_samples/security/
├── CMakeLists.txt # security_sample 源文件与编译宏
├── security_demo.c # AT 指令注册与安全示例汇总入口
├── security_demo.h # 示例函数声明
├── security_demo_mbedtls.c # mbed TLS SHA-256 标准向量板端验证
├── security_demo_utils.c # PASS/FAIL、字节比较和清零
└── security_demo_utils.h # 公共辅助函数声明
各文件职责
| 文件或目录 | 职责 |
|---|---|
| mbedtls_harden/CMakeLists.txt | 编译全部硬化源文件,并通过 PUBLIC_DEFINES 自动发布 MBEDTLS_HARDEN_OPEN。 |
| mbedtls port CMakeLists.txt | 自动发布 MBEDTLS_CONFIG_FILE 和 MBEDTLS_USER_CONFIG_FILE。 |
| /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/build_info.h | 按“基础配置 → 用户配置”的顺序加载宏。 |
| 用户配置头文件 | 仅在 MBEDTLS_HARDEN_OPEN 自动存在时定义 ALT 宏,处理 XTS 与曲线裁剪。 |
| /src/middleware/utils/mbedtls_harden/include/mbedtls_build_config_check.h | 检查 ECP/ECDSA/ECDH ALT 与安全驱动支持的椭圆曲线是否一致。 |
| security/CMakeLists.txt | 将 security_demo_mbedtls.c 编入 security_sample,并发布 AT_DITING_EXAMPLE_SECURITY。 |
| /samples/native_samples/security/security_demo.c | 注册 AT+SECMBEDTLS,并在 AT+SECDEMOALL 中汇总 mbed TLS 结果。 |
| /samples/native_samples/security/security_demo_mbedtls.c | 调用 mbedtls_sha256() 并比对标准向量,验证公共 API 在目标板上的实际执行结果。 |
代码走读
CMake 与配置加载
构建阶段不要在应用内直接写 -DMBEDTLS_HARDEN_OPEN。正确做法是选择 mbedtls_v3.6.5_harden,由组件 CMake 自动发布该宏;mbedtls_port 同时发布配置文件宏;build_info.h 加载用户配置后,用户配置头文件才定义 MBEDTLS_SHA256_ALT、MBEDTLS_AES_ALT、MBEDTLS_ECDSA_SIGN_ALT 等宏。
XTS_SUPPORT 会改变硬化策略:它关闭 HASH(SHA-256/SHA-512)、AES/GCM ALT,定义 MBEDTLS_ECP_RESTARTABLE,从而避免打开 ECP/ECDSA/ECDH ALT。CCM、CMAC、HKDF、大数 ALT 不受这一条件影响。
硬件加速宏与源码锚点
下表列出 mbedtls_harden_ex CMake 编译的全部硬化源文件。源文件被编译不代表默认一定启用;是否实际替换原生实现仍由“ALT 宏”列决定。
CCM/GCM ALT 开启时会取消 Camellia 和 ARIA;secp192k1、secp224k1、secp256k1 会被用户配置取消。若 ECP/ECDSA/ECDH ALT 使用的曲线未被安全驱动支持,mbedtls_build_config_check.h 会在编译期报错。
上游示例与测试源码位置
完整上游源码中,使用示例位于 GitHub programs/,算法正确性测试位于 GitHub tests/suites/。两者用途不同:
| 类型 | HASH | AES | ECC/RSA | TLS |
|---|---|---|---|---|
| API 示例 | programs/hash/hello.c、generic_sum.c、md_hmac_demo.c |
programs/aes/crypt_and_hash.c |
programs/pkey/ecdsa.c、rsa_genkey.c、rsa_sign.c、rsa_verify.c |
programs/ssl/ssl_client1.c、ssl_server.c、dtls_client.c、dtls_server.c |
| 单元测试 | tests/suites/test_suite_sha256.*、test_suite_md.* |
test_suite_aes.*、test_suite_gcm.*、test_suite_ccm.* |
test_suite_ecdsa.*、test_suite_ecdh.*、test_suite_ecp.*、test_suite_rsa.* |
tests/suites/test_suite_ssl.* |
programs 示例用于学习 API 调用流程;tests/suites 由 *.function 测试函数和 *.data 测试数据组成,用于算法正确性与回归验证。当前 SDK 只保留 programs/Makefile,没有这些 .c、.function 或 .data 文件,不能把上表当作当前目录中的可构建文件。
基于上游示例完成业务接入
本节以完整上游 programs 的调用方式为参考,给出 HASH、AES、ECC、RSA、TLS 的最小 API 片段,便于开发者在业务组件中集成 mbed TLS。
以下片段不要求在业务代码中手工定义任何 MBEDTLS_* 配置宏;这些宏由所选组件集及 mbed TLS 公开头文件提供。示例中的数据长度均直接使用 sizeof 计算,避免引入未定义的长度占位宏。
公共随机数准备
ECC、RSA、TLS 都需要密码学随机数。系统已通过 mbedtls_port 将 mbedtls_hardware_poll() 接到 TRNG;应用使用 entropy 和 CTR-DRBG 即可,不直接调用 TRNG 驱动。
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const unsigned char personalization[] = "my_crypto_component";
int ret;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
personalization, sizeof(personalization) - 1);
if (ret != 0) {
/* 记录 ret,停止后续私钥、签名或 TLS 操作。 */
}
/* 组件退出时按相反顺序释放。 */
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
HASH
原生参考:programs/hash/hello.c、generic_sum.c、md_hmac_demo.c。

#include "mbedtls/sha256.h"
unsigned char digest[32];
const unsigned char message[] = "payload";
int ret = mbedtls_sha256(message, sizeof(message) - 1, digest, 0);
if (ret == 0) {
/* digest 为 32 字节 HASH(SHA-256)结果。 */
}
一次性 mbedtls_sha256() 在原生库中会按 init → starts → update → finish → free 组织调用。默认硬化配置下,starts/update/finish 进入 /src/middleware/utils/mbedtls_harden/library/sha256_alt.c,并调用 uapi_drv_cipher_sha256_start、uapi_drv_cipher_sha256_update、uapi_drv_cipher_sha256_finish。处理大数据时应使用流式 mbedtls_sha256_init/starts/update/finish/free,避免一次性分配大缓冲区。
AES
原生参考:programs/aes/crypt_and_hash.c。原生程序包含文件 I/O;嵌入式业务通常只保留密钥、nonce、AAD、数据和标签的处理。

#include "mbedtls/gcm.h"
/* 仅用于展示 API 参数关系;量产密钥必须来自密钥管理或安全存储。 */
static const unsigned char key[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
static const unsigned char nonce[12] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b
};
static const unsigned char aad[] = "header";
static const unsigned char plaintext[] = "payload";
mbedtls_gcm_context gcm;
unsigned char ciphertext[sizeof(plaintext) - 1];
unsigned char tag[16];
int ret;
mbedtls_gcm_init(&gcm);
ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, 128);
if (ret == 0) {
ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT,
sizeof(plaintext) - 1, nonce, sizeof(nonce), aad, sizeof(aad) - 1,
plaintext, ciphertext, sizeof(tag), tag);
}
mbedtls_gcm_free(&gcm);
nonce 对同一密钥必须唯一,tag 必须与密文保存。解密时使用 mbedtls_gcm_auth_decrypt(),返回非零即丢弃明文。mbedtls_gcm_* 由 /src/middleware/utils/mbedtls_harden/library/gcm_alt.c 转发给 uapi_drv_cipher_symc_gcm_setup、uapi_drv_cipher_symc_gcm_update、uapi_drv_cipher_symc_gcm_finish;若业务使用 ECB/CBC/CTR 等通用 AES API,则对应 /src/middleware/utils/mbedtls_harden/library/aes_alt.c 的 uapi_drv_cipher_symc_ecb_update、uapi_drv_cipher_symc_cbc_update、uapi_drv_cipher_symc_ctr_update 路径。
ECC
原生参考:programs/pkey/ecdsa.c、ecdh_curve25519.c。

#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
mbedtls_ecdsa_context key;
static const unsigned char message[] = "payload";
unsigned char hash[32];
unsigned char signature[MBEDTLS_ECDSA_MAX_LEN];
size_t signature_len = 0;
int ret;
mbedtls_ecdsa_init(&key);
ret = mbedtls_ecdsa_genkey(&key, MBEDTLS_ECP_DP_SECP256R1,
mbedtls_ctr_drbg_random, &ctr_drbg);
if (ret == 0) {
ret = mbedtls_sha256(message, sizeof(message) - 1, hash, 0);
}
if (ret == 0) {
ret = mbedtls_ecdsa_write_signature(&key, MBEDTLS_MD_SHA256,
hash, sizeof(hash), signature, sizeof(signature), &signature_len,
mbedtls_ctr_drbg_random, &ctr_drbg);
}
if (ret == 0) {
ret = mbedtls_ecdsa_read_signature(&key, hash, sizeof(hash), signature, signature_len);
}
mbedtls_ecdsa_free(&key);
mbedtls_ecdsa_genkey()、底层 mbedtls_ecdsa_sign()、mbedtls_ecdsa_verify() 分别由 /src/middleware/utils/mbedtls_harden/library/ecdsa_alt.c 调用 uapi_drv_cipher_pke_ecc_gen_key、uapi_drv_cipher_pke_ecdsa_sign、uapi_drv_cipher_pke_ecdsa_verify。曲线映射由 /src/middleware/utils/mbedtls_harden/library/mbedtls_ecp_func.c 完成;直接 ECP/ECDH 操作应分别检查 /src/middleware/utils/mbedtls_harden/library/ecp_alt.c 与 /src/middleware/utils/mbedtls_harden/library/ecdh_alt.c。量产场景应从安全存储或密钥管理模块获得私钥,不能为每次业务签名临时生成私钥。
RSA
原生参考:programs/pkey/rsa_genkey.c、rsa_sign.c、rsa_verify.c,以及 PSS 对应程序。

#include "mbedtls/md.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha256.h"
mbedtls_rsa_context rsa;
static const unsigned char message[] = "payload";
unsigned char hash[32];
unsigned char signature[MBEDTLS_MPI_MAX_SIZE];
int ret;
mbedtls_rsa_init(&rsa);
ret = mbedtls_rsa_gen_key(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, 2048, 65537);
if (ret == 0) {
ret = mbedtls_sha256(message, sizeof(message) - 1, hash, 0);
}
if (ret == 0) {
ret = mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
}
if (ret == 0) {
ret = mbedtls_rsa_pkcs1_sign(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg,
MBEDTLS_MD_SHA256, sizeof(hash), hash, signature);
}
if (ret == 0) {
ret = mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA256, sizeof(hash), hash, signature);
}
mbedtls_rsa_free(&rsa);
当前芯片配置没有 MBEDTLS_RSA_ALT。RSA 填充和 API 仍在原生 library/rsa.c 中运行;mbedtls_mpi_exp_mod() 才会尝试 /src/middleware/utils/mbedtls_harden/library/bignum_alt.c 的 mbedtls_mpi_exp_mod_alt(),再调用 uapi_drv_cipher_pke_exp_mod。ALT 返回成功才使用硬件结果;参数长度、对齐或硬件能力不满足时继续软件路径。在线生成 RSA 密钥开销较大,产品应使用受保护的既有密钥;PSS 应改用 mbedtls_rsa_rsassa_pss_sign() / verify()。
TLS
原生参考:programs/ssl/ssl_client1.c、ssl_server.c;DTLS 对应 dtls_client.c、dtls_server.c。

#include "mbedtls/ssl.h"
/* 仅用于文档示例;量产必须替换为服务器证书 SAN 中的产品域名。 */
static const char server_hostname[] = "example.com";
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
int ret;
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
if (ret == 0) {
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &ca, NULL);
ret = mbedtls_ssl_setup(&ssl, &conf);
}
if (ret == 0) {
ret = mbedtls_ssl_set_hostname(&ssl, server_hostname);
}
if (ret == 0) {
mbedtls_ssl_set_bio(&ssl, transport_ctx, send_cb, recv_cb, NULL);
do {
ret = mbedtls_ssl_handshake(&ssl);
} while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);
}
/* 成功后调用 mbedtls_ssl_write/read;退出时调用 mbedtls_ssl_free/config_free。 */
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
transport_ctx、send_cb、recv_cb 由网络适配层实现,ca 必须预先完成解析和加载。example.com 是 IANA 保留的文档示例域名,可用于说明 mbedtls_ssl_set_hostname() 的主机名校验参数,但不能作为量产服务端;量产值必须替换为服务器证书 Subject Alternative Name(SAN)中的产品域名。TLS 没有 MBEDTLS_SSL_*_ALT:状态机、证书和握手控制仍为软件实现;TLS 1.2 的 HASH、AES-GCM、AES-CCM、ECDHE/ECDSA 会按套件进入 HASH、SYMC、PKE ALT,TLS 1.3 密钥派生可进入 /src/middleware/utils/mbedtls_harden/library/hkdf_alt.c。MBEDTLS_SSL_VERIFY_REQUIRED 是生产连接的最低要求,不能为规避证书错误改成 MBEDTLS_SSL_VERIFY_NONE。
上游示例和测试的构建条件
上游 programs 示例与 tests/suites 测试不属于当前 SDK 的 fbb 工作流。当前 SDK 不包含其完整源文件,不能在此目录运行上游 make 或 ctest。
需要运行上游测试时,请下载完整的 mbedtls-3.6.5 官方发布源码,并在主机环境而非 HiDiTing SDK 根目录运行:
cmake -S . -B build -DENABLE_PROGRAMS=On -DENABLE_TESTING=On
cmake --build build
ctest --test-dir build --output-on-failure
以上命令验证未经芯片 porting/ALT 改造的上游主机版本。若项目决定移植某个示例为 SDK 应用,需单独建立组件、适配网络/文件系统/证书,并另行确认新增应用代码需求。
注意事项
- 使用
mbedtls_v3.6.5_harden时不手工定义MBEDTLS_HARDEN_OPEN;使用 soft 组件集时也不手工补定义该宏。 - 应用、原生库与 ALT 库必须通过同一目标组件集获得配置;手工混合 soft/harden 宏会造成上下文布局与链接库不一致。
- 不访问标记为
MBEDTLS_PRIVATE的结构体成员,只使用公开 API。 - AES-ECB、固定密钥、固定 nonce、关闭证书校验等示例写法不能用于量产业务;AES-GCM/CCM 必须管理 nonce 和认证标签。
- ECC、RSA、TLS 必须使用密码学安全随机数,不能用固定数组、时间戳或普通伪随机函数替代 entropy/CTR-DRBG。
- TLS 原生 socket 示例依赖网络、证书文件和时间;嵌入式移植需要替换 BIO、证书存储、时间校验和任务调度。
- 当前 SDK 缺失上游
programs/**/*.c与tests/suites/**,文档中的上游路径仅作引用,不能视为当前目录可构建文件。
常见编译错误
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
No rule to make target programs/hash/hello.c 或找不到 tests/suites |
当前 SDK 裁剪了上游示例和测试源码。 | 获取同版本完整上游源码构建上游示例,或只构建 SDK mbed TLS 组件。 |
mbedtls/xxx.h: No such file or directory |
mbed TLS 组件未参与构建,或依赖组件未正确传递头文件。 | 确认目标包含 mbedtls_v3.6.5_harden 或 mbedtls_v3.6.5_soft。 |
| 上下文结构体定义不一致或 ALT 符号未定义 | 应用、库和 ALT 层采用了不同组件集或手工定义了硬化宏。 | 为整个目标统一选择 harden 或 soft 组件集;不要在应用中手工定义 MBEDTLS_HARDEN_OPEN。 |
mbedtls_ctr_drbg_seed 失败 |
熵源不可用,或安全驱动初始化时序异常。 | 检查 /src/drivers/chips/3322/porting/mbedtls/entropy_poll_alt.c、TRNG 驱动和 uapi_drv_cipher_env_init。 |
AT+SECMBEDTLS 不存在 |
security_sample 未编入目标,或安全 AT 未注册。 |
检查 CONFIG_ENABLE_SECURITY_SAMPLE、目标组件列表、AT_DITING_EXAMPLE_SECURITY 和烧录固件版本。 |
[SEC][MBEDTLS] FAIL |
mbedtls_sha256() 返回失败,或 abc 摘要与标准向量不一致。 |
保存 mbedtls_sha256 返回值,检查 harden/soft 组件选择、SHA-256 配置与安全 HASH 驱动。 |
| ECC 返回曲线不支持 | 曲线被裁剪或安全驱动未启用对应 PKE 曲线。 | 检查 MBEDTLS_ECP_DP_*_ENABLED 与 /src/middleware/utils/mbedtls_harden/include/mbedtls_build_config_check.h。 |
| RSA 性能未提升或部分操作失败 | RSA 没有完整 ALT,仅大数模幂尝试 PKE;参数可能不适合硬件。 | 查看 /src/middleware/utils/mbedtls_harden/library/bignum_alt.c 的能力限制与软件回退路径。 |
TLS 长时间返回 WANT_READ |
对端未发送数据、BIO 回调错误或事件循环未调度。 | 将 WANT_READ/WANT_WRITE 作为等待状态;检查 socket/BIO 与任务调度。 |
| TLS 无共同密码套件 | 配置裁剪了密钥交换、AES、摘要或 TLS 版本。 | 检查 MBEDTLS_KEY_EXCHANGE_*、MBEDTLS_AES_C、MBEDTLS_SHA256_C、MBEDTLS_SSL_PROTO_TLS1_2 等宏。 |