你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32移植使用mbedtls-2.24.0

[复制链接]
STMCU小助手 发布时间:2022-4-10 17:09
(1)关于PolarSSL
6 Z1 w# `: t1 Qmbed TLS(以前称为PolarSSL)是TLS和SSL协议的实现,并且需要相应的加密算法和支持代码。这是双重许可与Apache许可证 2.0版(与GPLv2许可也可)。, E9 C( ]# f8 O" \0 k: Q
核心SSL库用C编程语言编写,并实现SSL模块,基本加密功能并提供各种实用功能。与OpenSSL和TLS的其他实现不同,mbed TLS设计为适合小型嵌入式设备,最小完整的TLS堆栈需要60KB的程序空间和64KB的RAM。它也是高度模块化的:每个组件,如加密函数,可以独立于框架的其余部分使用。因为mbed TLS是用C编程语言编写的,没有外部依赖,现在叫MbedTSL,PolarSSL源码,也许是最小巧的ssl代码库。高效、便于移植和集成。尤其适合嵌入式应用。: Z7 o9 @/ Y2 O* X9 q; C% Y3 B

1 z$ c4 ^4 x: S  W% A# U2 R本章就基于STM32移植mbedtls-2.24.0版本进行测试与使用!
$ I7 S+ A( ~5 e( a/ o2 L) {$ c
8 j; |/ I4 ?: ]1 F8 `$ [" J注意:因为本章节只是用了加解密的API,没有使用网络进行SSL认证操作,如果要使用mbedtls的SSL认证,最低的硬件环境最低需要60K的FLASH以及64K的SRAM(内存),如果你使用的比较低端的STM32,那么无解,没法用embedtls。。。# b6 U; z2 N& z
& F! Z) s. T3 ~* q
(2)mbedtls移植2 x! n  g5 v) g% G
首先使用STM32CubeMX建立裸机工程,我使用的是STM32F103RB,配置了串口一当作信息输出的端口,这里注意,mbedtls所使用的栈空间是比较大的,所以在STM32CubeMX输出工程的时候将栈空间调大,如下图:0 w9 \9 K+ [. D8 x+ N6 Y" O; A
$ Z5 L7 p2 L) J
20201103091929701.png
, E8 p/ P0 z0 a' ~0 i) Q3 E- @8 H! w2 w4 T
下载解压mbedtls源码目录如下:, |. Q  `  N( i0 c; M3 N4 B

& M- x. _  z! z 20201103092210854.png 8 u/ O0 z# F0 _* Q) o) K4 E
# G6 h% L4 i7 X/ {0 |2 N% R
而我们需要的仅仅是configs(配置头文件)、include(头文件)、library(源码)。' e6 `+ ~( t5 c: l
configs,该文件夹内的是配置头文件,可以根据不同需求进行选择,例如我们本次是在嵌入式系统上使用,资源有限,所以就选择config-mini-tls1_1.h这个配置文件,复制该文件内的内容替换mbedtls的默认配置头文件mbedtls/config.h即可。include,所有头文件0 g9 E, G' k5 n8 \+ V* J) K
library,所有源代码# o0 g% E7 H; D$ [' o5 R6 W' P

0 l. r3 X# X$ s& E首先在STM32 工程目录下建立文件夹mbedtls,并将mbedtls源码目录下的include和library两个文件夹复制过来,复制config-mini-tls1_1.h文件中的内容替换include/config.h。(注:include/config.h文件是只读的,需要先修改权限为读写)。3 ]4 N( ~+ q4 l: j4 z/ j+ r6 b$ H
# ?1 F- M, }* y0 V  z
打开keil工程将源码添加进来:
; J3 \( m% g9 ~+ E/ Z
  K4 J  z4 i# A' u' t: C Y9SAJGXFMN7PO[S9H(7{($Y.png
( ^# V# A8 }( A0 A8 r! k' ?6 J: Z6 ]2 w' W9 f
添加头文件包含:
9 R: b( V1 q3 |7 ~+ f% G( y
8 w; J' G1 z0 x1 q# U 15(8I]$`W9[O]%`060[A9YN.png & @, i. z+ M$ |/ l3 o2 ~

! L+ t* L8 |7 f& X- F修改include/config.h配置文件:  m9 A4 {/ U) ], @+ E9 k6 x
注释掉宏定义MBEDTLS_HAVE_TIME,因为我们目前没有用到时间相关的
# m5 g& }6 {/ T/ q6 q6 ]注释掉宏定义MBEDTLS_NET_C,因为没有用到网络( C5 H8 c; ?: I( g7 j. w
注释掉宏定义MBEDTLS_FS_IO,这是带系统时候需要用到的标准系统调用IO,例如linux下的系统调用函数read、write等,裸机我们没有用到
& ]1 G) L( E# l& s5 i添加一个宏定义MBEDTLS_NO_PLATFORM_ENTROPY,单片机无系统所以需要添加该宏。# O3 Y" D7 p" P# L  I5 l

- K: E- R6 A& @! N; c: C然后编译工程即可~!
; ^8 T$ N6 G5 [: c& x& I* g# s+ [% Q$ Q* o- |! e4 f4 |+ M: Z* ^2 {) r
(3)移植测试
" l: a  ^$ A( V& V+ i. f
将printf函数重定向到串口一输出:
0 C7 o# U2 O1 v4 \
* Z& ^( F6 |0 `5 W4 v" X
  1. /// 重定向printf函数到串口一
    : y9 j+ N, {7 q* a' C
  2. int fputc(int ch, FILE* fp)' X' L6 J4 H( C; o
  3. {) e- g4 H3 N! m3 L2 c/ O
  4.     while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);
    % o/ t  _; t& n* u
  5.     huart1.Instance->DR = (uint8_t)(ch & 0XFF);- R: r, M, E% L+ x
  6.     return ch;
    : b; [% Y5 O6 t' L1 P# W6 h
  7. }
复制代码

0 L( {7 D' h# d4 m2 U  N2 O- E/ y3 A下面我们开始编写代码测试,测试两个,一个是base64编码的,另一个是AES加解密的,
# p1 q0 B7 o5 |& G需要添加头文件:
- U1 ]/ C& K' o+ t4 ?2 L8 x% I" p
' M' S% c/ g3 [* Z
  1. #include "mbedtls/config.h"1 r( _0 k* {- e# X* \7 @
  2. #include "mbedtls/aes.h". i* y$ e; Y- Q& `5 U
  3. #include "mbedtls/base64.h"
复制代码

: r) t& l! V. ^+ \# n; j( d& ~! M! m) ~base64编解码测试代码:
# l5 s+ I5 t1 D4 v
& m% b2 G) G( X, u0 n- d3 ~
  1. void mbedtls_base64_demo(void)7 ?+ v: g6 e0 ]; t7 P7 }: m
  2. {; Z1 _1 i0 i9 Y. x
  3.         int i = 0;
    % g' l$ t1 n/ G3 D( g) D* @5 E
  4.         * Q9 W3 T) P% k: B9 M
  5.         // 原始数据
    8 a- s$ v0 l5 h7 n4 @
  6.         uint8_t plaintext[16] = {'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'};9 q; Y7 `  U: @0 ?4 [4 ~8 a

  7. 3 B6 G6 D. l( d, D
  8.     // base64编码和解码输出数据的长度, u' P0 J, t$ l+ F. y) L
  9.     size_t enclen = 0, declen = 0;% l2 ~! K9 _/ N* z8 ^

  10. 6 Q! y$ ?" ~  E1 |0 n' ~: h. [
  11.     // 存放base64编码输出4 O( h. l# v1 l: m8 x
  12.     uint8_t encode[32];% D: e$ p1 B3 R0 }# t

  13. & Y' G! ^+ v6 d1 d
  14.     // 存放base64解码输出
    6 |3 u4 a- Y# L$ C# O: E! w
  15.     uint8_t decode[32];
    1 c- g* Y+ {. r, k$ e

  16. . A0 d- o0 W- @# b0 D/ u
  17.         // 编码
    5 v% z9 c! x& ^' s$ f3 N& L
  18.     mbedtls_base64_encode(encode, sizeof(encode), &enclen, plaintext, sizeof(plaintext));1 H: z0 M# q2 h) @; z

  19. 1 x+ @+ E. y% W, M1 C( G9 A$ n( i; C
  20.         // 解码
    & u  W+ y( w7 N4 j* c! y
  21.     mbedtls_base64_decode(decode, sizeof(decode), &declen, encode, enclen);
    % p0 ]3 |- q: p  Z+ E; d! w# q

  22. ) B$ H+ B+ j: @9 C8 X  _; _
  23.     printf("- enclen:%d\r\n", enclen);
    ! W( U5 b& ~# I  K( W$ G4 x
  24.     printf("- encode:%s\r\n", encode);  h) J0 f, u3 R( _# d; l
  25.     printf("- declen:%d\r\n", declen);
    ) R5 }) k0 h8 W
  26.     printf("- decode:");
    6 i7 V) V: f' a5 ]
  27.         for(i = 0; i < declen; i++)
    : G4 ?, u- w5 f
  28.         {
    5 n2 J. D+ b% u1 ^$ a. C# n9 g6 s
  29.                 printf("%c", (char)decode<i>);
    + y; U  K& B; H2 C# _
  30.         }
    8 r7 x; }  T' C" I& R2 Y7 ]
  31.         printf("\r\n");: m# u( |1 _# D1 n4 D
  32. }</i>
复制代码
+ d. W* w# [4 ~
AES加解密测试代码(ECB模式):; X3 A6 F* _7 l/ @8 a! L( ^& ~8 s% h

' L+ U3 C; R+ m2 z9 b5 `
  1. void mbedtls_aes_ecb_demo(void)
    - @  b5 f- h% q! W) q" Y! l
  2. {
    * T+ w' O# B, p
  3.         int i = 0;5 d$ K7 [( i2 w# `, d
  4.         mbedtls_aes_context ctx;
    8 K/ z1 X: k( W
  5.         ; Q: m  E) |9 q; n& D& Q
  6.         // 要加密的数据- R% @* \  {; Y. a2 j
  7.         uint8_t plaintext[16] = {'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'};  h% j' g* Y: _) u
  8. / a. h" i; \' ~* X: i
  9.         // 密码
    2 H  E& ^+ ^8 g0 q" d8 N- V
  10.         const uint8_t passwd[32] = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDD";7 i9 W& e4 @' C; s
  11.         ' ^3 E- f+ N7 h2 i* Z% d0 G& S
  12.         // 加密输出4 v( e. u4 N0 S9 y
  13.         uint8_t encrypt[16];
    3 P" z7 J0 G! X) [0 j; B5 w& d
  14.         
    $ g' J: h2 b; t: _1 l# r, ^6 h
  15.         // 解密输出7 p& ^3 o* n3 ]8 i, M! A7 L
  16.         uint8_t decrypt[16];
    & l+ \% |4 N3 Q* t  j

  17. 9 O' f1 a+ O( N6 L! Q. N
  18.         // 初始化
    : F  t0 H. {2 A0 q+ e
  19.         mbedtls_aes_init(&ctx);* G: \' R9 L) [5 c
  20. 2 n7 u3 D9 _0 y  N  z8 @* q% b9 s5 c
  21.         // 设置加密密钥
    1 i# i( S" [9 y
  22.         mbedtls_aes_setkey_enc(&ctx, passwd, 256);
    0 S9 C; d: i0 u4 h
  23.         1 ?1 P+ S2 K0 M/ H! _: R" {1 }
  24.         // 加密
    ' U* l4 |; e# u- \0 v% d
  25.         mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, encrypt);  R* t* M+ N  q) N+ n" ~
  26.         
    7 J( X+ X) S/ R' ]' q
  27.         // 设置解密密钥
    5 v) ~% L& k) g* W3 [4 F
  28.         mbedtls_aes_setkey_dec(&ctx, passwd, 256);
    8 w  V" k( T# |; X. q
  29.         & P! @4 H- ~8 l- g; L& _
  30.         // 解密( w, b7 s, I5 `5 P4 K. o9 c! Q
  31.         mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, encrypt, decrypt);
    ; f- u9 }4 d7 `  R  z& y# j
  32. 2 `2 [3 a  G; D  C; n
  33.         // 清理
    1 W8 n7 @( U" y7 i6 `3 f& J
  34.         mbedtls_aes_free(&ctx);* U# [# o( m) u- M6 T5 v
  35.         ' K& O; D, i+ I
  36.         printf("encrypt:");
    $ @8 m) |- t8 v- k
  37.         for(i = 0; i < 16; i++)3 N" p) t6 F( h5 k
  38.         {
    1 b& @: b( U  ]- D# f* ~8 k. p
  39. <i>                printf("%02X", encrypt);6 ]6 I' E! P6 T. z; E! n
  40.         }
      l/ D2 J" ^. b" q9 [/ ^" ?7 ?
  41.         printf("\r\n");+ y( W5 G, _1 N' l8 [
  42. ' b/ z: M( R! ]: k- U# @) X
  43.         printf("decrypt:");" W+ Q, M* i5 F5 {& c) F8 j; y
  44.         for(i = 0; i < 16; i++)- H* ^" a7 M6 I/ U4 b
  45.         {6 y$ w7 z  P* w! N3 x/ L5 F
  46.                 printf("%c", decrypt);+ A8 T9 p! f$ I& h- r  P: z
  47.         }' G# F) e7 q" Y+ ~2 K
  48.         printf("\r\n");
    % |( Y9 C: a4 S- @( O
  49. }</i>
复制代码

1 j2 h1 _, V. EAES加解密测试代码(CBC模式):
! T# q$ V/ s; U, L6 B' i4 c$ e* R  O
- m6 @% a+ s0 e$ f8 G7 R
  1. void mbedtls_aes_cbc_demo(void)  R# h. `8 M/ }/ a
  2. {
    - [" K$ J2 n! T7 O( J8 `& }
  3.         int i = 0;
    ! {9 ]$ f" k6 B' @1 }
  4. 2 B# q1 `7 Q: y( l
  5.         mbedtls_aes_context ctx;
    8 I- F+ X4 U+ A" S7 z4 I
  6. # u/ o/ d+ R! h" X
  7.         // 密码/ g5 [1 c# Y+ W2 u
  8.         uint8_t passwd[16] = "AAAAAAAAAACCCCDD";
    ( g( L( U3 `  R" B4 e; x
  9. / [  p7 t* D0 ^/ ?% U; i
  10.         // 用于加密的向量表( e4 w8 {4 {2 J" u/ d/ p" u
  11.         uint8_t iv_encrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 };
    * l% G# i  Z3 Z, V
  12. + F- W0 O3 e! e7 W, u- q0 P
  13.         // 用于解密的向量表/ j  ^6 p' |6 U2 {5 e
  14.         uint8_t iv_decrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 };
    8 c0 m3 Z2 {9 n4 N3 Q
  15. . H; C2 r: _2 `3 M9 N
  16.         // 待加密的数据
    ! |7 Y, v/ \; ~/ ]3 E  m5 f& m5 c
  17.         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' };  G9 q7 w& v9 ^
  18. ' s' p% e2 \- m, ^# f1 X" |
  19.         // 存储加密后的输出' v6 ^+ N2 Q; e9 q. W' m" c5 f! i% i
  20.         uint8_t encrypt[sizeof(plaintext)];
    9 Y& Q. W1 {: s) s5 x8 }& T
  21. : J' k0 I) C) S! q
  22.         // 存储解密后的输出, Y$ d5 S" }- l
  23.         uint8_t decrypt[sizeof(plaintext)];
    2 q' x, X, i7 ^/ V. k

  24. % D: R  `$ c- g8 M8 M6 X  P& P* {
  25.         // 加密3 y, x, X# x& \( ^4 Z
  26.         mbedtls_aes_setkey_enc(&ctx, passwd, 128);& ~2 a8 \0 y7 \9 d* l" h( X
  27.         mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(plaintext), iv_encrypt, plaintext, encrypt);/ i: ^. }4 _8 h7 S

  28. 4 C& r: o  q% V. Z* x  q
  29.         // 解密6 w1 h9 q' o1 X- F+ |; V+ c
  30.         mbedtls_aes_setkey_dec(&ctx, passwd, 128);
    ; w0 A$ L4 X2 p( n
  31.         mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(plaintext), iv_decrypt, encrypt, decrypt);
    . H$ j. S, D5 k' H+ I" V
  32. : _! I3 b* F/ G5 h
  33.         // 打印出加入后的结果7 g/ [3 ~' U1 D7 j- N4 G7 g1 V# r7 V
  34.         for (i = 0; i < sizeof(plaintext); i++)* b7 H- s9 l' k
  35.         {2 o/ s: a% X- Q# Q
  36.                 printf("%02X", encrypt);
    7 x* |7 P0 L1 O5 `) D: c
  37.         }; I6 Q! @+ `$ `+ r
  38.         printf("\r\n");( e% y2 q% n* J) y- g5 B
  39. % N5 ]9 {+ o! Y6 C  z9 E- z
  40.         // 打印处解密后的结果
    ! B0 m0 F0 l4 r, E) t. x
  41.         for (i = 0; i < sizeof(plaintext); i++)
    ! b. h5 o! Y3 e" K4 N# F* J7 r8 h
  42.         {% b( d' h1 x  ^$ j# ~4 ?
  43.                 printf("%c", decrypt);
    ( F# m+ ^& S, U* T5 z
  44.         }
    ' ?- `# F0 \2 ]6 S
  45.         printf("\r\n");
    , C' s7 ^# u) c0 [: T; i& Q
  46. }
    * g% R, A% |; a" }( H1 M! a
  47. : W. F9 I  Q1 K+ `+ g. q
复制代码

2 p  P% D0 `6 o: e2 |. p1 m* U' ]# Ymain函数如下:0 z' T- }* j; S8 Z5 ~: b0 ^0 j% H

6 a1 @6 y1 E- G# t* E JWNISW4TJY98}2C6W(D(ZNA.png
, [0 L) v" _2 r, i
& c0 c+ M$ y  ]0 `5 ^0 q程序运行效果:
+ ^$ w  B& H  ~4 o, j6 ^6 A) }7 r, k0 V/ }. |
W(YRU[09DXX5A2S{B{MB7OS.png
3 t/ G& u- e" P/ `0 q6 V) s. T3 x$ a
网上有很多在线AES、BASE64加解密测试平台,可以去做验证移植测试的准确性!* ~( k$ ]$ W( o) W+ @: S$ p

6 h$ G7 J  }* |. ]" V! [% D! |) j( v5 N+ f3 P# r, N( k
; w) m: u7 A* L' f6 ^6 V
收藏 评论0 发布时间:2022-4-10 17:09

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版