MbedTLS RAM 和 ROM 资源占用优化指南

mbedtls 软件包采用了模块化的设计,可以使用 config.h 文件来进行功能模块的配置选择。

mbedtls 默认提供的 config.h 文件是一个通用的、全功能的配置,占用了非常大的 RAM 和 ROM 空间,但是保证了 SSL 握手和通讯的建立速度、稳定性、协议兼容性以及数据传输效率。但嵌入式设备受限于其有限的 RAM 和 ROM 空间,我们不得不牺牲速度来节省 RAM 空间,裁剪不需要的功能模块来降低 ROM 占用。

本优化指南,在保证 SSL/TLS 客户端能与服务器建立安全稳定连接的前提下,对 RAM 和 ROM 占用进行优化统计。

注意:

mbedtls 客户端的优化属于针对性优化,针对特定的 SSL/TLS 服务器进行的优化,不同的 SSL/TLS 服务器配置不同,优化所用到的配置参数也是不同的。

因此,开发者在进行 SSL/TLS 优化前,在 MCU 资源条件允许的情况下,请先使用默认的配置调通 SSL/TLS 握手连接和加密通讯,然后再根据 SSL/TLS 服务器具体的配置进行逐项优化。

当然,多数情况下您并不知道服务器的具体参数配置,因此也只能试探性优化,本文给出了各个配置的说明,来方便开发者进行针对性的优化。

优化说明

  • RAM 资源占用统计说明

首先保证 SSL 握手连接正常,加密数据通讯正常。运行 tls_test 测试例程,进行 RAM 优化测试。测试例程在单独的线程中运行,通过对比 SSL 握手成功前后所占用的内存来确定在握手通讯过程所使用的 RAM 情况。该测试方法只能粗略估计 SSL 客户端成功进行握手连接所需要的 RAM 大小,该数据包含了保证握手通讯所需要的额外的 RAM 空间。

  • ROM 资源占用统计说明

通过对比启动 mbedtls 功能组件前后参与链接的文件来统计 mbedtls 所占用 ROM 大小。

  • 测试平台: iMXRT1052

  • 测试 IDE: MDK5

  • 优化级别: o2
  • 测试例程: samples/tls_app_test.c
  • 测试使用的 SSL 服务器: www.rt-thread.org
  • 测试服务器根证书签名算法: sha1RSA
  • 测试服务器根证书签名哈希算法: sha1
  • 测试服务器根证书公钥: RSA 2048 bits
  • 测试服务器根证书指纹算法: sha1
  • SSL 客户端指定密码套件
  1. #define MBEDTLS_SSL_CIPHERSUITES \
  2. MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
  • SSL 客户端指定帧大小为 #define MBEDTLS_SSL_MAX_CONTENT_LEN 3584
  • 测试使用的配置(详见文末

    优化后的资源占用汇总

  • 默认的 tls_config.h 配置资源占用情况

mbedtls 默认的配置文件为 mbedtls/include/mbedtls/config.h,而 RT-Thread 使用的配置文件为 ports/inc/tls_config.h。用户进行配置优化的时候也是使用的 ports/inc/tls_config.h 文件。

  1. RO(CODE + RO) : 159828 bytes156.08K
  2. RW(RW + ZI) : 720 bytes
  3. ROM(CODE + RO + RW) : 159972 bytes156.22K
  4. 动态内存使用 : 26849 bytes26.22K)(包含 1K 的测试 buffer
  • 优化后的配置资源占用情况
  1. RO(CODE + RO) : 71893 bytes70.21K
  2. RW(RW + ZI) : 82 bytes
  3. ROM(CODE + RO + RW) : 71975 bytes70.29K
  4. 动态内存使用 : 23344 bytes22.79K)(包含 1K 的测试 buffer

优化前的准备

  • 首先你要有准备接入的 SSL 服务器(保证能正常工作)
  • 准备好接入 SSL 服务器的 PEM 格式根证书文件(存放到 mbedtls 软件包 certs 目录下,删除其他不需要的证书)
  • 使用默认的 mbedtls 配置文件成功接通 SSL 服务器(优化后更难定位失败原因)
  • 逐项优化 mbedtls 配置,反复测试
    注意:

如果您的 MCU 资源比较小,无法使用默认的 tls_config.h 配置文件,开发者可以选择使用 QEMU 虚拟机进行开发调试以及 mbedtls 优化。将 mbedtls 资源占用优化到合适的时候,再使用您需要的 MCU 进行验证测试。

优化配置概述

常用优化配置

通过对下面列表中的配置进行修改,可以很大程度上降低 mbedtls RAM 和 ROM 的占用。

开发者在进行优化时,建议优先对下面列表中的配置进行优化,如果不能满足要求,再针对其他的配置进行逐项的优化。

配置 依赖 说明 优化建议
const char mbedtls_root_certificate[] 存储根证书的常量数组。编译的时候,会将 PEM 证书添加到该数组。建议只在 certs 证书目录存放需要的根证书文件,否则会占用非常大的 RAM 和 ROM 空间 只存放需要的证书文件
MBEDTLS_SSL_CIPHERSUITES 通过指定密码套件来节省几百字节的 ROM 和 几百字节的 RAM。这里注意需要指定服务器支持的加密套件,并为该加密套件启用相关的功能组件,关闭其他功能组件。如果只接入一个 SSL 服务器,通常这里只需要定义支持一个加密套件即可 仅指定根证书需要的加密套件
MBEDTLS_AES_ROM_TABLES 将 AES 表存储在 ROM 中以节省 RAM 占用(很大程度上降低 RAM 占用) 建议启用
MBEDTLS_SSL_MAX_CONTENT_LEN 默认为 16384。RFC定义了 SSL/TLS 消息的默认大小,如果您在此处更改值,则其他客户端/服务器可能无法再与您通信。除非你能确定服务端的帧大小。根据服务器发送的最大帧大小做适当的修改 适当调小(出现 0x7200 错误时请增大该配置)
MBEDTLS_MPI_MAX_SIZE 可用的 MPI 最大字节数,默认为 1024,可以根据适当调小 适当调小
MBEDTLS_MPI_WINDOW_SIZE MPI 用于模幂运算的最大窗口数量,默认为6,选值范围:1-6,可适当调小 适当调小
MBEDTLS_ECP_MAX_BITS GF(p) 椭圆曲线最大位,默认为 521 适当调小
MBEDTLS_ECP_WINDOW_SIZE 用于点乘的最大窗口大小,默认为 6,选值范围: 2-7,可以适当减小,减小会影响速度 适当调小
MBEDTLS_ECP_FIXED_POINT_OPTIM 默认1,启用定点加速。启用后,将加速点乘运算大约 3 到 4 倍,成本是峰值内存占用增加约 2 倍。可以配置为 0,牺牲速度来节省 RAM 占用 可优化配置为 0
MBEDTLS_ECP_NIST_OPTIM 为每个 NIST 启用特定的实例,使相应曲线上的操作快 4 到 8 倍,缺点是 ROM 占用大。可以选择性优化 可禁用
MBEDTLS_ENTROPY_MAX_SOURCES 最大的熵源数量,最小为2,默认使用 mbedtls_platform_entropy_poll 源。RT-Thread 上使用最小配置 2 可优化配置为 2

系统相关配置

这部分配置跟具体的系统和编译器相关,下表列出了在 RT-Thread 上需要做的配置。

配置 依赖 说明 优化建议
MBEDTLS_HAVE_ASM 需要编译器可以处理汇编代码 启用
MBEDTLS_HAVE_TIME 如果您的系统没有 time.h 和 time() 函数,请注释该配置 启用
MBEDTLS_HAVE_TIME_DATE 如果您的系统没有 time.h、time()、gmtime() 或者没有正确的时钟,请注释该配置 启用
MBEDTLS_DEBUG_C 定义该配置以启动调试 log 输出 如需调试log,则启用,否则请禁用
MBEDTLS_NET_C 该配置仅支持 POSIX/Unix 和 windows 系统,在 RT-Thread 系统上需要关闭 禁用
MBEDTLS_NO_PLATFORM_ENTROPY 如果您的平台不支持 /dev/urandom 或 Windows CryptoAPI 等标准,则需要启用该配置。RT-Thread 上必须启用 启用
MBEDTLS_TIMING_C 如果注释,则需要用户自己实现相关的函数。默认启用 启用
MBEDTLS_TIMING_ALT 如果注释,则需要用户自己实现相关的函数。默认启用 启用
MBEDTLS_ENTROPY_HARDWARE_ALT 如果注释,则需要用户自己实现相关的函数。默认启用 启用
MBEDTLS_ENTROPY_C MBEDTLS_SHA256_C 或 MBEDTLS_SHA512_C 启用特定于平台的熵代码。需要启用 启用
MBEDTLS_PADLOCK_C MBEDTLS_HAVE_ASM 在x86上启用VIA Padlock支持 禁用
MBEDTLS_AESNI_C MBEDTLS_HAVE_ASM 在x86-64上启用AES-NI支持 禁用
MBEDTLS_PLATFORM_C 使能平台抽象层,用于重定义实现 free、printf 等函数 启用

功能组件相关配置

用户可以根据要接入的 SSL/TLS 服务器特性以及根证书使用的签名算法来选择启用哪部分的功能。启用或禁用功能组件时请注意将相关的依赖打开或禁用。

配置 依赖 说明 优化建议
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 加密。PEMPARSE 使用 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),防止签名时缺少熵而导致签名密钥泄露。建议启用 建议启用

密码套件相关配置

mbedtls 中密码套件命名形式为 MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384

mbedtls 在数组 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_GCMCAMELLIA_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_ECDSAECDHE_RSADHE_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

TLS 版本选择相关配置

通常 SSL/TLS 服务器支持多种 TLS 协议版本,客户端则不需要支持所有的协议版本。因此在确定服务器支持的 TLS 协议版本后,可以禁用其他版本的协议。

配置 依赖 说明 优化建议
MBEDTLS_SSL_PROTO_TLS1 MBEDTLS_MD5_C、MBEDTLS_SHA1_C 启用对 TLS 1.0 版本的支持 根据需要选择
MBEDTLS_SSL_PROTO_TLS1_1 MBEDTLS_MD5_C、MBEDTLS_SHA1_C 启用对 TLS 1.1 版本的支持 根据需要选择
MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SHA1_C 或者 MBEDTLS_SHA256_C 或者 MBEDTLS_SHA512_C 启用对 TLS 1.2 版本的支持 根据需要选择

DTLS 相关配置

DTLS 是基于 UDP 的安全加密连接,目的是保障 UDP 通讯的数据安全。由于 UDP 本身不支持自动重传,且存在丢包问题,所以在进行握手连接的时候与 TLS 有些许不同,但两者重复了大部分的代码。因此可以通过下表中的配置来优化 DTLS 加密连接。

如果用户的系统中,不需要使用 DTLS,则可以将下表中的所有配置禁用。

配置 依赖 说明 优化建议
MBEDTLS_SSL_PROTO_DTLS MBEDTLS_SSL_PROTO_TLS1_1 或 MBEDTLS_SSL_PROTO_TLS1_2 启用 DTLS 功能,用于对 UDP 进行加密 如果不需要 DTLS 加密连接,则禁用
MBEDTLS_SSL_DTLS_ANTI_REPLAY MBEDTLS_SSL_TLS_C、MBEDTLS_SSL_PROTO_DTLS 启用对DTLS中的反重放机制的支持 可以禁用
MBEDTLS_SSL_DTLS_HELLO_VERIFY MBEDTLS_SSL_PROTO_DTLS 启用对 DTLS HelloVerifyRequest 的支持 需要开启
MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE MBEDTLS_SSL_DTLS_HELLO_VERIFY 为从同一端口重新连接的客户端启用服务器端支持,需要服务器特殊支持 可以禁用
MBEDTLS_SSL_DTLS_BADMAC_LIMIT MBEDTLS_SSL_PROTO_DTLS 启用支持 MAC 错误的记录限制 可以禁用
MBEDTLS_SSL_COOKIE_C DTLS hello cookie 支持。非 DTLS 下可以禁用 可以禁用

参考

  1. /* tls_config.h*/
  2. #ifndef MBEDTLS_CONFIG_H
  3. #define MBEDTLS_CONFIG_H
  4.  
  5. #include <rtthread.h>
  6.  
  7. #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
  8. #define _CRT_SECURE_NO_DEPRECATE 1
  9. #endif
  10.  
  11. #define MBEDTLS_HAVE_ASM
  12. #define MBEDTLS_HAVE_TIME
  13. #define MBEDTLS_ASN1_PARSE_C
  14. #define MBEDTLS_ASN1_WRITE_C
  15. #define MBEDTLS_BIGNUM_C
  16. #define MBEDTLS_CIPHER_C
  17. #define MBEDTLS_AES_C
  18. #define MBEDTLS_CTR_DRBG_C
  19. // #define MBEDTLS_ECDH_C
  20. // #define MBEDTLS_ECDSA_C
  21. #define MBEDTLS_ECP_C
  22. // #define MBEDTLS_GCM_C
  23. #define MBEDTLS_MD_C
  24. // #define MBEDTLS_NET_C
  25. #define MBEDTLS_OID_C
  26. #define MBEDTLS_PK_C
  27. #define MBEDTLS_PK_PARSE_C
  28. #define MBEDTLS_SHA256_C
  29. // #define MBEDTLS_SHA512_C
  30. #define MBEDTLS_SSL_CLI_C
  31. // #define MBEDTLS_SSL_SRV_C
  32. #define MBEDTLS_SSL_TLS_C
  33. #define MBEDTLS_X509_CRT_PARSE_C
  34. #define MBEDTLS_X509_USE_C
  35. #define MBEDTLS_BASE64_C
  36. // #define MBEDTLS_CERTS_C
  37. #define MBEDTLS_PEM_PARSE_C
  38. #define MBEDTLS_AES_ROM_TABLES
  39. #define MBEDTLS_MPI_MAX_SIZE 384
  40. #define MBEDTLS_MPI_WINDOW_SIZE 2
  41. #define MBEDTLS_ECP_MAX_BITS 384
  42. #define MBEDTLS_ECP_WINDOW_SIZE 2
  43. #define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
  44. #define MBEDTLS_ECP_NIST_OPTIM
  45. #define MBEDTLS_ENTROPY_MAX_SOURCES 2
  46. #define MBEDTLS_SSL_CIPHERSUITES \
  47. MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
  48.  
  49. // #define MBEDTLS_SSL_MAX_CONTENT_LEN 3584
  50. #define MBEDTLS_NO_PLATFORM_ENTROPY
  51. // #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
  52. #define MBEDTLS_RSA_C
  53. #define MBEDTLS_SHA1_C
  54. #define MBEDTLS_TIMING_C
  55. #define MBEDTLS_ENTROPY_HARDWARE_ALT
  56. #define MBEDTLS_TIMING_ALT
  57. // #define MBEDTLS_DEBUG_C
  58. #define MBEDTLS_MD5_C
  59. // #define MBEDTLS_HAVE_TIME_DATE
  60. #define MBEDTLS_CIPHER_MODE_CBC
  61. // #define MBEDTLS_CIPHER_MODE_CFB
  62. // #define MBEDTLS_CIPHER_MODE_CTR
  63. // #define MBEDTLS_CIPHER_PADDING_PKCS7
  64. // #define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
  65. // #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
  66. // #define MBEDTLS_CIPHER_PADDING_ZEROS
  67. #define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
  68. // #define MBEDTLS_ECP_DP_SECP192R1_ENABLED
  69. // #define MBEDTLS_ECP_DP_SECP224R1_ENABLED
  70. #define MBEDTLS_ECP_DP_SECP256R1_ENABLED
  71. #define MBEDTLS_ECP_DP_SECP384R1_ENABLED
  72. // #define MBEDTLS_ECP_DP_SECP521R1_ENABLED
  73. // #define MBEDTLS_ECP_DP_SECP192K1_ENABLED
  74. // #define MBEDTLS_ECP_DP_SECP224K1_ENABLED
  75. // #define MBEDTLS_ECP_DP_SECP256K1_ENABLED
  76. // #define MBEDTLS_ECP_DP_BP256R1_ENABLED
  77. // #define MBEDTLS_ECP_DP_BP384R1_ENABLED
  78. // #define MBEDTLS_ECP_DP_BP512R1_ENABLED
  79. // #define MBEDTLS_ECP_DP_CURVE25519_ENABLED
  80. // #define MBEDTLS_ECDSA_DETERMINISTIC
  81. // #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
  82. // #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
  83. // #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
  84. // #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
  85. // #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
  86. // #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
  87. // #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
  88. // #define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
  89. // #define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
  90. #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
  91. // #define MBEDTLS_PK_PARSE_EC_EXTENDED
  92. // #define MBEDTLS_ERROR_STRERROR_DUMMY
  93. // #define MBEDTLS_GENPRIME
  94. // #define MBEDTLS_FS_IO
  95. // #define MBEDTLS_PK_RSA_ALT_SUPPORT
  96. // #define MBEDTLS_PKCS12_C
  97. #define MBEDTLS_PKCS1_V15
  98. // #define MBEDTLS_PKCS1_V21
  99. // #define MBEDTLS_SELF_TEST
  100. // #define MBEDTLS_SSL_ALL_ALERT_MESSAGES
  101. // #define MBEDTLS_SSL_ENCRYPT_THEN_MAC
  102. // #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
  103. // #define MBEDTLS_SSL_FALLBACK_SCSV
  104. // #define MBEDTLS_SSL_CBC_RECORD_SPLITTING
  105. // #define MBEDTLS_SSL_RENEGOTIATION
  106. // #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
  107. // #define MBEDTLS_SSL_PROTO_TLS1
  108. // #define MBEDTLS_SSL_PROTO_TLS1_1
  109. #define MBEDTLS_SSL_PROTO_TLS1_2
  110. // #define MBEDTLS_SSL_ALPN
  111. // #define MBEDTLS_SSL_PROTO_DTLS
  112. // #define MBEDTLS_SSL_DTLS_ANTI_REPLAY
  113. // #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
  114. // #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
  115. // #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
  116. // #define MBEDTLS_SSL_SESSION_TICKETS
  117. // #define MBEDTLS_SSL_EXPORT_KEYS
  118. // #define MBEDTLS_SSL_SERVER_NAME_INDICATION
  119. // #define MBEDTLS_SSL_TRUNCATED_HMAC
  120. // #define MBEDTLS_VERSION_FEATURES
  121. // #define MBEDTLS_X509_CHECK_KEY_USAGE
  122. // #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
  123. // #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
  124. // #define MBEDTLS_AESNI_C
  125. // #define MBEDTLS_ARC4_C
  126. // #define MBEDTLS_BLOWFISH_C
  127. // #define MBEDTLS_CAMELLIA_C
  128. // #define MBEDTLS_CCM_C
  129. // #define MBEDTLS_DES_C
  130. // #define MBEDTLS_DHM_C
  131. #define MBEDTLS_ENTROPY_C
  132. // #define MBEDTLS_ERROR_C
  133. // #define MBEDTLS_HMAC_DRBG_C
  134. // #define MBEDTLS_PADLOCK_C
  135. // #define MBEDTLS_PEM_WRITE_C
  136. // #define MBEDTLS_PK_WRITE_C
  137. // #define MBEDTLS_PKCS5_C
  138. #define MBEDTLS_PLATFORM_C
  139. // #define MBEDTLS_RIPEMD160_C
  140. // #define MBEDTLS_SSL_CACHE_C
  141. // #define MBEDTLS_SSL_COOKIE_C
  142. // #define MBEDTLS_SSL_TICKET_C
  143. // #define MBEDTLS_VERSION_C
  144. // #define MBEDTLS_X509_CRL_PARSE_C
  145. // #define MBEDTLS_X509_CSR_PARSE_C
  146. // #define MBEDTLS_X509_CREATE_C
  147. // #define MBEDTLS_X509_CRT_WRITE_C
  148. // #define MBEDTLS_X509_CSR_WRITE_C
  149. // #define MBEDTLS_XTEA_C
  150.  
  151. #if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
  152. #include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
  153. #elif defined(MBEDTLS_USER_CONFIG_FILE)
  154. #include MBEDTLS_USER_CONFIG_FILE
  155. #endif
  156.  
  157. #include "mbedtls/check_config.h"
  158.  
  159. #define tls_malloc rt_malloc
  160. #define tls_free rt_free
  161. #define tls_realloc rt_realloc
  162. #define tls_calloc rt_calloc
  163.  
  164. #endif /* MBEDTLS_CONFIG_H */

原文: https://www.rt-thread.org/document/site/submodules/mbedtls/docs/footprint-optimization-guide/