精华内容
下载资源
问答
  • mbedtls ecdsa使用样例

    2021-01-07 22:47:27
    该code是基于最新的mbedtls所列出的,样例的代码路径如下所示 mbedtls/crypto/programs/pkey/ecdsa.c 具体的code如下所示 #if !defined(MBEDTLS_CONFIG_FILE) #include mbedtls/config.h #else #include MBEDTLS_...
  • mbedtls官方文档(包括所有API说明)的离线版本,方便没网时候单机查询,chm格式,原始网站为:https://tls.mbed.org/api/,手工拉取所有网站内容制作的离线版本文档。
  • 本文介绍如何使用mbedtls编译生成RSA 4096长度的公私钥,再使用私钥进行PSS签名,公钥验签
  • mbedtls-2.16.5-apache.tgz

    2020-03-21 09:17:12
    ARM公司,自家开源 mbedtls-2.16.3-apache.tgz 2020-3-21最新发布版本。 针对ARM 有很多汇编级别的优化配置,开源有维护定期升级,使用新版本替换文件即可。 VS2010 很多工程包,可以直接编译。 Linux 下自带...
  • mbedtls.zip

    2020-01-21 14:24:37
    Mbedtls加解密工具代码。
  • mbedtls 2.16.0

    2019-03-04 11:25:46
    官方的mbedtls库,2.16.0版本,移植教程可以去他们的github上面看,https://github.com/ARMmbed/mbedtls
  • mbedtls源代码

    2019-02-02 16:46:55
    mbedtls源代码
  • mbedtls源码.rar

    2019-10-14 16:34:06
    mbedtls源码,c语言实现,包含各种加解密算法,非对称加密等
  • 密码技术与物联网安全:mbedtls开发实战.pdf
  • ARM.mbedTLS.1.7.0.pack

    2021-09-16 09:54:43
    ARM.mbedTLS.1.7.0.pack
  • mbedTLS 展示了如何在 PIC32MZ2048EFH144 以太网入门套件上使用 Microchips Harmony Framework 2.04 mbedTLS 和 UART2 上的控制台接口(路由到 MCP2221 芯片) 在此版本中,只有 mbedTLS 源代码可用。 此版本中未...
  • STM32F103CB_mbedtls_Demo.zip

    2021-04-22 22:23:06
    基于STM32HAL库,移植mbedtls开源库支持mqtt证书加密,该demo包含(mbedtls-2.24.0.zip)源码,对应博文:...
  • 在ESP32下,使用mbedtls库,测试sha1和sha256/224 aes_ecb、aes_cbc的简单DEMO
  • mbedtls, 开放源码可以移植易于使用可以读和灵活的SSL库 mbed的自述文件配置mbed TLS应该在大多数系统中构建。 有些平台特定的选项在完全文档化的配置文件 include/mbedtls/config.h 中可以用,这也是特性可以以选择...
  • mbedtls-2.16.3-apache.tgz

    2019-12-04 09:41:06
    最新版本的mbedtls-2.16.5-apache.tgz已经上次 请转到这里下载 2020-03-21 的最新版本 https://download.csdn.net/download/yinggegege/12260002 ARM公司,自家开源 mbedtls-2.16.3-apache.tgz 最新发布版本。 ...
  • ARM.mbedTLS.1.5.0pack包

    2018-11-14 08:45:32
    MDK 中使用的 MbedTLS 包,可以直接安装到MDK,用作算法加密
  • stm32f4 mqtt
  • 基于MbedTLS的AES加密实现,含STM32H7和STM32F4的实现例程-附件资源
  • MbedTLS-Test-源码

    2021-04-29 09:51:35
    MbedTLS测试 警告! 这是测试项目! 开发环境 硬件 ST MICRO STM32F103VC皮质M3 Wiznet W5500硬件TCP / IP堆栈IC 个人设计的板。 软件 科德 海湾合作委员会 固件 MbedTLS 2.1.2 可以从下载,但MbedTLS库存在...
  • mbedtls-2.13 最新

    2019-01-08 17:35:33
    mbed tls 被设计成尽可能松散耦合,让你只需要整合你需要的部分,而不需要关注其余部分.这也为mbed tls 带来了非常低内存占用和构建足迹.通过消除你系统中不需要的部分,你可以将构建版本从低至45kB的版本升级到更典型...
  • mbedtls学习4.mbedtls_RAM/ROM优化指南

    千次阅读 2020-05-26 14:11:29
    MbedTLS RAM 和 ROM 资源占用优化指南 mbedtls 软件包采用了模块化的设计,可以使用 config.h 文件来进行功能模块的配置选择。 mbedtls 默认提供的 config.h 文件是一个通用的、全功能的配置,占用了非常大的 RAM 和...

    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_SIZEMPI 用于模幂运算的最大窗口数量,默认为6,选值范围:1-6,可适当调小适当调小
    MBEDTLS_ECP_MAX_BITSGF§ 椭圆曲线最大位,默认为 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_CRIPEMD (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_CDTLS 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 */
    
    展开全文
  • mbedtls学习3.mbedtls_API分析

    千次阅读 2020-05-26 14:10:31
    注:更多详细 API 内容请参阅 ARM mbedtls API 手册。 应用层 API 应用层 API 是提供给用户在 App 中直接使用的 API,这部分 API 屏蔽了 mbedtls 内部具体的操作步骤,简化了用户使用。 mbedtls 初始化 int mbedtls...

    1.API 说明

    为了方便用户使用,这里列出了常用的 API,并给出了相关的使用说明。

    注:更多详细 API 内容请参阅 ARM mbedtls API 手册

    应用层 API

    应用层 API 是提供给用户在 App 中直接使用的 API,这部分 API 屏蔽了 mbedtls 内部具体的操作步骤,简化了用户使用。

    mbedtls 初始化

    int mbedtls_client_init(MbedTLSSession *session, void *entropy, size_t entropyLen);
    

    mbedtls 客户端初始化函数,用于初始化底层网络接口、设置证书、设置 SSL 会话等。

    参数描述
    session入参,mbedtls 会话对象 MbedTLSSession
    entropy入参,mbedtls 熵字符串
    entropyLen入参,mbedtls 熵字符串长度
    返回描述
    = 0成功
    !0失败

    配置 mbedtls 上下文

    int mbedtls_client_context(MbedTLSSession *session);
    

    SSL 层配置,应用程序使用 mbedtls_client_context 函数配置客户端上下文信息,包括证书解析、设置主机名、设置默认 SSL 配置、设置认证模式(默认 MBEDTLS_SSL_VERIFY_OPTIONAL)等。

    参数描述
    session入参,mbedtls 会话对象 MbedTLSSession
    返回描述
    = 0成功
    !0失败

    建立 SSL/TLS 连接

    int mbedtls_client_connect(MbedTLSSession *session);
    

    使用 mbedtls_client_connect 函数为 SSL/TLS 连接建立通道。这里包含整个的握手连接过程,以及证书校验结果。

    参数描述
    session入参,mbedtls 会话对象 MbedTLSSession
    返回描述
    = 0成功
    !0失败

    读取数据

    • 向加密连接写入数据
    int mbedtls_client_write(MbedTLSSession *session, const unsigned char *buf , size_t len);
    
    参数描述
    session入参,mbedtls 会话对象 MbedTLSSession
    buf入参,待写入的数据缓冲区
    len入参,待写入的数据长度
    返回描述
    = 0成功
    !0失败
    • 从加密连接读取数据
    int mbedtls_client_read(MbedTLSSession *session, unsigned char *buf , size_t len);
    
    参数描述
    session入参,mbedtls 会话对象 MbedTLSSession
    buf入参,mbedtls 读取内容的缓冲区
    len入参,mbedtls 待读取内容长度
    返回描述
    = 0成功
    !0失败

    关闭 mbedtls 客户端

    int mbedtls_client_close(MbedTLSSession *session);
    

    客户端主动关闭连接或者因为异常错误关闭连接,都需要使用 mbedtls_client_close 关闭连接并释放资源。

    参数描述
    session入参,mbedtls 会话对象 MbedTLSSession
    返回描述
    = 0成功
    !0失败

    mbedtls 相关 API

    设置调试级别

    void mbedtls_debug_set_threshold( int threshold );
    

    如果开启了 MBEDTLS_DEBUG_C,可以使用该函数设置调试级别,用于控制不同级别的调试日志输出。

    参数描述
    threshold入参,Debug 级别,默认为 0 没有调试日志
    返回描述

    mbedtls 定义了 5 种调试级别,如下所示:

    调试级别描述
    0No debug
    1Error
    2State change
    3Informational
    4Verbose

    初始化阶段相关 API

    • 网络上下文初始化
    void mbedtls_net_init( mbedtls_net_context *ctx );
    

    初始化 TLS 网络上下文,目前只有 fd 描述符。

    参数描述
    ctx入参,网络上下文对象
    返回描述
    • SSL 上下文初始化
    void mbedtls_ssl_init( mbedtls_ssl_context *ssl );
    
    

    SSL 上下文初始化,主要是清空 SSL 上下文对象,为 SSL 连接做准备。

    参数描述
    ssl入参,SSL 上下文对象
    返回描述
    • 初始化 SSL 配置
    void mbedtls_ssl_config_init( mbedtls_ssl_config *conf );
    
    

    SSL 配置初始化,主要是清空 SSL 配置结构体对象,为 SSL 连接做准备。

    参数描述
    conf入参,SSL 配置结构体对象
    返回描述
    • 初始化 SSL 随机字节发生器
    void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
    
    

    清空 CTR_DRBG(SSL 随机字节发生器)上下文结构体对象,为 mbedtls_ctr_drbg_seed 做准备。

    参数描述
    ctx入参,CTR_DRBG 结构体对象
    返回描述
    • 初始化 SSL 熵
    void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
    
    

    初始化 SSL 熵结构体对象。

    参数描述
    ctx入参,熵结构体对象
    返回描述
    • 设置 SSL/TLS 熵源
    int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
                       int (*f_entropy)(void *, unsigned char *, size_t),
                       void *p_entropy,
                       const unsigned char *custom,
                       size_t len );
    
    

    为 SSL/TLS 熵设置熵源,方便产生子种子。

    参数描述
    ctx入参,CTR_DRBG 结构体对象
    f_entropy入参,熵回调
    p_entropy入参,熵结构体(mbedtls_entropy_context)对象
    custom入参,个性化数据(设备特定标识符),可以为空
    len个性化数据长度
    返回描述
    • 设置根证书列表
    void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );
    
    

    初始化根证书链表。

    参数描述
    crt入参,x509 证书结构体对象
    返回描述
    • 解析根证书
    int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );
    
    

    解释性地解析。解析 buf 中一个或多个证书并将其添加到根证书链接列表中。如果可以解析某些证书,则结果是它遇到的失败证书的数量。 如果没有正确完成,则返回第一个错误。

    根证书位于 ports/src/tls_certificate.c 文件 mbedtls_root_certificate 数组中。

    参数描述
    chain入参,x509 证书结构体对象
    buf入参,存储根证书的 buffer,mbedtls_root_certificate 数组
    buflen入参,存储根证书的 buffer 大小
    返回描述
    • 设置主机名
    int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
    
    

    注意,这里设置的 hostname 必须对应服务器证书中的 common name,即 CN 字段。

    • 加载默认的 SSL 配置
    int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
                                     int endpoint, int transport, int preset );
    
    

    使用前,需要先调用 mbedtls_ssl_config_init 函数初始化 SSL 配置结构体对象。

    参数描述
    conf入参,SSL 配置结构体对象
    endpoint入参,MBEDTLS_SSL_IS_CLIENT 或者 MBEDTLS_SSL_IS_SERVER
    transport入参,TLS: MBEDTLS_SSL_TRANSPORT_STREAM; DTLS: MBEDTLS_SSL_TRANSPORT_DATAGRAM
    preset入参, 预定义的 MBEDTLS_SSL_PRESET_XXX 类型值,默认使用 MBEDTLS_SSL_PRESET_DEFAULT
    返回描述
    • 设置证书验证模式
    void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
    
    

    设置证书验证模式默认值:服务器上为 MBEDTLS_SSL_VERIFY_NONE,客户端上为 MBEDTLS_SSL_VERIFY_REQUIRED 或者 MBEDTLS_SSL_VERIFY_OPTIONAL(默认使用)。

    MBEDTLS_SSL_VERIFY_OPTIONAL 表示证书验证失败也可以继续通讯。

    参数描述
    conf入参,SSL 配置结构体对象
    authmode入参,证书验证模式
    返回描述
    • 设置验证对等证书所需的数据
    void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
                                    mbedtls_x509_crt *ca_chain,
                                    mbedtls_x509_crl *ca_crl );
    
    

    将受信的证书链配置到 SSL 配置结构体对象中。

    参数描述
    conf入参,SSL 配置结构体对象
    ca_chain入参,受信的 CA 证书链,存储在 MbedTLSSession 的成员对象 cacert 中
    ca_crl入参,受信的 CA CRLs,可为空
    返回描述
    • 设置随机数生成器回调
    void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
                               int (*f_rng)(void *, unsigned char *, size_t),
                               void *p_rng );
    
    
    参数描述
    conf入参,SSL 配置结构体对象
    f_rng入参,随机数生成器函数
    p_rng入参,随机数生成器函数参数
    返回描述
    • 设置 SSL 上下文
    int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
                           const mbedtls_ssl_config *conf );
    
    

    将 SSL 配置结构体对象设置到 SSL 上下文中。

    参数描述
    ssl入参,SSL 上下文结构体对象
    conf入参,SSL 配置结构体对象
    返回描述
    = 0成功
    - 0x7F00内存分配失败

    连接阶段相关 API

    int mbedtls_net_connect( mbedtls_net_context *ctx,
                             const char *host, const char *port,
                             int proto );
    
    

    与给定的 hostportproto 协议建立网络连接。

    参数描述
    ctx入参,NET 网络配置结构体对象
    host入参,指定的待连接主机名
    port入参,指定的主机端口号
    proto入参,指定的协议类型,MBEDTLS_NET_PROTO_TCP 或者 MBEDTLS_NET_PROTO_UDP
    返回描述
    = 0成功
    - 0x0042socket 创建失败
    - 0x0052未知的主机名,DNS 解析失败
    - 0x0044网络连接失败
    • 设置网络层读写接口
    void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
                              void *p_bio,
                              mbedtls_ssl_send_t *f_send,
                              mbedtls_ssl_recv_t *f_recv,
                              mbedtls_ssl_recv_timeout_t *f_recv_timeout );
    
    

    为网络层设置读写函数,被 mbedtls_ssl_readmbedtls_ssl_write 函数调用。

    • 对于 TLS,用户提供 f_recv 和 f_recv_timeout 其中之一即可,如果都有提供,默认使用 f_recv_timeout 回调
    • 对于 DTLS,用户需要提供 f_recv_timeout 回调函数
    参数描述
    ssl入参,SSL 上下文结构体对象
    p_bio入参,socket 描述符
    f_send入参,网络层写回调函数
    f_recv入参,网络层读回调函数
    f_recv_timeout入参,网络层非阻塞带超时读回调函数
    返回描述
    • SSL/TLS 握手接口
    int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
    
    

    执行 SSL/TLS 握手操作。

    参数描述
    ssl入参,SSL 上下文结构体对象
    返回描述
    = 0成功
    - 0x6900SSL 客户端需要读取调用
    - 0x6880SSL 客户端需要写入调用
    - 0x6A80DTLS 客户端必须重试才能进行 hello 验证
    其它其它 SSL 指定的错误码

    注意,如果您使用的是 DTLS,你需要单独处理 - 0x6A80 错误,因为它是预期的返回值而不是实际错误。

    • 获取证书验证结果
    uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl );
    
    
    参数描述
    ssl入参,SSL 上下文结构体对象
    返回描述
    = 0成功
    - 1返回结果不可用
    其它BADCERT_xxx 和 BADCRL_xxx 标志的组合,请参阅 x509.h

    或者证书验证结果的 API 接口,具体的错误信息需要使用 mbedtls_x509_crt_verify_info 接口获取。

    int mbedtls_x509_crt_verify_info( char *buf, size_t size,
                                      const char *prefix,
                                      uint32_t flags );
    
    

    使用 mbedtls_x509_crt_verify_info 函数获取有关证书验证状态的信息字符串,存储在 MbedTLSSession 的对象的 buffer 成员中。

    参数描述
    buf入参,存储验证状态信息字符串的缓冲区
    size入参,缓冲区大小
    prefix入参,行前缀
    flags入参,由 mbedtls_x509_crt_verify_info 函数返回的值
    返回描述
    整数写入的字符串的长度(不包括结束符)或负的错误代码

    读写 API

    SSL/TLS 写函数

    int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len );
    
    

    从 SLL/TLS 读取数据,最多读取 ‘len’ 字节长度数据字节。

    参数描述
    ssl入参,SSL 上下文结构体对象
    buf入参,接收读取数据的缓冲区
    len入参,要读取的数据长度
    返回描述
    > 0读取到的数据长度
    = 0读取到结束符
    - 0x6900SSL 客户端需要读取调用
    - 0x6880SSL 客户端需要写入调用
    - 0x6780SSL 客户端需要重连
    其它其它 SSL 指定的错误码

    SSL/TLS 读函数

    int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len );
    
    

    向 SSL/TLS 写入数据,最多写入 ‘len’ 字节长度数据。

    参数描述
    ssl入参,SSL 上下文结构体对象
    buf入参,待写入数据的缓冲区
    len入参,待写入数据的长度
    返回描述
    > 0实际写入的数据长度
    = 0读取到结束符
    - 0x6900SSL 客户端需要读取调用
    - 0x6880SSL 客户端需要写入调用
    其它其它 SSL 指定的错误码
    展开全文
  • 完全记录在案的配置文件include/mbedtls/config.h中提供了一些特定于平台的选项,这也是可以选择功能的地方。 该文件可以手动编辑,也可以使用Python 3脚本scripts/config.py (使用--help以获得更详尽的说明)以...
  • 一、mbedtls 开源库 1. mbedtls是什么 Mbed TLS是一个开源、可移植、易于使用、代码可读性高的SSL库。可实现加密原语,X.509证书操作以及SSL / TLS和 DTLS 协议,它的代码占用空间小,非常适合用于嵌入式系统。 mbed...

    一、mbedtls 开源库

    1. mbedtls是什么

    Mbed TLS是一个开源、可移植、易于使用、代码可读性高的SSL库。可实现常用的加密/解密算法,X.509证书操作以及TLS/DTLS 协议。它的各个功能模块相对独立、耦合低,可以通过配置宏定义裁剪,非常适合用于嵌入式系统。

    mbedtls遵循 Apache 2.0 开源许可协议,目前由 TrustedFirmware 维护(Linaro主持的一个治理开放社区项目),在Github上已收获 2.6k star,目前Github上发布的最新版本为 2.24.0 版本,开源仓库地址为:

    https://github.com/ARMmbed/mbedtls

    2. mbedtls有何用

    mbedtls库提供了 TLS / DTLS协议的实现,有了mbedtls库之后意味着:

    • TCP + TLS = TCP(S)
    • MQTT + TLS = MQTT(S)
    • HTTP + TLS = HTTP(S)
    • COAP + DTLS = COAP(S)

    目前的物联网操作系统+各种通信模组方式可以很好的实现TCP/UDP通信,进而提供一些HTTP、MQTT、COAP之类的上层协议,这些协议最大的特点是“明文传输”,一旦有中间人想要截获篡改数据,非常容易。

    要想物联网设备和服务器之间具备高安全性,mbedtls库不可或缺。

    3. 下载mbedtls库

    在github release页面下载:

    4. STM32移植方法

    移植mbedtls开源库到stm32有两种方法:

    ① 针对STM32CubeMX中Middleware下面已经提供mbedtks库的情况:直接使用cubeMX配置即可;

    ② 针对STM32CubeMX中没有提供mbedtls库的情况:手动移植。

    接下来分别演示如何移植。

    二、使用STM32CubeMX移植

    此小节中我使用的是正点原子STM32F407探索者开发板,首先准备一份可以正常使用printf打印到串口的工程。

    1. 开启RNG外设支持(可选)

    一些STM32系列中有RNG外设(随机数发生器),如果有的话就开启,没有就不用开启,接着后面的步骤就好。

    2. RTC支持和网络支持(可选)

    网络支持需要提供一套TCP/IP协议栈,比如基于AT模组的SAL层、lwip协议栈等,这里我们不使用网络连接功能,后续在带操作系统移植时讲解。

    RTC支持是为了校验CA证书有效期提供时间支持,这里我们不使用时间功能,后续在带操作系统移植时讲解。

    3. 开启mbedtls库

    在Middleware下开启mbedtls库支持:

    4. 配置mbedtls

    mebdtls库提供的算法非常多,全都通过宏定义来配置。

    ① 特性配置:保持默认即可。

    ② 使用功能模块配置(重点):

    5. 编写测试代码

    生成工程,在middleware文件夹下即可看到mbedtls库:
    打开工程,在main.c中包含头文件:

    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include <stdio.h>
    #include "mbedtls/sha1.h"		//使用sha1相关加密函数
    #include "string.h"				//使用到了strlen函数
    /* USER CODE END Includes */
    

    然后在main函数中编写如下测试代码:

    /* USER CODE BEGIN 2 */
    printf("mbedtls port on ATK-STM32F407 board by mculover666\r\n");
    
    /* sha1 test */
    char *source_cxt = "mculover666";
    char encrypt_cxt[64];
    
    printf("source context is:%s\r\n", source_cxt);
    
    mbedtls_sha1_context sha1_ctx;
    mbedtls_sha1_init(&sha1_ctx);
    mbedtls_sha1_starts(&sha1_ctx);
    mbedtls_sha1_update(&sha1_ctx, (unsigned char *)source_cxt, strlen(source_cxt));
    mbedtls_sha1_finish(&sha1_ctx, (unsigned char *)encrypt_cxt);
    mbedtls_sha1_free(&sha1_ctx);
    
    int i = 0;
    printf("sha1 encrypt context is:[");
    while (encrypt_cxt[i]) {
      printf("%02x", encrypt_cxt[i]);
      i++;
    }
    printf("]\r\n");
    
    /* USER CODE END 2 */
    

    特别注意:Keil-MDK需要改为ANSI 编码,否则因为字符串编码问题,会导致加密结果出错。


    编译,下载到开发板中,在串口助手中查看加密结果:

    6. 验证加密结果

    可以使用一些在线工具计算出结果进行对比,如图,加密无误:

    https://1024tools.com/hash

    三、手动移植mbedtls库

    这里我以STM32L431RCT6小熊派开发板为例,首先准备一份可以正常使用printf打印的裸机工程,其中没有开启硬件RNG外设。

    1. 复制mbedtls相关文件

    ① 从mbedtls库中复制mbedtls源码文件到工程中:

    ② 再复制mbedtls示例配置文件:

    2. 添加mbedtls文件到MDK中

    ① 添加 mbedtls\library 文件夹中所有的c文件:

    再将配置文件也添加到工程目录,方便修改:

    ② 添加头文件路径:

    ③ 在宏定义中指定mbedconfig配置文件:

    MBEDTLS_CONFIG_FILE=<config-mini-tls1_1.h>
    

    3. 修改mbedtls配置

    编辑 config-mini-tls1_1.h 文件。

    ① 配置mbedtls系统支持:

    ② 配置功能模块

    ③ 屏蔽功能测试,添加一个宏定义,表示没有平台支持:

    4. 编写测试代码

    打开工程,在main.c中包含头文件:

    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include <stdio.h>
    #include "mbedtls/sha1.h"
    #include "string.h"
    /* USER CODE END Includes */
    

    然后在main函数中编写如下测试代码:

    /* USER CODE BEGIN 2 */
     printf("mbedtls port on BearPi-STM32L431RC board by mculover666\r\n");
    
     /* sha1 test */
     char *source_cxt = "mculover666";
     char encrypt_cxt[64];
    
     printf("source context is:%s\r\n", source_cxt);
    
     mbedtls_sha1_context sha1_ctx;
     mbedtls_sha1_init(&sha1_ctx);
     mbedtls_sha1_starts(&sha1_ctx);
     mbedtls_sha1_update(&sha1_ctx, (unsigned char *)source_cxt, strlen(source_cxt));
     mbedtls_sha1_finish(&sha1_ctx, (unsigned char *)encrypt_cxt);
     mbedtls_sha1_free(&sha1_ctx);
    
     int i = 0;
     printf("sha1 encrypt context is:[");
     while (encrypt_cxt[i]) {
       printf("%02x", encrypt_cxt[i]);
       i++;
     }
     printf("]\r\n");
    
    /* USER CODE END 2 */
    

    特别注意:Keil-MDK需要改为ANSI 编码,否则因为字符串编码问题,会导致加密结果出错。


    编译,下载到开发板中,在串口助手中查看加密结果:

    5. 测试加密结果

    同第二节第 6 小节。

    四、移植总结

    mbedtls可以说是一个牛逼的开源库,其功能开源灵活的通过宏定义来选择,整个移植过程比较简单。

    而且mbedtls库对于我们的配置文件会做检查,在配置文件的最后一句可以看到:

    #include "mbedtls/check_config.h"
    

    如果对应某些功能我们开启了,但是没有开启它的依赖功能,编译器会直接报错,根据报错修改对应定义即可。

    总之,这么好的东西,不学一下有点可惜~

    接收精彩文章及资源推送,请订阅我的微信公众号:『mculover666』

    展开全文
  • mbedtls学习--大数运算

    2021-06-24 14:35:32
    文章目录库文件依赖宏接口示例代码算法分析数位统计读取字符串输出字符串数值比较加减计算乘法运算 ...mbedtls/library/bignum.c 依赖宏 MBEDTLS_BIGNUM_C MBEDTLS_PLATFORM_C 接口 接口 描述 mbedtls


    大数计算,顾名思义,指超出64位的数的乘法运算、指数运算和模逆运算,其中模逆运算,特指求逆元,所谓乘法逆元,例如:
    2 ∗ 9 m o d 17 = 1 2*9 mod 17 = 1 29mod17=1
    则9是2关于模17的逆元(余数为1的被除数)或者2 * 9 与 1 关于模17同余即:
    9 = 2 − 1 m o d 17 9 = 2^{-1} mod 17 9=21mod17

    库文件

    mbedtls/library/bignum.c

    依赖宏

    MBEDTLS_BIGNUM_C
    MBEDTLS_PLATFORM_C

    接口

    接口描述
    mbedtls_mpi_init初始化大数结构体
    mbedtls_mpi_read_string读取字符串到大数结构体
    mbedtls_mpi_write_string大数结构体输出到字符串
    mbedtls_mpi_mul_mpi大数乘法
    mbedtls_mpi_exp_mod大数指数
    mbedtls_mpi_inv_mod大数模逆
    mbedtls_mpi_free释放大数结构体

    示例代码

    代码结构

    .
    ├── build
    ├── CMakeLists.txt
    ├── main.c
    └── mbedtls_config.h    #对使用的库的裁剪,包含需要的库
    

    main.c

    #include <string.h>
    #include <stdio.h>
    
    #include "mbedtls/bignum.h"
    #include "mbedtls/platform.h"
    
    static void dump_buf(char *buf, size_t len) 
    {
        for (int i = 0; i < len; i++) {
            mbedtls_printf("%c%s", buf[i], 
                            (i + 1) % 32 ? "" : "\n\t"); 
        }
        mbedtls_printf("\n");
    }
    
    int main(void)
    {
        size_t olen;
        char buf[256];
        mbedtls_mpi A, E, N, X;
    
        mbedtls_mpi_init(&A); 
        mbedtls_mpi_init(&E); 
        mbedtls_mpi_init(&N); 
        mbedtls_mpi_init(&X);
    
        mbedtls_mpi_read_string(&A, 16,					//以16进制读取字符串,允许2-16进制
            "EFE021C2645FD1DC586E69184AF4A31E" \
            "D5F53E93B5F123FA41680867BA110131" \
            "944FE7952E2517337780CB0DB80E61AA" \
            "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" );
    
        mbedtls_mpi_read_string(&E, 16,
            "B2E7EFD37075B9F03FF989C7C5051C20" \
            "34D2A323810251127E7BF8625A4F49A5" \
            "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
            "5B5C25763222FEFCCFC38B832366C29E" );
    
        mbedtls_mpi_read_string(&N, 16,
            "0066A198186C18C10B2F5ED9B522752A" \
            "9830B69916E535C8F047518A889A43A5" \
            "94B6BED27A168D31D4A52F88925AA8F5" );
    
        mbedtls_mpi_mul_mpi(&X, &A, &N);
        mbedtls_mpi_write_string(&X, 16, buf, 256, &olen);
        mbedtls_printf("\n  X = A * N = \n\t");
        dump_buf(buf, olen);
    
        mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL);
        mbedtls_mpi_write_string(&X, 16, buf, 256, &olen);
        mbedtls_printf("\n  X = A^E mode N = \n\t");
        dump_buf(buf, olen);
    
        mbedtls_mpi_inv_mod( &X, &A, &N);
        mbedtls_mpi_write_string(&X, 16, buf, 256, &olen);
        mbedtls_printf("\n  X = A^-1 mod N = \n\t");
        dump_buf(buf, olen);
    
        mbedtls_mpi_free(&A); 
        mbedtls_mpi_free(&E);
        mbedtls_mpi_free(&N); 
        mbedtls_mpi_free(&X);
    
        return 0;   
    }
    

    CmakeList.txt

    cmake_minimum_required(VERSION 3.8)
    
    project("bignum")
    
    include_directories(./ $ENV{MBEDTLS_BASE}/include)
    aux_source_directory($ENV{MBEDTLS_BASE}/library MBEDTLS_SOURCES)
    
    set(SOURCES 
    	${CMAKE_CURRENT_LIST_DIR}/main.c
        ${CMAKE_CURRENT_LIST_DIR}/mbedtls_config.h 
    	${MBEDTLS_SOURCES})
    
    add_executable(bignum ${SOURCES})
    

    mbedtls_config.h

    /* System support */
    #define MBEDTLS_PLATFORM_C
    #define MBEDTLS_PLATFORM_MEMORY
    #define MBEDTLS_MEMORY_BUFFER_ALLOC_C
    #define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
    #define MBEDTLS_PLATFORM_EXIT_ALT
    #define MBEDTLS_NO_PLATFORM_ENTROPY
    #define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
    #define MBEDTLS_PLATFORM_PRINTF_ALT
    
    /* mbed TLS modules */
    #define MBEDTLS_BIGNUM_C
    
    #include "mbedtls/check_config.h"
    
    #endif /* MBEDTLS_CONFIG_H */
    
    

    运行测试

    mkdir -p build && cd build && cmake .. && make -j32
    ./bignum          
    
      X = A * N = 
            602AB7ECA597A3D6B56FF9829A5E8B85
            9E857EA95A03512E2BAE7391688D264A
            A5663B0341DB9CCFD2C4C5F421FEC814
            8001B72E848A38CAE1C65F78E56ABDEF
            E12D3C039B8A02D6BE593F0BBBDA56F1
            ECF677152EF804370C1A305CAF3B5BF1
            30879B56C61DE584A0F53A2447A51E
    
      X = A^E mode N = 
            36E139AEA55215609D2816998ED020BB
            BD96C37890F65171D948E9BC7CBAA4D9
            325D24D6A3C12710F10A09FA08AB87
    
      X = A^-1 mod N = 
            3A0AAEDD7E784FC07D8F9EC6E3BFD5C3
            DBA76456363A10869622EAC2DD84ECC5
            B8A74DAC4D09E03B5E0BE779F2DF61
    

    算法分析

    typedef struct mbedtls_mpi
    {
        int s;              			/*!<  Sign: -1 if the mpi is negative, 1 otherwise */
        size_t n;           			/*!<  total # of limbs  */
        mbedtls_mpi_uint *p;          	/*!<  pointer to limbs  */
    }
    mbedtls_mpi;
    

    X->s指大数的正负,X->指数位总数,X->p[n]指向每一位,大小为32位或64位数。例如十六进制数-1 000000000000000F的结果为,最低位为65535,最高位为1,这里每16个字符是一位。

    A->s = -1 , A->n = 2
    A->[0] = 65535
    A->[1] = 1
    

    数位统计

    size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
    

    该函数计算大数的bit位的总个数,忽略前导0,譬如十六进制-1000000000000FFFF的运算结果为65,实现过程如下:i从最高位n-1往后数,遇到X->p[i] != 0截止,例如-1000000000000FFFF的n=2, i=1开始,此时再计算当前位(最左位)的bit数,依靠

    static size_t mbedtls_clz( const mbedtls_mpi_uint x )
    

    函数来计算,这个函数将数值转为二进制并去除前导0计算剩余的有效bit位的总和,返回j=1,则大数的数位综合为( i * biL ) + j,biL在这里值为64。

    读取字符串

    int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
    

    radix指进制,支持2-16进制以内的读取。以十六进制为例:

        mbedtls_mpi_init( &T );		//初始化一个大数
        slen = strlen( s );         //获取字符串长度
        if( radix == 16 )
        {
            if( slen > MPI_SIZE_T_MAX >> 2 )					//判断是否超出范围
                return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
    
            n = BITS_TO_LIMBS( slen << 2 );
    
            MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );		//扩展n位
            MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );		//初始化每一位为0
    
            for( i = slen, j = 0; i > 0; i--, j++ )
            {
                if( i == 1 && s[i - 1] == '-' ) 				//判断字符串首位
                {
                    X->s = -1;
                    break;
                }
    
                MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
                X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
            }
        }
    

    i初始为slen,也就是字符串最右边(数值上的低位),j初始为大数的最低位,mpi_get_digit将i-1位的char类型转为digit类型,这里ciL=8,所以j / ( 2 * ciL )意味着每16个字符为一组记为大数的1位。d << ( ( j % ( 2 * ciL ) ) << 2 )则表示这组16个字符每一位的数值,拆解来开,譬如字符串00001234,

    i=7,d=4,j=0,左移0位
    i=6,d=3,j=1,左移4位,乘以16
    i=5,d=2,j=2,左移8位,乘以256
    i=4,d=1,j=3,左移12位,乘以4096
    

    以此类推求和。这里采用或运算而非加法。

    输出字符串

    int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
                                  char *buf, size_t buflen, size_t *olen )
    

    过程与读取相反,作者写的非常精简:

        if( X->s == -1 )
        {
            *p++ = '-';
            buflen--;
        }
        if( radix == 16 )
        {
            int c;
            size_t i, j, k;
    
            for( i = X->n, k = 0; i > 0; i-- )
            {
                for( j = ciL; j > 0; j-- )
                {
                    c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
    
                    if( c == 0 && k == 0 && ( i + j ) != 2 )
                        continue;
    
                    *(p++) = "0123456789ABCDEF" [c / 16];
                    *(p++) = "0123456789ABCDEF" [c % 16];
                    k = 1;
                }
            }
        }
    

    除此之外还有操作文件的接口:

    int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
    int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
    

    数值比较

    mbedtls提供了两个大数比较的接口,分别是原值和绝对值:

    int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
    int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
    

    由于大数结构体存放了数位n,因此首先比较两者n的大小,对绝对值的情况,n越大,值越大;如果n相同,则从高位向后循环。

    加减计算

    大数加减提供四个主要函数:

    /*
     * Unsigned addition: X = |A| + |B|  (HAC 14.7)
     */
    int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
    /*
     * Unsigned subtraction: X = |A| - |B|  (HAC 14.9, 14.10)
     */
    int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
    /*
     * Signed addition: X = A + B
     */
    int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
    /*
     * Signed subtraction: X = A - B
     */
    int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
    

    首先是绝对值相加,然后是绝对值减法,有符号数加减法则可以是前两者的组合,例如正数加负数其实就是减法,负数加负数(或者负数减正数)则是绝对值加法取反。例如X=A+B的计算,
    首先判断A和B的符号位乘积,如果为负数,
    则比较A和B的绝对值,

    • 绝对值A>B,则为绝对值A-B,符号位与A一致
    • 绝对值A<B,则为绝对值B-A,符号位与A相反

    如果为正数,则为绝对值A+B,符号位与A一致

    乘法运算

    乘法提供两个接口

    /*
     * Baseline multiplication: X = A * B  (HAC 14.12)
     */
    int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
    /*
     * Baseline multiplication: X = A * b
     */
    int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
    

    大数除法

    /*
     * Division by mbedtls_mpi: A = Q * B + R  (HAC 14.20)
     */
    int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
                             const mbedtls_mpi *B )
    

    这里Q=A/B,R=A mod B

    取模运算

    其实就是上面的R=0

    /*
     * Modulo: R = A mod B
     */
    int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
    

    指数运算

    因为结果可能非常大,所以对结果取模N,即
    X = A E m o d N X = A^{E} mod N X=AEmodN

    /*
     * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
     */
    int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
                             const mbedtls_mpi *E, const mbedtls_mpi *N,
                             mbedtls_mpi *_RR )
    

    求取最大公约数

    /*
     * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
     */
    int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
    

    模逆运算

    这里是求乘法逆元,即找到一个数X使得A和X的积关于模N与1同余,或者说
    A ∗ X m o d N = 1 , X = A − 1 m o d N A*X mod N = 1, X=A^{-1} mod N AXmodN=1,X=A1modN

    /*
     * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
     */
    int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
    
    展开全文
  • mbedtls学习2.mbedtls从0使用指南

    千次阅读 2020-05-26 14:07:34
    这里主要介绍 mbedtls 程序的基本使用流程,并针对使用过程中经常涉及到的结构体和重要 API 进行简要说明。 mbedtls 的基本工作流程如下所示: 初始化 SSL/TLS 上下文 建立 SSL/TLS 握手 发送、接收数据 交互完成,...
  • 常用加解密库-mbedtls

    2016-02-02 16:04:32
    mbedtls-2.0.0-gpl.tgz
  • 完全记录在案的配置文件include/mbedtls/config.h中提供了一些特定于平台的选项,这也是可以选择功能的地方。 该文件可以手动编辑,也可以使用Python 3脚本scripts/config.py (使用--help以获得更详尽的说明)以...
  • mbedtls 开源库Mbed TLS是一个开源、可移植、易于使用、代码可读性高的SSL库
  • mbedTLS简介

    2021-08-28 21:40:32
    mbedTLS简介mbedTLS的背景介绍关于mbedTLS的简要概括mbedTLS常用结构体1. 公钥算法类型mbedtls_pk_type_t2. 摘要算法类型mbedtls_md_type_t3. 公钥上下文mbedtls_pk_context4. 解析证书得到的mbedtls_pk_info_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,380
精华内容 952
关键字:

mbedtls

友情链接: ProjectSumo-master.zip