mbedTLS debug and questions - XradioTech/XR871-OLD GitHub Wiki


mbedTLS调试和常见问题


mbedTLS的配置文件和打印

  • mbedTLS的配置文件

可通过mbedTLS的配置文件,来配置、裁剪mbedTLS的功能,减少mbedTLS的资源占用。 (1)文件位置 配置文件在include/net/mbedtls/configs目录中。SDK选择的配置文件为config-xr-mini-cliserv.h。 (2)修改SDK配置文件 mbedTLS的配置文件需要在Makefile文件中修改。mbedTLS的Makefile文件在/src/net/mbedtls-2.2.0目录中,修改项为CC_FLAGS += -DMBEDTLS_CONFIG_FILE='<config-xr-mini-cliserv.h>'。一般不建议修改为其他配置文件。 (3)配置文件的修改 配置文件主要是通过添加或减去一些宏来配置mbedTLS的功能,比如支持的加解密算法、密钥协商算法、输入输出缓冲区大小等。config-xr-mini-cliserv.h配置文件所有的宏都来源于/include/net/mbedtls/config.h,该文件对每个宏都有详细的解释。也可参考链接: https://www.rt-thread.org/document/site/submodules/mbedtls/docs/footprint-optimization-guide/

  • 开mbedTLS打印

mbedTLS是以连接为单位,每条连接的资源都相互独立,比如打印函数、发送/接收函数、输入输出缓冲区等。故mbedTLS的每条连接都可以单独设置打印函数,但打印等级不能单独设置。 (1)打开打印宏   在include/net/mbedtls/configs/config-xr-mini-cliserv.h文件中,将宏MBEDTLS_DEBUG_C打开。 (2)注册打印函数 在初始化一个mbedTLS连接时,调用mbedtls_ssl_conf_dbg为这条连接注册打印回调函数。debug_function为自己编写的打印函数.例如:

static void mbedtls_debug(void *ctx, int level,const char *file, int line, const char *str)
{
  printf("%s:%04d: %s", file, line, str);
}
mbedtls_ssl_conf_dbg(&conf, mbedtls_debug, stdout);

具体可参考/src/net/mbedtls-2.2.0/mbedtls.c或/project/common/cmd/tls/client.c中例子。 (3)设置打印等级 注册完打印回调函数后,调用mbedtls_debug_set_threshold函数设置打印等级。mbedtls有5个打印等级,一般设置为3。

0:No debug 1:Error 2:State change 3:Informational 4:Verbose。

注: 如果使用SDK中HTTPC模块中的HTTPC_get函数下载https链接文件,并且需要开mbedTLS打印,则只需要打开宏MBEDTLS_DEBUG_C,修改/src/net/mbedtls-2.2.0/mbedtls.c文件的宏TLS_DEBUG_LEVEL,一般设置为3。如果需要开HTTPC模块的打印,则需要开net/HTTPClient/API/debug.h中的宏_HTTP_DEBUGGING_HTTPCLIENT_DEBUG


mbedTLS常见问题

以下列出了部分常见问题,更多常见问题更新中。

  • 连接时,死机重启 查看调用mbedTLS连接的线程的栈大小,建议栈空间大于等于3K。

  • 握手失败,返回-0x7200错误码 搜索-0x7200得到如下结果: #define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 /**< An invalid SSL record was received. */ 这个错误表示SSL记录层收到一个无效的帧。产生这个问题的原因有两个:   1)访问的服务器不支持数据分片;   2)mbedTLS设置输入输出缓冲区太小。   解决办法: 增加mbedTLS的输入输出缓冲区大小,修改include/net/mbedtls/configs/config-xr-mini-cliserv.h的宏MBEDTLS_SSL_MAX_CONTENT_LEN 为(16*1024)。目前很多服务器都默认不支持数据分片,所以为了增加mbedTLS的兼容性,设置缓冲区大小为16K(最大为16K),增加缓存区大小,会增加内存占用。

  • 握手失败,返回-0x7780错误码 搜索-0x7780得到如下结果: #define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */     记录层接收到对端的一个致命警告。记录层的警告较多,可通过mbedTLS的打印查看是什么类型的警告,常见的警告是客户端和服务器加解密套件不同引起的。   确定警告类型: (1) 打开mbedTLS打印,在通过打印确定错误位置,以下为部分打印:

mbedtls: ssl_tls.c:3905 got an alert message, type: [2:40]
mbedtls: ssl_tls.c:3913 is a fatal alert message (msg 40)
mbedtls: ssl_cli.c:1402 mbedtls_ssl_read_record() returned -30592 (-0x7780)
mbedtls: ssl_tls.c:6286 <= handshake
[inf] _TLSConnectNetwork(430): failed  ! mbedtls_ssl_handshake returned -0x7780
mbedtls: ssl_tls.c:6838 => write close notify
mbedtls: ssl_tls.c:6854 <= write close notify

(2) 通过打印mbedtls: ssl_tls.c:3905 got an alert message, type: [2:40]确定警告类型:警告类型是2,致命警告,编码为40。 (3) 查询RFC4346警报协议的相关资料,编码为40的警告为双方无法协商安全参数,即加密套件不匹配导致的,加密套件的选择可参考 “如何配置合适的加解密套件”部分。

  • mbedtls握手速度慢 握手速度慢一般有两个原因: (1) 网络不稳定,导致数据传输慢。 (2) 握手阶段密钥协商算法计算速度慢,常见于ECDHE和ECDSA密钥协商算法,解决办法是在config-xr-mini-cliserv.h添加宏#define MBEDTLS_ECP_NIST_OPTIM,为每个 NIST 启用特定的实例,使相应曲线上的操作快 4 到 8 倍,缺点是 ROM 占用大。

如何配置合适的加密套件

不同的加解密套件占用的资源不一样,比如内存占用和加解密时间占用,所以在客户端配置合适的加解密套件可以尽量减少资源的消耗。 在配置客户端加解密套件前,必须要知道需要连接的服务器支持的加解密套件,可通过链接https://www.ssllabs.com/ssltest/测试并获取服务器的信息。

输入需要测试的网址: ssllabs-ssltest-1

等待分析完成: ssllabs-ssltest-2

查看测试分析结果:(该图为服务器支持的加密套件) ssllabs-ssltest-3

如果设备只连接固定的服务器,为了减少内存的使用,可选择较简单的加解密算法,以降低内存和时间的消耗。上图中,可尽量选择TLS_RSA_WITH_AES_128_CBC_SHA加解密套件。密钥交换算法为RSA,对称加密为AES,密钥长度为128,模式为CBC模式,哈希算法为SHA算法。通过修改config-xr-mini-cliserv.h中的宏可修改设备端支持的加解密套件。当设备端和服务器进行握手时,设备端会将支持的加解密套件列表发送给服务器,服务器会在列表中选择第一个匹配到的加解密套件来进行后续的加解密通讯。根据上图,可以选择宏MBEDTLS_RSA_CMBEDTLS_AES_CMBEDTLS_CIPHER_MODE_CBCMBEDTLS_SHA1_CMBEDTLS_KEY_EXCHANGE_RSA_ENABLED

下图为另外一台服务器支持的加解密套件列表: ssllabs-ssltest-4 上图的服务器只支持ECDHE_RSA秘钥交换算法,可选择TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA加解密套件。因为上面的服务器只支持ECDHE_RSA,所以需要开宏MBEDTLS_ECDH_CMBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED,由于需要支持ECDH secp521r1,所以还需要开宏MBEDTLS_ECP_CMBEDTLS_ECP_DP_SECP521R1_ENABLED