一、mbedtls 開源庫
1. mbedtls是什么
Mbed TLS是一個開源、可移植、易于使用、代碼可讀性高的SSL庫,可實作加密原語,X.509證書操作以及SSL / 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』,

CSDN認證博客專家
嵌入式軟體開發
IoT全堆疊開發
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/102473.html
標籤:其他
