Mbed TLS 的 TLS 1.3 支持全解析:能力边界、配置项与握手实现架构(TEN-framework 第三方依赖深度解读)
Mbed TLS 的 TLS 1.3 支持全解析:能力边界、配置项与握手实现架构(TEN-framework 第三方依赖深度解读)
本指南以 TEN-framework 仓库内第三方依赖 Mbed TLS 的架构文档 tls13-support.md 为主体,系统梳理其 TLS 1.3 实现的能力边界(支持的密码套件、ClientHello 扩展、签名算法与密钥交换方式)、编译与运行时配置方法,并深入剖析握手状态机、消息处理/写入手管线的代码组织方式与命名约定。读完本文,你既能快速判断 Mbed TLS 在当前构建中支持哪些 TLS 1.3 特性、如何开启,也能读懂 ssl_tls13_*.c 系列源码的演进结构与审查规范。
背景:Mbed TLS 的 TLS 1.3 实现处于什么阶段
TLS 1.3(RFC 8446)是现代传输安全的核心协议,其与 TLS 1.2 的最大差异在于:握手流程从两次往返压缩到一次(或 0-RTT)、移除了静态 RSA 与 CBC 模式、所有对称加密均采用 AEAD 且密钥派生统一基于 HKDF。Mbed TLS 在仓库中以 library/ssl_tls13_client.c、library/ssl_tls13_server.c、library/ssl_tls13_generic.c、library/ssl_tls13_keys.c 四个模块实现 TLS 1.3,并通过编译期宏 MBEDTLS_SSL_PROTO_TLS1_3 控制启停。
需要特别说明的是:这是一份部分实现(partial implementation),并非对 RFC 8446 的完整覆盖。Mbed TLS 官方将开发路线建立在 hannestschofenig/mbedtls 的 TLS 1.3 原型之上,并持续把开发分支的提交合并进原型、再反向 upstream,具体缺口见下文"上游化进度"一节。因此在当前仓库中启用 TLS 1.3 之前,务必先对照本文的能力清单确认你的使用场景是否在支持范围内。
编译期开关:如何开启与关闭 TLS 1.3
TLS 1.3 的使能完全由配置宏 MBEDTLS_SSL_PROTO_TLS1_3 控制,定义于 include/mbedtls/mbedtls_config.h:
/**
* \def MBEDTLS_SSL_PROTO_TLS1_3
*
* Enable support for TLS 1.3.
*
* \note The support for TLS 1.3 is not comprehensive yet, in particular
* pre-shared keys are not supported.
* See docs/architecture/tls13-support.md for a description of the TLS
* 1.3 support that this option enables.
*
* Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
* Requires: MBEDTLS_PSA_CRYPTO_C
* ...
*/
//#define MBEDTLS_SSL_PROTO_TLS1_3
该宏默认处于注释状态(未启用),启用前必须满足两个硬性依赖:
MBEDTLS_SSL_KEEP_PEER_CERTIFICATE:TLS 1.3 实现要求保留对端证书,必须保持默认的"启用"状态;MBEDTLS_PSA_CRYPTO_C:TLS 1.3 的密钥派生与 AEAD 加密构建在 PSA Crypto 之上,同样必须保持启用。若希望所有密码学操作(含 X.509、与 TLS 1.2 共用的记录保护、握手哈希)都走 PSA,还需额外打开MBEDTLS_USE_PSA_CRYPTO,否则 TLS 1.3 依赖的 PSA 之外的部分仍会走非 PSA 实现。
配置宏的合法性检查在 include/mbedtls/check_config.h 中完成,构建时若遗漏上述依赖会直接报错,而不是在运行期才暴露。
相关配置宏一览
| 配置宏 | 默认状态 | 说明 |
|---|---|---|
MBEDTLS_SSL_PROTO_TLS1_3 |
关闭 | TLS 1.3 总开关 |
MBEDTLS_SSL_PROTO_TLS1_2 |
开启 | TLS 1.2 开关,可与 TLS 1.3 相互独立编译 |
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE |
关闭 | RFC 8446 附录 D.4 的中间盒兼容模式,开启会增加少量线上字节,但不影响与其他 TLS 1.3 实现的互通;除带宽极端敏感外官方建议开启 |
MBEDTLS_SSL_SESSION_TICKETS |
开启 | RFC 5077 会话票据,当前 TLS 1.3 实现不消费该特性 |
仓库提供了纯 TLS 1.3 的测试配置 tests/configs/tls13-only.h,它开启 MBEDTLS_SSL_PROTO_TLS1_3 与兼容模式、同时关闭 MBEDTLS_SSL_PROTO_TLS1_2、MBEDTLS_SSL_PROTO_DTLS 等宏,是验证"只跑 TLS 1.3"构建形态的现成参考:
#define MBEDTLS_SSL_PROTO_TLS1_3
#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC
#undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET
#undef MBEDTLS_SSL_PROTO_TLS1_2
#undef MBEDTLS_SSL_PROTO_DTLS
能力边界:TLS 1.3 到底支持到什么程度
客户端/服务端与密钥交换方式
- Mbed TLS 同时实现了 TLS 1.3 的客户端与服务器端。
- 密钥交换仅支持 ECDHE(椭圆曲线迪菲-赫尔曼临时密钥);
- 不支持 DHE(有限域上的临时 DH);
- 不支持预共享密钥(PSK),包括任何形式的会话恢复,因此不支持 0-RTT(early data)发送。
从源码结构看,TLS 1.3 侧统一经由 library/ssl_tls.c 分派:客户端握手步进 mbedtls_ssl_tls13_handshake_client_step() 与服务器端 mbedtls_ssl_tls13_handshake_server_step() 分别定义于 ssl_tls13_client.c 与 ssl_tls13_server.c。值得注意的是,虽然当前构建不支持 PSK,但运行时 API 层已经预留了密钥交换模式的概念,见 include/mbedtls/ssl.h:
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK ( 1u << 0 )
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL ( 1u << 1 )
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ( 1u << 2 )
并通过 mbedtls_ssl_conf_tls13_key_exchange_modes()(ssl.h)在运行时配置允许的模式组合。这也印证了原文档中的判断:TLS 1.3 的密钥交换配置正沿着 PSK / PSK_EPHEMERAL / EPHEMERAL 这套运行时宏体系组织,PSK 相关能力属于"待上游化"部分。
支持的密码套件
TLS 1.3 的密码套件数量远少于 TLS 1.2(不再有"密钥交换 + 认证 + 批量加密"的自由组合),取决于库配置,以下五套理论上均可支持:
TLS_AES_128_GCM_SHA256TLS_AES_256_GCM_SHA384TLS_CHACHA20_POLY1305_SHA256TLS_AES_128_CCM_SHA256TLS_AES_128_CCM_8_SHA256
密码套件表在 library/ssl_ciphersuites.c 中维护(该文件同样引用了 MBEDTLS_SSL_PROTO_TLS1_3)。由于 TLS 1.3 全部使用 AEAD,TLS 1.2 时代的 MBEDTLS_SSL_ENCRYPT_THEN_MAC、MBEDTLS_SSL_EXTENDED_MASTER_SECRET 等选项对 TLS 1.3 而言是"不适用(n/a)"。
ClientHello 扩展支持矩阵
原文档给出了一张完整的 ClientHello 扩展支持表,直接继承如下:
| 扩展 | 支持 |
|---|---|
| server_name | YES |
| max_fragment_length | no |
| status_request | no |
| supported_groups | YES |
| signature_algorithms | YES |
| use_srtp | no |
| heartbeat | no |
| apln(ALPN) | YES |
| signed_certificate_timestamp | no |
| client_certificate_type | no |
| server_certificate_type | no |
| padding | no |
| key_share | YES |
| pre_shared_key | no |
| psk_key_exchange_modes | no |
| early_data | no |
| cookie | no |
| supported_versions | YES |
| certificate_authorities | no |
| post_handshake_auth | no |
| signature_algorithms_cert | no |
(注:表中 apln 为原文拼写,对应实际扩展 ALPN,仓库中的 MBEDTLS_SSL_ALPN 宏默认开启。)
可以看到,TLS 1.3 握手所需的核心扩展——supported_versions、key_share、supported_groups、signature_algorithms、server_name、ALPN——均已实现;而 PSK/early data/会话恢复相关扩展全部未实现,与"不支持 PSK、0-RTT"的能力边界完全一致。
支持的椭圆曲线组与签名算法
- 支持的组:取决于库配置,ECDHE 组理论上全部支持:
secp256r1、x25519、secp384r1、x448、secp521r1;有限域组(DHE)不支持。 - 支持的签名算法(证书与 CertificateVerify 均适用,取决于库配置):
ecdsa_secp256r1_sha256、ecdsa_secp384r1_sha384、ecdsa_secp521r1_sha512、rsa_pkcs1_sha256、rsa_pkcs1_sha384、rsa_pkcs1_sha512、rsa_pss_rsae_sha256、rsa_pss_rsae_sha384、rsa_pss_rsae_sha512。 - 强制算法提醒:在没有应用侧 profile 标准另行规定时,
rsa_pkcs1_sha256、rsa_pss_rsae_sha256、ecdsa_secp256r1_sha256三者为规范第 9.1 节规定的强制项,实现层面需保证默认可用。
签名算法与证书/密钥的匹配校验可在 ssl_tls13_generic.c 的 ssl_tls13_check_sig_alg_cert_key_match() 与 ssl_tls13_select_sig_alg_for_certificate_verify() 中看到对应实现。
版本支持与运行时协商约束
- 客户端侧支持 TLS 1.2 与 TLS 1.3 的版本协商(通过
supported_versions扩展向服务器表达能力); - 服务器端不参与版本协商;
- TLS 1.2 与 TLS 1.3 可相互独立地编译启用;
- 运行时约束:若同时编译启用了 TLS 1.2 与 TLS 1.3,对服务器端点而言,通过
mbedtls_ssl_conf_min_tls_version()/mbedtls_ssl_conf_max_tls_version()(ssl.h)只能把版本区间限定到二者之一;否则mbedtls_ssl_setup()会返回MBEDTLS_ERR_SSL_BAD_CONFIG错误。
与既有 TLS 1.2 构建选项的兼容性
原文档的核心结论是:TLS 1.3 实现与几乎所有 TLS 1.2 配置选项兼容——开启 TLS 1.3 时,极少需要改动原本为 TLS 1.2 准备的配置。仅有的两个例外是 MBEDTLS_PSA_CRYPTO_C 与 MBEDTLS_SSL_KEEP_PEER_CERTIFICATE(必须保持启用)。
其余 SSL/TLS 相关选项对 TLS 1.3 大多不支持或不适用,完整对照表如下:
| Mbed TLS 配置选项 | 支持 |
|---|---|
| MBEDTLS_SSL_ALL_ALERT_MESSAGES | no |
| MBEDTLS_SSL_ASYNC_PRIVATE | no |
| MBEDTLS_SSL_CONTEXT_SERIALIZATION | no |
| MBEDTLS_SSL_DEBUG_ALL | no |
| MBEDTLS_SSL_ENCRYPT_THEN_MAC | n/a |
| MBEDTLS_SSL_EXTENDED_MASTER_SECRET | n/a |
| MBEDTLS_SSL_KEEP_PEER_CERTIFICATE | no (1) |
| MBEDTLS_SSL_RENEGOTIATION | n/a |
| MBEDTLS_SSL_MAX_FRAGMENT_LENGTH | no |
| MBEDTLS_SSL_SESSION_TICKETS | no |
| MBEDTLS_SSL_SERVER_NAME_INDICATION | yes |
| MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH | no |
| MBEDTLS_ECP_RESTARTABLE | no |
| MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED | no |
| MBEDTLS_KEY_EXCHANGE_PSK_ENABLED | n/a (2) |
| MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_RSA_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED | n/a |
| MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED | n/a |
| MBEDTLS_PSA_CRYPTO_C | no (1) |
| MBEDTLS_USE_PSA_CRYPTO | yes |
注释说明:(1) 这些选项必须保持默认的"启用"状态;(2) TLS 1.3 的密钥交换配置选项未来将围绕密钥交换模式组织,即上文提到的 MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE/PSK/PSK_EPHEMERAL/EPHEMERAL 运行时宏体系。
值得注意的例外是 MBEDTLS_SSL_SERVER_NAME_INDICATION(SNI)与 MBEDTLS_USE_PSA_CRYPTO 在 TLS 1.3 下为 yes——SNI 对应 ClientHello 表中的 server_name 扩展。
原型上游化进度:尚未合并的部分
Mbed TLS 的 TLS 1.3 基于外部原型演进,以下部分尚未上游到当前仓库:
- 预共享密钥、会话恢复与 0-RTT 数据(客户端与服务器端两侧均未完成)——这是当前实现最大的能力缺口,与本仓库"不支持任何形式的会话恢复"的行为一致。
- 新的 TLS 消息处理栈(MPS,Message Processing Stack):原型开发伴随 TLS 消息层的重写,涵盖记录解析、握手重组、DTLS 重传状态机等底层细节。MPS 由四层加两个辅助组件构成:
- Layer 1:数据报处理(Datagram handling)
- Layer 2:记录处理(Record handling)
- Layer 3:消息处理(Message handling)
- Layer 4:重传状态机(Retransmission State Machine)
- Reader:入站数据的指针运算与重组逻辑抽象
- Writer:出站数据的指针运算与分片逻辑抽象
截至本文档版本,随 MBEDTLS_SSL_PROTO_TLS1_3 一起上游的 MPS 组件仅有 Reader,对应文件为 third_party/mbedtls/library/mps_reader.h(连同 mps_reader.c、mps_common.h、mps_error.h 等辅助文件)。测试方面,tests/suites/test_suite_mps.function 为 MPS 提供了专门的单元测试套件。
TLS 1.3 专用编码规则清单
TLS 1.3 上游化工作的代码审查成本较高,Mbed TLS 在文档中沉淀了一套专用编码规则,作为每次 PR 的自检清单(不替代项目总体编码规范,规范来源见文档中引用的 mbedtls-coding-standards 页面)。这些规则对阅读、贡献 TLS 1.3 代码的人来说是极好的"地图":
命名约定
- TLS 1.3 专用的 C 模块、头文件、静态函数以
ssl_tls13_前缀命名,模块内部的结构体与类型同样如此; - 导出的函数、结构体与类型以
mbedtls_ssl_tls13_前缀命名; - TLS 1.3 专用宏中使用
TLS1_3字样; - 与规范中字段/结构相关的宏与变量名应尽量携带规范字段名;若字段名过长需缩写,则全代码库统一使用同一缩写。
向量(length-prefixed vector)的指针命名惯例
<vector_name>_len:存放向量字节长度的变量;p_<vector_name>_len:存放向量长度字段首字节地址的变量;<vector_name>:存放向量值首字节地址的变量;<vector_name>_end:存放向量值末尾后一字节地址的变量。
原文档以 ClientHello 的 cipher_suites 向量为例:
size_t cipher_suites_len;
unsigned char *p_cipher_suites_len;
unsigned char *cipher_suites;
该惯例降低了"拿错地址类型"的风险——例如误把长度字段地址当值地址使用,可能引发严重问题。
字节序与缓冲区安全宏 适用处应使用:
MBEDTLS_BYTE_{0-8}:从多字节整数提取单字节;MBEDTLS_PUT_UINT{8|16|32|64}_BE:按大端序把多字节整数写入内存;MBEDTLS_GET_UINT{8|16|32|64}_BE:按大端序从内存读出多字节整数;MBEDTLS_SSL_CHK_BUF_PTR:写输出缓冲区前的空间检查;MBEDTLS_SSL_CHK_BUF_READ_PTR:读输入缓冲区前的数据检查。
前两类宏提升可读性、降低字节序写错的风险;后两类宏把"读写不越界"的指针算术集中化,与上面的指针命名惯例配合,共同规避缓冲区越界。示例:
hs_hdr[1] = MBEDTLS_BYTE_2( total_hs_len );
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0 );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 );
其他通用规则
- 解析/写入函数中一律使用局部变量
p作为读写指针(该名字在既有 TLS 代码中已广泛使用,避免重蹈 PR #4882 讨论中的覆辙); - 读写 TLS 1.3 结构时,在函数注释中附上规范定义的结构;
- 关联语句分组排列、不插入空行;跨函数复用的常量用宏(如
#define CLIENT_HELLO_RANDOM_LEN 32),仅函数内局部使用的常量无需建宏; - 指针声明时解引用符
*贴近指针名(如mbedtls_ssl_context *ssl;); - 行宽上限 80 字符,字符串字面量可超限以便搜索;重构导致超长时避免在同一次提交内重排(先提交超长行、再单独提交重排,降低审查难度);
- 连续行中函数/宏参数垂直对齐;参数跨行时按语义分组(例如
mbedtls_ssl_start_handshake_msg( ssl, hs_type, buf, buf_len );优于把buf与hs_type拆开排列)。
握手代码组织:状态机与处理管线
顶层状态机
TLS 1.3 握手协议实现为一个状态机,顶层函数为 mbedtls_ssl_tls13_handshake_client_step()(ssl_tls13_client.c)与 mbedtls_ssl_tls13_handshake_server_step()(ssl_tls13_server.c),二者均为覆盖全部可能状态的 switch 语句。它们由通用的 mbedtls_ssl_handshake_step() 在 ssl_tls.c 中按协议版本分派调用。
状态机设计上有两个值得注意的原则:
- 并非逐状态顺序遍历:若所有状态都顺序执行,会迫使每个状态处理器重复检查"是否要做某事",因此对可跳过的状态直接绕过。例如客户端侧,若握手基于预共享密钥(不含证书),则证书解析与校验相关状态被跳过。
- 部分可跳过状态反而强制经过:当"强制经过"能最小化入站/出站密钥更新时机的不确定性时,即使可跳过也会走一遍。客户端侧的
MBEDTLS_SSL_CLIENT_CERTIFICATE状态即为此类例子——从源码看,该状态处理器位于 ssl_tls13_client.c,且在mbedtls_ssl_tls13_handshake_client_step()的 switch 中被显式列出,同时还有 L1955 处的状态回退逻辑。
消息处理(process)管线的五阶段
处理握手消息的处理器命名统一为 mbedtls_ssl_tls13_process_*(如 mbedtls_ssl_tls13_process_certificate、mbedtls_ssl_tls13_process_certificate_verify、mbedtls_ssl_tls13_process_finished_message,见 ssl_tls13_generic.c)。每个处理器内部按阶段拆分,以压缩代码规模、降低出错概率:
- 协调阶段(coordination,可选):判断本状态是否应被绕过。判断依据要么仅读取 SSL 上下文的某些字段值,要么读取下一条消息的类型——后者用于尚不确定下一消息类型的情形(例如客户端侧不确定将收到 CertificateRequest 还是其他消息)。除读取下一条记录外,此阶段不应修改 SSL 上下文,因为它可能因下一条握手消息未到达而被重复执行。
- 获取阶段(fetching):此时已确定下一握手消息的类型并尝试获取。若未经过涉及"下一记录类型读取"的协调阶段,下一条消息可能尚未到达,处理器返回
MBEDTLS_ERR_SSL_WANT_READ且不改变当前状态,稍后会被再次调用。仓库为此提供了公共封装mbedtls_ssl_tls13_fetch_handshake_msg()(ssl_tls13_generic.c)。 - 预处理阶段(pre-processing,可选):为消息解析准备 SSL 上下文,或简化解析代码。此阶段可做少量简单解析,如 ServerHello 消息的预处理。
- 解析阶段(parsing):解析消息,并尽可能限制对 SSL 上下文的更新。预处理/解析/后处理的分层目的,就是让解析函数只专注解析,从而缩小函数体、简化逻辑。
- 后处理阶段(post-processing,可选):解析完成后进一步更新 SSL 上下文,为后续入站/出站消息做准备。例如秘密(secret)与密钥计算、握手消息校验和(transcript hash)更新均发生在这一阶段。
- 状态迁移(state change):统一在主状态处理器中完成,便于追踪状态机转移路径。
消息写入(write)管线的五阶段
写入手处理器命名统一为 mbedtls_ssl_tls13_write_*(如 mbedtls_ssl_tls13_write_certificate、mbedtls_ssl_tls13_write_certificate_verify、mbedtls_ssl_tls13_write_finished_message、mbedtls_ssl_tls13_write_change_cipher_spec,均见 ssl_tls13_generic.c)。管线阶段与处理侧对称:
- 协调阶段(可选):基于 SSL 上下文字段值判断是否跳过;
- 准备阶段(preparation,可选):为消息写入做前置处理或简化写入代码;
- 写入阶段(writing):写入消息,并尽可能限制对 SSL 上下文的更新(准备/写入/终结的分层让写入函数只专注写入);
- 终结阶段(finalization,可选):写入完成后更新 SSL 上下文,例如握手秘密与密钥计算(如 ServerHello 写入的终结)、服务端切换到出站方向的握手密钥,都在此阶段发生;
- 状态迁移(state change):同样统一在主状态处理器中完成。
出站数据刷新的关键约定
数据向对端的发送只发生在 mbedtls_ssl_handshake_step() 中、处理器调用之间,因此处理器无需处理 MBEDTLS_ERR_SSL_WANT_WRITE 错误码;且在调用下一个处理器前所有待发数据都已刷新完毕。这保证处理器在更换出站密钥时无需担心仍有未刷新的待发数据——这是整个写入管线能安全地"在终结阶段切换出站密钥"的前提。
测试与验证路径
当前仓库为 TLS 1.3 提供了多层验证手段,可作为实现能力的事实佐证:
- 运行时密钥交换模式测试:tests/ssl-opt.sh 中的用例通过
tls13_kex_modes=psk / psk_ephemeral / ephemeral / ephemeral_all / psk_all / all参数驱动ssl_server2与ssl_client2,覆盖MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_*的各类组合;这些用例均以requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3为前提。 - 示例程序:programs/ssl/ssl_client2.c 与 programs/ssl/ssl_server2.c 支持通过
tls13_kex_modes、min_version/max_version等命令行参数在真实握手场景中验证 TLS 1.3 行为。 - 测试套件:tests/suites/test_suite_ssl.data 与 tests/suites/test_suite_ssl.function 承载 SSL 层(含 TLS 1.3 相关路径)的单元测试;
test_suite_mps.function覆盖 MPS Reader。 - 构建脚本:tests/scripts/all.sh 与 tests/scripts/generate_tls13_compat_tests.py 负责 TLS 1.3 兼容性测试的生成与调度;tests/opt-testcases/tls13-compat.sh 提供了与 OpenSSL/GnuTLS 对测的用例模板。
小结:启用 TLS 1.3 前的决策清单
基于本仓库 Mbed TLS 的实际实现,若要启用 MBEDTLS_SSL_PROTO_TLS1_3,建议按以下清单核对:
- 确保
MBEDTLS_PSA_CRYPTO_C与MBEDTLS_SSL_KEEP_PEER_CERTIFICATE保持启用;如需全链路 PSA,另开MBEDTLS_USE_PSA_CRYPTO。 - 确认使用场景落在能力边界内:仅 ECDHE、无 PSK/会话恢复/0-RTT;服务端若同时编译了 TLS 1.2,运行时须把
min/max_tls_version收敛到单一版本。 - 按需开启
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE以提升中间盒穿透性。 - 选择密码套件与曲线组时,以
MBEDTLS_SSL_PROTO_TLS1_3相关配置为准,并保证rsa_pkcs1_sha256、rsa_pss_rsae_sha256、ecdsa_secp256r1_sha256三种强制签名算法可用。 - 使用 tests/ssl-opt.sh 的
tls13_kex_modes用例或 ssl_client2/ssl_server2 对握手做端到端验证。
若需要同时追踪 Mbed TLS 中 TLS 1.3 的实现细节,可直接以 ssl_tls13_generic.c 的消息处理/写入管线为入口,配合本文的"阶段划分 + 命名约定"阅读,可以较快建立起对这套状态机实现的完整心智模型。