mbedtls學習4.mbedtls_RAM/ROM優化指南

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)

優化前的準備

  1. 首先你要有準備接入的 SSL 服務器(保證能正常工作)
  2. 準備好接入 SSL 服務器的 PEM 格式根證書文件(存放到 mbedtls 軟件包 certs 目錄下,刪除其他不需要的證書)
  3. 使用默認的 mbedtls 配置文件成功接通 SSL 服務器(優化後更難定位失敗原因)
  4. 逐項優化 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 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章