跳转至

mbed TLS 开发指南

本文档以 HiDiTingV100 SDK 的 mbed TLS v3.6.5 组件为对象,介绍 mbed TLS、mbedtls_portmbedtls_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/**/*.ctests/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.5mbedtls_portmbedtls_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_ALTMBEDTLS_AES_ALTMBEDTLS_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 的标准流程如下:

  1. 选择组件集:产品目标选择 mbedtls_v3.6.5_hardenmbedtls_v3.6.5_soft,不要在单个应用中手工补宏。
  2. 系统安全初始化:系统完成 uapi_drv_cipher_env_init 后,TRNG、HASH、SYMC、PKE 等硬件资源可供 ALT 使用。
  3. 准备上下文:应用调用 mbed TLS 的 *_init();需要随机数的算法再初始化 entropy/CTR-DRBG。
  4. 调用公共 API:应用使用 mbedtls_sha256()mbedtls_gcm_*()mbedtls_ecdsa_*()mbedtls_rsa_*()mbedtls_ssl_*() 等标准 API。
  5. 按配置分流:原生库根据 MBEDTLS_*_ALT 选择 ALT 实现或软件实现;ALT 通过安全驱动 API 进入硬件,例如 HASH SHA-256 startSYMC GCM setupPKE ECDSA sign
  6. 检查返回值和释放资源:所有 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_exMBEDTLS_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。

分类 关键宏或 API 说明 参考
安全驱动 uapi_drv_cipher_env_init 系统启动时初始化安全驱动;应用依赖其初始化结果。 API 参考
随机数 MBEDTLS_ENTROPY_HARDWARE_ALTmbedtls_ctr_drbg_* mbedtls_hardware_poll() 作为熵源,为 ECC/RSA/TLS 提供随机数。 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/entropy.h/src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/ctr_drbg.h
HASH MBEDTLS_SHA256_ALTmbedtls_sha256* HASH 的 SHA-224/SHA-256 变体可由硬件加速。 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/sha256.h
AES/AEAD MBEDTLS_AES_ALTMBEDTLS_GCM_ALTMBEDTLS_CCM_ALT AES、GCM、CCM 可由 SYMC 硬件加速。 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/aes.h/src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/gcm.h
ECC MBEDTLS_ECP_ALTMBEDTLS_ECDSA_*_ALTMBEDTLS_ECDH_COMPUTE_SHARED_ALT 曲线计算、ECDSA、ECDH 可由 PKE 加速。 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/ecp.h/src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/ecdsa.h/src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/ecdh.h
RSA MBEDTLS_BIGNUM_ALTmbedtls_rsa_* RSA 没有完整 RSA ALT;大数模幂会优先尝试 PKE,再回退软件。 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/rsa.h
TLS/DTLS mbedtls_ssl_*MBEDTLS_HKDF_ALT TLS 状态机仍由软件执行,算法/密钥派生可进入硬件。 /src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/ssl.h/src/open_source/mbedtls/mbedtls_v3.6.5/include/mbedtls/hkdf.h

快速验证 mbed TLS 组件

功能说明

本节通过 mbed TLS 公共接口计算 SHA-256 标准测试向量,同时验证 mbedtls_v3.6.5mbedtls_portmbedtls_harden_ex 的构建集成和目标板运行链路。示例源码为 /samples/native_samples/security/security_demo_mbedtls.c。该文件不是上游 programs 示例,而是 HiDiTingV100 security_sample 的板端回归用例;CONFIG_ENABLE_SECURITY_SAMPLE 负责将组件编入 diting-communitysecurity_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

fbb set-target pack_diting_community
fbb build --clean

pack_diting_community 包含 diting-community 和打包所需的其他目标;成功后从 <SDK_ROOT>/src/output/<芯片目录>/fwpkg/ 获取固件包。

使用方式

  1. 使用一站式 CLI 烧写并监视 UART2 串口。以下为 Windows USB DFU 示例;将 COM3 替换为实际日志串口,其他平台和串口烧写参数参见一站式 CLI 开发环境使用指南

    fbb flash -f "$env:FBB_SDK_DIR\output\3322\fwpkg\diting-community.fwpkg" --chip 3322 -d --timeout 180
    fbb monitor --port COM3 --baud 750000
    
  2. 在 UART2 串口执行:

    AT+SECMBEDTLS
    
  3. 示例通过 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] PASSOK
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_FILEMBEDTLS_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_ALTMBEDTLS_AES_ALTMBEDTLS_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 宏”列决定。

能力 ALT 宏与默认状态 具体硬化代码锚点 关键入口和硬件路径
硬件熵源 MBEDTLS_ENTROPY_HARDWARE_ALT;始终定义 /src/drivers/chips/3322/porting/mbedtls/entropy_poll_alt.c mbedtls_hardware_poll()uapi_drv_cipher_trng_get_random_bytes → TRNG。此文件属于 porting 层,在 soft 组件集也生效。
HASH(SHA-1) MBEDTLS_SHA1_ALT;默认未定义 /src/middleware/utils/mbedtls_harden/library/sha1_alt.c mbedtls_sha1_starts/update/finish()sha1_start / sha1_update / sha1_finish → HASH。
HASH(SHA-224/256) MBEDTLS_SHA256_ALT;默认启用,XTS_SUPPORT 时关闭 /src/middleware/utils/mbedtls_harden/library/sha256_alt.c mbedtls_sha256_starts/update/finish()sha224_start / sha256_start,以及对应 update / finish → HASH。
HASH(SHA-384/512) MBEDTLS_SHA512_ALT;默认启用,XTS_SUPPORT 时关闭 /src/middleware/utils/mbedtls_harden/library/sha512_alt.c mbedtls_sha512_starts/update/finish()sha384_start / sha512_start,以及对应 update / finish → HASH。
AES MBEDTLS_AES_ALT;默认启用,XTS_SUPPORT 时关闭 /src/middleware/utils/mbedtls_harden/library/aes_alt.c mbedtls_aes_setkey_*()mbedtls_aes_crypt_*()uapi_drv_cipher_symc_setupECB / CBC / CTR update → SYMC。
CCM MBEDTLS_CCM_ALT;默认启用 /src/middleware/utils/mbedtls_harden/library/ccm_alt.c mbedtls_ccm_*()uapi_drv_cipher_symc_ccm_setup / update / finish → SYMC。
GCM MBEDTLS_GCM_ALT;默认启用,XTS_SUPPORT 时关闭 /src/middleware/utils/mbedtls_harden/library/gcm_alt.c mbedtls_gcm_crypt_and_tag()mbedtls_gcm_auth_decrypt()uapi_drv_cipher_symc_gcm_setup / update / finish → SYMC。
CMAC MBEDTLS_CMAC_ALT;默认启用 /src/middleware/utils/mbedtls_harden/library/cmac_alt.c mbedtls_cipher_cmac_*()uapi_drv_cipher_cmacuapi_drv_cipher_cmac_updateuapi_drv_cipher_cmac_finish → MAC/SYMC。
HKDF MBEDTLS_HKDF_ALT;默认启用 /src/middleware/utils/mbedtls_harden/library/hkdf_alt.c mbedtls_hkdf*()uapi_drv_cipher_hkdfextractexpand → KDF。
PBKDF2 MBEDTLS_PBKDF2_HMAC_ALT;默认未定义 /src/middleware/utils/mbedtls_harden/library/pbkdf2_alt.c mbedtls_pkcs5_pbkdf2_hmac*()uapi_drv_cipher_pbkdf2 → KDF。
大数模幂 MBEDTLS_BIGNUM_ALT;默认启用 /src/middleware/utils/mbedtls_harden/library/bignum_alt.c mbedtls_mpi_exp_mod_alt()uapi_drv_cipher_pke_exp_mod / uapi_drv_cipher_pke_mod → PKE。
ECP MBEDTLS_ECP_ALT;默认启用,XTS_SUPPORT 时关闭 /src/middleware/utils/mbedtls_harden/library/ecp_alt.c mbedtls_ecp_mul*()mbedtls_ecp_gen_keypair()uapi_drv_cipher_pke_mul_dotmul_dot_addecc_gen_key → PKE。
ECDSA MBEDTLS_ECDSA_SIGN_ALTMBEDTLS_ECDSA_VERIFY_ALTMBEDTLS_ECDSA_GENKEY_ALT;默认启用 /src/middleware/utils/mbedtls_harden/library/ecdsa_alt.c mbedtls_ecdsa_sign/verify/genkey()uapi_drv_cipher_pke_ecdsa_signverifyecc_gen_key → PKE。
ECDH MBEDTLS_ECDH_COMPUTE_SHARED_ALT;默认启用 /src/middleware/utils/mbedtls_harden/library/ecdh_alt.c mbedtls_ecdh_compute_shared()uapi_drv_cipher_pke_ecc_gen_ecdh_key → PKE。
HASH/ECC 辅助 无独立 ALT 宏 /src/middleware/utils/mbedtls_harden/library/mbedtls_hash_func.c/src/middleware/utils/mbedtls_harden/library/mbedtls_ecp_func.c 摘要类型映射、曲线类型映射、PKE 数据封装与释放。
性能统计 MBEDTLS_PERF_UTILS_OPEN;仅 UT/FUZZ 自动追加 /src/middleware/utils/mbedtls_harden/library/mbedtls_perf_utils.c 记录 AES、HASH、ECC、CCM、GCM、CMAC、大数性能;默认不开启。

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.cgeneric_sum.cmd_hmac_demo.c programs/aes/crypt_and_hash.c programs/pkey/ecdsa.crsa_genkey.crsa_sign.crsa_verify.c programs/ssl/ssl_client1.cssl_server.cdtls_client.cdtls_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_portmbedtls_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.cgeneric_sum.cmd_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_startuapi_drv_cipher_sha256_updateuapi_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_setupuapi_drv_cipher_symc_gcm_updateuapi_drv_cipher_symc_gcm_finish;若业务使用 ECB/CBC/CTR 等通用 AES API,则对应 /src/middleware/utils/mbedtls_harden/library/aes_alt.cuapi_drv_cipher_symc_ecb_updateuapi_drv_cipher_symc_cbc_updateuapi_drv_cipher_symc_ctr_update 路径。

ECC

原生参考programs/pkey/ecdsa.cecdh_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_keyuapi_drv_cipher_pke_ecdsa_signuapi_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.crsa_sign.crsa_verify.c,以及 PSS 对应程序。

RSA密码处理流程

#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.cmbedtls_mpi_exp_mod_alt(),再调用 uapi_drv_cipher_pke_exp_mod。ALT 返回成功才使用硬件结果;参数长度、对齐或硬件能力不满足时继续软件路径。在线生成 RSA 密钥开销较大,产品应使用受保护的既有密钥;PSS 应改用 mbedtls_rsa_rsassa_pss_sign() / verify()

TLS

原生参考programs/ssl/ssl_client1.cssl_server.c;DTLS 对应 dtls_client.cdtls_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_ctxsend_cbrecv_cb 由网络适配层实现,ca 必须预先完成解析和加载。example.comIANA 保留的文档示例域名,可用于说明 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.cMBEDTLS_SSL_VERIFY_REQUIRED 是生产连接的最低要求,不能为规避证书错误改成 MBEDTLS_SSL_VERIFY_NONE

上游示例和测试的构建条件

上游 programs 示例与 tests/suites 测试不属于当前 SDK 的 fbb 工作流。当前 SDK 不包含其完整源文件,不能在此目录运行上游 makectest

需要运行上游测试时,请下载完整的 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/**/*.ctests/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_hardenmbedtls_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_CMBEDTLS_SHA256_CMBEDTLS_SSL_PROTO_TLS1_2 等宏。