STM32移植使用mbedtls-2.24.0
(1)關於PolarSSL
mbed TLS(之前稱爲PolarSSL)是TLS和SSL協議的實現,而且須要相應的加密算法和支持代碼。這是雙重許可與Apache許可證 2.0版(與GPLv2許可也可)。網站上指出,mbed TLS的目標是「易於理解,使用,集成和擴展」。linux
核心SSL庫用C編程語言編寫,並實現SSL模塊,基本加密功能並提供各類實用功能。與OpenSSL和TLS的其餘實現不一樣,mbed TLS設計爲適合小型嵌入式設備,最小完整的TLS堆棧須要60KB的程序空間和64KB的RAM。它也是高度模塊化的:每一個組件,如加密函數,能夠獨立於框架的其他部分使用。版本也可用於Microsoft Windows和Linux。由於mbed TLS是用C編程語言編寫的,沒有外部依賴,如今叫MbedTSL,PolarSSL源碼,也許是最小巧的ssl代碼庫。高效、便於移植和集成。尤爲適合嵌入式應用。git
本章就基於STM32移植mbedtls-2.24.0版本進行測試與使用!github
mbedtls下載地址:https://github.com/ARMmbed/mbedtls算法
本章工程代碼下載地址:https://github.com/wowyyy/HAL_STM32_MBEDTLS_DEMO.git編程
(2)mbedtls移植
首先使用STM32CubeMX創建裸機工程,我使用的是STM32F103RB,配置了串口一看成信息輸出的端口,這裏注意,mbedtls所使用的棧空間是比較大的,因此在STM32CubeMX輸出工程的時候將棧空間調大,以下圖:網絡
下載解壓mbedtls源碼目錄以下:框架
而咱們須要的僅僅是configs(配置頭文件)、include(頭文件)、library(源碼)。編程語言
- configs,該文件夾內的是配置頭文件,能夠根據不一樣需求進行選擇,例如咱們本次是在嵌入式系統上使用,資源有限,因此就選擇
config-mini-tls1_1.h
這個配置文件,複製該文件內的內容替換mbedtls的默認配置頭文件mbedtls/config.h
便可。 - include,全部頭文件
- library,全部源代碼
首先在STM32 工程目錄下創建文件夾mbedtls,並將mbedtls源碼目錄下的include和library兩個文件夾複製過來,複製config-mini-tls1_1.h
文件中的內容替換include/config.h
。(注:include/config.h
文件是隻讀的,須要先修改權限爲讀寫)。模塊化
打開keil工程將源碼添加進來:
添加頭文件包含:
函數
修改include/config.h
配置文件:
- 註釋掉宏定義
MBEDTLS_HAVE_TIME
,由於咱們目前沒有用到時間相關的 - 註釋掉宏定義
MBEDTLS_NET_C
,由於沒有用到網絡 - 註釋掉宏定義
MBEDTLS_FS_IO
,這是帶系統時候須要用到的標準系統調用IO,例如linux下的系統調用函數read、write等,裸機咱們沒有用到 - 添加一個宏定義
MBEDTLS_NO_PLATFORM_ENTROPY
,單片機無系統因此須要添加該宏。
而後編譯工程便可~!
(3)移植測試
將printf函數重定向到串口一輸出:
/// 重定向printf函數到串口一 int fputc(int ch, FILE* fp) { while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET); huart1.Instance->DR = (uint8_t)(ch & 0XFF); return ch; }
下面咱們開始編寫代碼測試,測試兩個,一個是base64編碼的,另外一個是AES加解密的,
須要添加頭文件:
#include "mbedtls/config.h" #include "mbedtls/aes.h" #include "mbedtls/base64.h"
base64編解碼測試代碼:
void mbedtls_base64_demo(void) { int i = 0; // 原始數據 uint8_t plaintext[16] = { 'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'}; // base64編碼和解碼輸出數據的長度 size_t enclen = 0, declen = 0; // 存放base64編碼輸出 uint8_t encode[32]; // 存放base64解碼輸出 uint8_t decode[32]; // 編碼 mbedtls_base64_encode(encode, sizeof(encode), &enclen, plaintext, sizeof(plaintext)); // 解碼 mbedtls_base64_decode(decode, sizeof(decode), &declen, encode, enclen); printf("- enclen:%d\r\n", enclen); printf("- encode:%s\r\n", encode); printf("- declen:%d\r\n", declen); printf("- decode:"); for(i = 0; i < declen; i++) { printf("%c", (char)decode[i]); } printf("\r\n"); }
AES加解密測試代碼(ECB模式):
void mbedtls_aes_ecb_demo(void) { int i = 0; mbedtls_aes_context ctx; // 要加密的數據 uint8_t plaintext[16] = { 'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'}; // 密碼 const uint8_t passwd[32] = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDD"; // 加密輸出 uint8_t encrypt[16]; // 解密輸出 uint8_t decrypt[16]; // 初始化 mbedtls_aes_init(&ctx); // 設置加密密鑰 mbedtls_aes_setkey_enc(&ctx, passwd, 256); // 加密 mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, encrypt); // 設置解密密鑰 mbedtls_aes_setkey_dec(&ctx, passwd, 256); // 解密 mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, encrypt, decrypt); // 清理 mbedtls_aes_free(&ctx); printf("encrypt:"); for(i = 0; i < 16; i++) { printf("%02X", encrypt[i]); } printf("\r\n"); printf("decrypt:"); for(i = 0; i < 16; i++) { printf("%c", decrypt[i]); } printf("\r\n"); }
AES加解密測試代碼(CBC模式):
void mbedtls_aes_cbc_demo(void) { int i = 0; mbedtls_aes_context ctx; // 密碼 uint8_t passwd[16] = "AAAAAAAAAACCCCDD"; // 用於加密的向量表 uint8_t iv_encrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 }; // 用於解密的向量表 uint8_t iv_decrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 }; // 待加密的數據 uint8_t plaintext[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' }; // 存儲加密後的輸出 uint8_t encrypt[sizeof(plaintext)]; // 存儲解密後的輸出 uint8_t decrypt[sizeof(plaintext)]; // 加密 mbedtls_aes_setkey_enc(&ctx, passwd, 128); mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(plaintext), iv_encrypt, plaintext, encrypt); // 解密 mbedtls_aes_setkey_dec(&ctx, passwd, 128); mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(plaintext), iv_decrypt, encrypt, decrypt); // 打印出加入後的結果 for (i = 0; i < sizeof(plaintext); i++) { printf("%02X", encrypt[i]); } printf("\r\n"); // 打印處解密後的結果 for (i = 0; i < sizeof(plaintext); i++) { printf("%c", decrypt[i]); } printf("\r\n"); }
main函數以下:
程序運行效果:
網上有不少在線AES、BASE64加解密測試平臺,能夠去作驗證移植測試的準確性!
ends…