mbedtls 默认提供的 config.h 文件是一个通用的、全功能的配置,占用了非常大的 RAM 和 ROM 空间,但是保证了 SSL 握手和通讯的建立速度、稳定性、协议兼容性以及数据传输效率。但嵌入式设备受限于其有限的 RAM 和 ROM 空间,我们不得不牺牲速度来节省 RAM 空间,裁剪不需要的功能模块来降低 ROM 占用。
因此,开发者在进行 SSL/TLS 优化前,在 MCU 资源条件允许的情况下,请先使用默认的配置调通 SSL/TLS 握手连接和加密通讯,然后再根据 SSL/TLS 服务器具体的配置进行逐项优化。
#define MBEDTLS_SSL_CIPHERSUITES / MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
RO(CODE + RO) : 159828 bytes(156.08K)RW(RW + ZI) : 720 bytesROM(CODE + RO + RW) : 159972 bytes(156.22K)动态内存使用 : 26849 bytes(26.22K)(包含 1K 的测试 buffer)
RO(CODE + RO) : 71893 bytes(70.21K)RW(RW + ZI) : 82 bytesROM(CODE + RO + RW) : 71975 bytes(70.29K)动态内存使用 : 23344 bytes(22.79K)(包含 1K 的测试 buffer)
如果您的 MCU 资源比较小,无法使用默认的 tls_config.h 配置文件,开发者可以选择使用 QEMU 虚拟机进行开发调试以及 mbedtls 优化。将 mbedtls 资源占用优化到合适的时候,再使用您需要的 MCU 进行验证测试。
MBEDTLS_ASN1_PARSE_C | 使能通用的 ASN1 解析器。ASN1: 一种描述数字对象的方法和标准,需要启用 | 启用 |
MBEDTLS_ASN1_WRITE_C | 启用通用 ASN1 编写器 | 启用 |
MBEDTLS_BIGNUM_C | 启用大整数库 (multi-precision integer library) | 启用 |
MBEDTLS_CIPHER_C | 启用通用密码层 | 启用 |
MBEDTLS_AES_C | 启用 AES 加密。PEM_PARSE 使用 AES 来解密被加密的密钥。通过启用 AES 来支持 *_WITH_AES_* 类型的加密套件 | 启用 |
MBEDTLS_CTR_DRBG_C (依赖:MBEDTLS_AES_C) | 启用基于 CTR_DRBG AES-256 的随机生成器 | 启用 |
MBEDTLS_MD_C | 启用通用消息摘要层,需要启用 | 启用 |
MBEDTLS_OID_C | 启用OID数据库,此模块在OID和内部值之间进行转换,需要启用 | 启用 |
MBEDTLS_PK_C (依赖:MBEDTLS_RSA_C、MBEDTLS_ECP_C) | 启用通用公共(非对称)密钥层,需要启用 | 启用 |
MBEDTLS_PK_PARSE_C (依赖:MBEDTLS_PK_C) | 启用通用公共(非对称)密钥解析器,需要启用 | 启用 |
MBEDTLS_SHA256_C | 启用 SHA-224 和 SHA-256 加密哈希算法,根据根证书详细信息中的签名哈希算法进行选择 | 根据需要选择 |
MBEDTLS_SHA512_C | 启用 SHA-384 和 SHA-512 加密哈希算法,根据根证书详细信息中的签名哈希算法进行选择 | 根据需要选择 |
MBEDTLS_SSL_CLI_C (依赖:MBEDTLS_SSL_TLS_C) | 启用 SSL 客户端代码,作为 SSL 服务端的时候不需要启用 | 启用 |
MBEDTLS_SSL_SRV_C (依赖:MBEDTLS_SSL_TLS_C) | 启用 SSL 服务端代码,作为 SSL 客户端的时候不需要启用 | 禁用 |
MBEDTLS_SSL_TLS_C (依赖:MBEDTLS_CIPHER_C、MBEDTLS_MD_C 和至少定义一个 MBEDTLS_SSL_PROTO_XXX) | 使能 SSL/TLS 代码 | 启用 |
MBEDTLS_X509_CRT_PARSE_C (依赖:MBEDTLS_X509_USE_C) | 使能 X509 证书解析 | 启用 |
MBEDTLS_X509_USE_C (依赖:MBEDTLS_ASN1_PARSE_C、MBEDTLS_BIGNUM_C、MBEDTLS_OID_C、MBEDTLS_PK_PARSE_C) | 启用X.509核心以使用证书 | 启用 |
MBEDTLS_BASE64_C | 启用 base64 组件,PEM 证书解析需要使用 | 启用 |
MBEDTLS_CERTS_C | 该模块用于测试 SSL 客户端和服务器,可以选择禁用 | 可禁用 |
MBEDTLS_PEM_PARSE_C(依赖:MBEDTLS_BASE64_C) | 启用对 PEM 文件解码解析的支持 | 启用 |
MBEDTLS_RSA_C (依赖:MBEDTLS_BIGNUM_C、MBEDTLS_OID_C) | 启用RSA公钥密码系统。RSA、DHE-RSA、ECDHE-RSA、RSA-PSK 方式的密钥交换需要使用 | 启用 |
MBEDTLS_SHA1_C | 启用 SHA1 加密哈希算法。TLS 1.1/1.2 需要使用 | 启用 |
MBEDTLS_MD5_C | 启用MD5哈希算法。PEM 解析需要使用 | 启用 |
MBEDTLS_PK_PARSE_EC_EXTENDED (依赖:) | 该宏用以支持 RFC 5915 和RFC 5480 不允许的 SEC1 变体增强对读取 EC 密钥的支持 | 可以禁用 |
MBEDTLS_ERROR_STRERROR_DUMMY | 启用虚拟错误功能,以便在禁用 MBEDTLS_ERROR_C 时更容易在第三方库中使用 mbedtls_strerror()(启用 MBEDTLS_ERROR_C 时无效) | 可以禁用 |
MBEDTLS_GENPRIME (依赖:MBEDTLS_BIGNUM_C) | 启用素数生成代码 | 可以禁用 |
MBEDTLS_FS_IO | 启用文件系统交互相关的功能函数 | 可以禁用 |
MBEDTLS_PKCS5_C (依赖:MBEDTLS_MD_C) | 该模块增加了对 PKCS#5 功能的支持。AES 算法数据填充方案的需要。根据需要选择是否禁用 | 根据需要选择 |
MBEDTLS_PKCS12_C (依赖:MBEDTLS_ASN1_PARSE_C、MBEDTLS_CIPHER_C、MBEDTLS_MD_C) | 添加用于解析 PKCS#8 加密私钥的算法 | 可以禁用 |
MBEDTLS_PKCS1_V15 (依赖:MBEDTLS_RSA_C) | 用于支持 PKCS#1 v1.5 操作,RSA 密钥套件需要使用。如果使用了 RSA 密钥套件,则需要启用 | 根据需要选择 |
MBEDTLS_PKCS1_V21 (依赖:MBEDTLS_MD_C、MBEDTLS_RSA_C) | 启用对 PKCS#1 v2.1 编码的支持,这样可以支持 RSAES-OAEP 和 RSASSA-PSS 操作 | 可以禁用 |
MBEDTLS_PK_RSA_ALT_SUPPORT | 支持 PK 层中的外部私有 RSA 密钥(例如,来自 HSM)。不需要启用,禁用 | 禁用 |
MBEDTLS_SELF_TEST | 启用检查功能。建议在启用 debug 的时候启用,其他时候禁用 | 可以禁用 |
MBEDTLS_SSL_ALL_ALERT_MESSAGES | 启用警报消息发送功能 | 可以禁用 |
MBEDTLS_SSL_ENCRYPT_THEN_MAC | 启用对Encrypt-then-MAC,RFC 7366的支持。用于加强对 CBC 密码套件的保护,可以禁用 | 可以禁用 |
MBEDTLS_SSL_EXTENDED_MASTER_SECRET | 启用对扩展主密钥的支持 | 可以禁用 |
MBEDTLS_SSL_FALLBACK_SCSV | 注释此宏以禁用客户端使用回退策略 | 可以禁用 |
MBEDTLS_SSL_CBC_RECORD_SPLITTING | 在 SSLv3 和 TLS 1.0 中为 CBC 模式启用 1/n-1 记录拆分。启用该宏以降低 BEAST 攻击的风险,可以选择性禁用 | 可以禁用 |
MBEDTLS_SSL_RENEGOTIATION | 屏蔽该宏禁用对TLS重新协商的支持。启用可能会带来安全风险,建议禁用 | 禁用 |
MBEDTLS_SSL_MAX_FRAGMENT_LENGTH | 在 SSL 中启用对 RFC 6066 最大帧长度扩展的支持 | 可以禁用 |
MBEDTLS_SSL_ALPN | 启用对 RFC 7301 应用层协议协商的支持 | 可以禁用 |
MBEDTLS_SSL_SESSION_TICKETS | 在SSL中启用对RFC 5077会话 tickets 的支持,需要服务端支持。通常用来优化握手流程 | 可以禁用 |
MBEDTLS_SSL_EXPORT_KEYS | 启用对导出密钥块和主密钥的支持。 这对于 TLS 的某些用户是必需的,例如 EAP-TLS | 可以禁用 |
MBEDTLS_SSL_SERVER_NAME_INDICATION (依赖:MBEDTLS_X509_CRT_PARSE_C) | 在 SSL 中启用对 RFC 6066 服务器名称指示(SNI)的支持 | 可以禁用 |
MBEDTLS_SSL_TRUNCATED_HMAC | 在 SSL 中启用对 RFC 6066 截断 HMAC 的支持 | 可以禁用 |
MBEDTLS_VERSION_FEATURES (依赖:MBEDTLS_VERSION_C) | 版本功能信息相关 | 可以禁用 |
MBEDTLS_VERSION_C | 该模块提供运行时版本信息 | 可以禁用 |
MBEDTLS_X509_CHECK_KEY_USAGE | 启用 keyUsage 扩展(CA和叶证书)的验证。禁用此功能可避免错误发布和/或误用(中间)CA 和叶证书的问题。注释后跳过 keyUsage 检查 CA 和叶证书 | 可以禁用 |
MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE | 启用 extendedKeyUsage 扩展(叶证书)的验证。禁用此功能可避免错误发布和/或误用证书的问题 | 可以禁用 |
MBEDTLS_X509_RSASSA_PSS_SUPPORT | 启用使用 RSASSA-PSS(也称为 PKCS#1 v2.1)签名的 X.509 证书,CRL 和 CSRS 的解析和验证。根据需要选择是否禁用 | 根据需要选择 |
MBEDTLS_BLOWFISH_C | 启用 Blowfish 分组密码 | 可以禁用 |
MBEDTLS_ERROR_C | 启用错误代码到错误字符串的转换 | 可以禁用 |
MBEDTLS_HMAC_DRBG_C (依赖:MBEDTLS_MD_C) | 启用随机字节发生器 | 可以禁用 |
MBEDTLS_PEM_WRITE_C (依赖:MBEDTLS_BASE64_C) | 此模块添加了对编码/写入PEM文件的支持。TLS Client 不需要 | 可以禁用 |
MBEDTLS_PK_WRITE_C(依赖:MBEDTLS_PK_C) | 启用通用公钥写入功能。嵌入式系统一般不需要,禁用 | 禁用 |
MBEDTLS_RIPEMD160_C | RIPEMD (RACE原始完整性校验讯息摘要)是一种加密哈希函数,通用性差于 SHA-1/2 | 可以禁用 |
MBEDTLS_SSL_CACHE_C | 启用 SSL 缓存 | 可以禁用 |
MBEDTLS_SSL_TICKET_C(依赖:MBEDTLS_CIPHER_C) | 服务端的配置 | 禁用 |
MBEDTLS_X509_CRL_PARSE_C(依赖:MBEDTLS_X509_USE_C) | CRL: Certidicate Revocation List (CRL) 证书吊销列表模块 | 可以禁用 |
MBEDTLS_X509_CSR_PARSE_C (依赖:MBEDTLS_X509_USE_C) | Certificate Signing Request (CSR).证书签名请求解析,用于 DER 证书 | 可以禁用 |
MBEDTLS_X509_CREATE_C (依赖:MBEDTLS_BIGNUM_C、MBEDTLS_OID_C、MBEDTLS_PK_WRITE_C) | 启用X.509核心以创建证书,服务器需要 | 禁用 |
MBEDTLS_X509_CRT_WRITE_C (依赖:MBEDTLS_X509_CREATE_C) | 启用创建证书,服务器需要。禁用 | |
MBEDTLS_X509_CSR_WRITE_C (依赖:MBEDTLS_X509_CREATE_C) | 启用创建X.509证书签名请求(CSR) | 可以禁用 |
MBEDTLS_XTEA_C | 启用 XTEA 分组密码 | 可以禁用 |
MBEDTLS_ECDSA_DETERMINISTIC (依赖:MBEDTLS_HMAC_DRBG_C) | 启用确定性 ECDSA(RFC 6979),防止签名时缺少熵而导致签名密钥泄露。建议启用 | 建议启用 |
在数组 static const int ciphersuite_preference[] 中定义了所有支持的密码套件,如果开启支持所有的密码套件将会占用非常大的 ROM 空间。这里建议用户通过 MBEDTLS_SSL_CIPHERSUITES 宏来指定客户端与服务器使用具体哪种加密套件。指定加密套件后,将不需要的加密套件和依赖的功能组件全部禁用,同时禁用不需要的椭圆曲线,来最大程度上节省 ROM 空间。
MBEDTLS_SSL_CIPHERSUITES | 通过指定密码套件来节省 ROM 和 几百字节的 RAM。这里注意需要指定服务器支持的加密套件,并为该加密套件启用相关的功能组件,关闭其他功能组件。如果只接入一个 SSL 服务器,通常这里只需要定义支持一个加密套件即可 | 仅指定根证书需要的加密套件 |
MBEDTLS_AES_C | 通过启用 AES 来支持 *_WITH_AES_* 类型的密码套件 | 根据需要选择 |
MBEDTLS_GCM_C (依赖:MBEDTLS_AES_C、MBEDTLS_CAMELLIA_C) | 启用该配置来支持 *_AES_GCM_*、*_CAMELLIA_GCM_* 类型的密码套件 | 根据需要选择 |
MBEDTLS_REMOVE_ARC4_CIPHERSUITES | 默认启用,在 SSL/TLS 中禁用 RC4 密码套件 | 根据需要选择 |
MBEDTLS_ARC4_C | 启用 RC4 加密套件,*_WITH_RC4* 类型密码套件。根据需要选择是否禁用 | 根据需要选择 |
MBEDTLS_CAMELLIA_C | 启用 Camellia 分组密码,用于支持 *_WITH_CAMELLIA_* 类型的密码套件。根据需要选择是否禁用 | 根据需要选择 |
MBEDTLS_CIPHER_MODE_CBC | 为对称密码启用密码块链接模式(CBC)。如果使用了 CBC 密码套件则需要启用 | 根据需要选择 |
MBEDTLS_CIPHER_MODE_CFB | 为对称密码启用密码反馈模式(CFB)。如果使用了 CFB 密码套件则需要启用 | 根据需要选择 |
MBEDTLS_CIPHER_MODE_CTR | 启用对称密码的计数器分组密码模式(CTR)。如果使用了 CTR 密码套件则需要启用 | 根据需要选择 |
MBEDTLS_CIPHER_PADDING_XXX | 在密码层中启用填充模式。如果禁用所有填充模式,则只有完整块可以与 CBC 一起使用 | 根据需要选择,可以全禁用 |
MBEDTLS_CIPHER_PADDING_PKCS7 | | 可以禁用 |
MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS | | 可以禁用 |
MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN | | 可以禁用 |
MBEDTLS_CIPHER_PADDING_ZEROS | | 可以禁用 |
MBEDTLS_CIPHER_PADDING_XXX | | |
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED (依赖:MBEDTLS_ECDH_C、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_ECDH_RSA_* 类型的密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED (依赖:MBEDTLS_ECDH_C、MBEDTLS_RSA_C、MBEDTLS_PKCS1_V15、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_ECDHE_RSA_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED (依赖:MBEDTLS_ECDH_C、MBEDTLS_ECDSA_C、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_ECDHE_ECDSA_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED (依赖:MBEDTLS_ECDH_C、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_ECDHE_ECDSA_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED (依赖:MBEDTLS_DHM_C、MBEDTLS_RSA_C、MBEDTLS_PKCS1_V15、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_DHE_RSA_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_PSK_ENABLED | 启用 *_PSK_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED(依赖:MBEDTLS_DHM_C) | 启用 *_DHE_PSK_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED (依赖:MBEDTLS_ECDH_C) | 启用 *_ECDHE_PSK_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED (依赖:MBEDTLS_RSA_C、MBEDTLS_PKCS1_V15、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_RSA_PSK_* 类型密码套件 | 根据需要选择 |
MBEDTLS_KEY_EXCHANGE_RSA_ENABLED (依赖:MBEDTLS_RSA_C、MBEDTLS_PKCS1_V15、MBEDTLS_X509_CRT_PARSE_C) | 启用 *_RSA_* 类型密码套件 | 根据需要选择 |
MBEDTLS_CCM_C (依赖:MBEDTLS_AES_C 或 MBEDTLS_CAMELLIA_C) | 启用具有 CBC-MAC(CCM)模式的计数器用于128位分组密码,用于支持 AES-CCM 密码套件。根据需要选择是否禁用 | 根据需要选择 |
MBEDTLS_DES_C | 启用 DES 块密码 | 可以禁用 |
MBEDTLS_DHM_C | 启用 Diffie-Hellman-Merkle 模块,用于支持 DHE-RSA, DHE-PSK 密码套件。根据需要选择是否禁用 | 根据需要选择 |
MBEDTLS_ECDH_C (依赖:MBEDTLS_ECP_C) | 启用椭圆曲线 Diffie-Hellman 库。用于支持 *_ECDHE_ECDSA_*、*_ECDHE_RSA_*、*_DHE_PSK_* 类型的密码套件 | 根据需要选择 |
MBEDTLS_ECDSA_C(依赖:MBEDTLS_ECP_C、MBEDTLS_ASN1_WRITE_C、MBEDTLS_ASN1_PARSE_C) | 用于支持 *_ECDHE_ECDSA_* 类型的密码套件 | 根据需要选择 |
MBEDTLS_ECP_C(依赖:MBEDTLS_BIGNUM_C 和至少一个 MBEDTLS_ECP_DP_XXX_ENABLED) | 启用 GF(p) 椭圆曲线 | 根据需要选择 |
MBEDTLS_ECP_XXXX_ENABLED | 在椭圆曲线模块中启用特定的曲线。默认情况下启用所有支持的曲线。可以根据实际情况选择一个曲线即可 | 根据需要选择 |
MBEDTLS_ECP_DP_SECP192R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP224R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP256R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP384R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP521R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP192K1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP224K1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_SECP256K1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_BP256R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_BP384R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_BP512R1_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_DP_CURVE25519_ENABLED | | 根据需要选择 |
MBEDTLS_ECP_XXXX_ENABLED | | |
通常 SSL/TLS 服务器支持多种 TLS 协议版本,客户端则不需要支持所有的协议版本。因此在确定服务器支持的 TLS 协议版本后,可以禁用其他版本的协议。
DTLS 是基于 UDP 的安全加密连接,目的是保障 UDP 通讯的数据安全。由于 UDP 本身不支持自动重传,且存在丢包问题,所以在进行握手连接的时候与 TLS 有些许不同,但两者重复了大部分的代码。因此可以通过下表中的配置来优化 DTLS 加密连接。