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 客戶端指定密碼套件
#define MBEDTLS_SSL_CIPHERSUITES \
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
文件。
RO(CODE + RO) : 159828 bytes(156.08K)
RW(RW + ZI) : 720 bytes
ROM(CODE + RO + RW) : 159972 bytes(156.22K)
動態內存使用 : 26849 bytes(26.22K)(包含 1K 的測試 buffer)
- 優化後的配置資源佔用情況
RO(CODE + RO) : 71893 bytes(70.21K)
RW(RW + ZI) : 82 bytes
ROM(CODE + RO + RW) : 71975 bytes(70.29K)
動態內存使用 : 23344 bytes(22.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§ 橢圓曲線最大位,默認爲 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 加密。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),防止簽名時缺少熵而導致簽名密鑰泄露。建議啓用 | 建議啓用 |
密碼套件相關配置
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_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§ 橢圓曲線 | 根據需要選擇 |
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 下可以禁用 | 可以禁用 |
參考
- mbedTLS 官方網站:https://tls.mbed.org/
- 測試時用的配置文件
/* tls_config.h*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
#include <rtthread.h>
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_AES_C
#define MBEDTLS_CTR_DRBG_C
// #define MBEDTLS_ECDH_C
// #define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
// #define MBEDTLS_GCM_C
#define MBEDTLS_MD_C
// #define MBEDTLS_NET_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_SHA256_C
// #define MBEDTLS_SHA512_C
#define MBEDTLS_SSL_CLI_C
// #define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_BASE64_C
// #define MBEDTLS_CERTS_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_MPI_MAX_SIZE 384
#define MBEDTLS_MPI_WINDOW_SIZE 2
#define MBEDTLS_ECP_MAX_BITS 384
#define MBEDTLS_ECP_WINDOW_SIZE 2
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
#define MBEDTLS_SSL_CIPHERSUITES \
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
// #define MBEDTLS_SSL_MAX_CONTENT_LEN 3584
#define MBEDTLS_NO_PLATFORM_ENTROPY
// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_TIMING_C
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_TIMING_ALT
// #define MBEDTLS_DEBUG_C
#define MBEDTLS_MD5_C
// #define MBEDTLS_HAVE_TIME_DATE
#define MBEDTLS_CIPHER_MODE_CBC
// #define MBEDTLS_CIPHER_MODE_CFB
// #define MBEDTLS_CIPHER_MODE_CTR
// #define MBEDTLS_CIPHER_PADDING_PKCS7
// #define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
// #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
// #define MBEDTLS_CIPHER_PADDING_ZEROS
#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
// #define MBEDTLS_ECP_DP_SECP192R1_ENABLED
// #define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
// #define MBEDTLS_ECP_DP_SECP521R1_ENABLED
// #define MBEDTLS_ECP_DP_SECP192K1_ENABLED
// #define MBEDTLS_ECP_DP_SECP224K1_ENABLED
// #define MBEDTLS_ECP_DP_SECP256K1_ENABLED
// #define MBEDTLS_ECP_DP_BP256R1_ENABLED
// #define MBEDTLS_ECP_DP_BP384R1_ENABLED
// #define MBEDTLS_ECP_DP_BP512R1_ENABLED
// #define MBEDTLS_ECP_DP_CURVE25519_ENABLED
// #define MBEDTLS_ECDSA_DETERMINISTIC
// #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
// #define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
// #define MBEDTLS_PK_PARSE_EC_EXTENDED
// #define MBEDTLS_ERROR_STRERROR_DUMMY
// #define MBEDTLS_GENPRIME
// #define MBEDTLS_FS_IO
// #define MBEDTLS_PK_RSA_ALT_SUPPORT
// #define MBEDTLS_PKCS12_C
#define MBEDTLS_PKCS1_V15
// #define MBEDTLS_PKCS1_V21
// #define MBEDTLS_SELF_TEST
// #define MBEDTLS_SSL_ALL_ALERT_MESSAGES
// #define MBEDTLS_SSL_ENCRYPT_THEN_MAC
// #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
// #define MBEDTLS_SSL_FALLBACK_SCSV
// #define MBEDTLS_SSL_CBC_RECORD_SPLITTING
// #define MBEDTLS_SSL_RENEGOTIATION
// #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
// #define MBEDTLS_SSL_PROTO_TLS1
// #define MBEDTLS_SSL_PROTO_TLS1_1
#define MBEDTLS_SSL_PROTO_TLS1_2
// #define MBEDTLS_SSL_ALPN
// #define MBEDTLS_SSL_PROTO_DTLS
// #define MBEDTLS_SSL_DTLS_ANTI_REPLAY
// #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
// #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
// #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
// #define MBEDTLS_SSL_SESSION_TICKETS
// #define MBEDTLS_SSL_EXPORT_KEYS
// #define MBEDTLS_SSL_SERVER_NAME_INDICATION
// #define MBEDTLS_SSL_TRUNCATED_HMAC
// #define MBEDTLS_VERSION_FEATURES
// #define MBEDTLS_X509_CHECK_KEY_USAGE
// #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
// #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
// #define MBEDTLS_AESNI_C
// #define MBEDTLS_ARC4_C
// #define MBEDTLS_BLOWFISH_C
// #define MBEDTLS_CAMELLIA_C
// #define MBEDTLS_CCM_C
// #define MBEDTLS_DES_C
// #define MBEDTLS_DHM_C
#define MBEDTLS_ENTROPY_C
// #define MBEDTLS_ERROR_C
// #define MBEDTLS_HMAC_DRBG_C
// #define MBEDTLS_PADLOCK_C
// #define MBEDTLS_PEM_WRITE_C
// #define MBEDTLS_PK_WRITE_C
// #define MBEDTLS_PKCS5_C
#define MBEDTLS_PLATFORM_C
// #define MBEDTLS_RIPEMD160_C
// #define MBEDTLS_SSL_CACHE_C
// #define MBEDTLS_SSL_COOKIE_C
// #define MBEDTLS_SSL_TICKET_C
// #define MBEDTLS_VERSION_C
// #define MBEDTLS_X509_CRL_PARSE_C
// #define MBEDTLS_X509_CSR_PARSE_C
// #define MBEDTLS_X509_CREATE_C
// #define MBEDTLS_X509_CRT_WRITE_C
// #define MBEDTLS_X509_CSR_WRITE_C
// #define MBEDTLS_XTEA_C
#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
#elif defined(MBEDTLS_USER_CONFIG_FILE)
#include MBEDTLS_USER_CONFIG_FILE
#endif
#include "mbedtls/check_config.h"
#define tls_malloc rt_malloc
#define tls_free rt_free
#define tls_realloc rt_realloc
#define tls_calloc rt_calloc
#endif /* MBEDTLS_CONFIG_H */