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

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

[复制链接]
STMCU小助手 发布时间:2022-4-10 17:09
(1)关于PolarSSL
4 {% C0 V5 {1 \9 q+ I6 R' o' xmbed TLS(以前称为PolarSSL)是TLS和SSL协议的实现,并且需要相应的加密算法和支持代码。这是双重许可与Apache许可证 2.0版(与GPLv2许可也可)。1 L" B$ F$ @* Y% G" ?: T
核心SSL库用C编程语言编写,并实现SSL模块,基本加密功能并提供各种实用功能。与OpenSSL和TLS的其他实现不同,mbed TLS设计为适合小型嵌入式设备,最小完整的TLS堆栈需要60KB的程序空间和64KB的RAM。它也是高度模块化的:每个组件,如加密函数,可以独立于框架的其余部分使用。因为mbed TLS是用C编程语言编写的,没有外部依赖,现在叫MbedTSL,PolarSSL源码,也许是最小巧的ssl代码库。高效、便于移植和集成。尤其适合嵌入式应用。
7 C3 J" W* F" H% g! X  A$ Y1 D, L, c( {1 B" W; Z1 w# b- n/ t/ U, f
本章就基于STM32移植mbedtls-2.24.0版本进行测试与使用!
% p- G* K# M/ g5 x
" h, W( K. t+ |& z0 x- ]+ b注意:因为本章节只是用了加解密的API,没有使用网络进行SSL认证操作,如果要使用mbedtls的SSL认证,最低的硬件环境最低需要60K的FLASH以及64K的SRAM(内存),如果你使用的比较低端的STM32,那么无解,没法用embedtls。。。1 R, ]; Y: I) c9 `' g7 i
0 e8 z  _; _5 r( C
(2)mbedtls移植
! }9 a( H8 g, \首先使用STM32CubeMX建立裸机工程,我使用的是STM32F103RB,配置了串口一当作信息输出的端口,这里注意,mbedtls所使用的栈空间是比较大的,所以在STM32CubeMX输出工程的时候将栈空间调大,如下图:
, U! Y( R% N7 A) X- z- w! q
3 |. j9 }; d4 j/ j( r 20201103091929701.png % x! A' t" z9 N
$ M' V( [8 C" N" Z
下载解压mbedtls源码目录如下:% n8 x3 w5 M+ m  C, x
% l: b5 `* v& s  d4 T! I
20201103092210854.png
6 B& C8 x; y1 p- Z8 W- l
" D2 q9 O0 P/ \( a而我们需要的仅仅是configs(配置头文件)、include(头文件)、library(源码)。
2 n1 C: t" b3 i# O$ |configs,该文件夹内的是配置头文件,可以根据不同需求进行选择,例如我们本次是在嵌入式系统上使用,资源有限,所以就选择config-mini-tls1_1.h这个配置文件,复制该文件内的内容替换mbedtls的默认配置头文件mbedtls/config.h即可。include,所有头文件
% q. H1 X; C  r5 |. u1 P7 Glibrary,所有源代码) D2 `! B% R3 U

3 i1 k7 o) q; a1 Y" v- a, M, t首先在STM32 工程目录下建立文件夹mbedtls,并将mbedtls源码目录下的include和library两个文件夹复制过来,复制config-mini-tls1_1.h文件中的内容替换include/config.h。(注:include/config.h文件是只读的,需要先修改权限为读写)。% Y2 A4 @( N/ j% W4 Y

( K5 X" o" \( t# T" b打开keil工程将源码添加进来:8 ^5 f8 ?1 g# N0 E5 w: c( U0 }
7 o* X" w8 Y4 v* |9 T/ L4 V
Y9SAJGXFMN7PO[S9H(7{($Y.png
! Z0 c/ r( R* }6 N
2 t% D8 s- C0 b5 X+ W5 {7 z  x  G' u+ ?添加头文件包含:
5 E0 I! Q! N' L$ k3 S' v
% j% V2 ?! m! A 15(8I]$`W9[O]%`060[A9YN.png
& s& u# W& ]: {% r: [
0 H4 G5 w" o& |0 J, F" T修改include/config.h配置文件:7 {* f/ L8 U" p
注释掉宏定义MBEDTLS_HAVE_TIME,因为我们目前没有用到时间相关的
1 U% _9 |7 r$ `2 z注释掉宏定义MBEDTLS_NET_C,因为没有用到网络
0 R- \- h$ M# t8 w注释掉宏定义MBEDTLS_FS_IO,这是带系统时候需要用到的标准系统调用IO,例如linux下的系统调用函数read、write等,裸机我们没有用到
+ ]* n, v+ I$ {, d2 Y添加一个宏定义MBEDTLS_NO_PLATFORM_ENTROPY,单片机无系统所以需要添加该宏。1 Q9 P  z0 c; }  W- m8 x
: i" J+ M; o  `; Y" K; R% d; {
然后编译工程即可~!
, X- x  U, o, u/ c8 L! |3 c. P% ]' T& M& B/ Q
(3)移植测试

+ A* v/ S/ O6 b/ D  W将printf函数重定向到串口一输出:
. F2 D, U* G" v" p7 b7 Q6 `4 J6 U+ r. w, K, g% p" |% }
  1. /// 重定向printf函数到串口一: Y: c2 Q6 c, C3 q3 h# L! q1 d
  2. int fputc(int ch, FILE* fp)
    : \( x2 w7 ~, M% _4 c3 x
  3. {& n( A& V" R- ]! U* K
  4.     while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);, f$ b% H9 ^9 E8 q0 M$ a5 P7 r
  5.     huart1.Instance->DR = (uint8_t)(ch & 0XFF);9 e+ x0 z6 V  X: w8 q
  6.     return ch;
    : Z0 K$ Z2 Z% ~) P9 h
  7. }
复制代码

3 f. Z0 {8 Y/ F下面我们开始编写代码测试,测试两个,一个是base64编码的,另一个是AES加解密的,
! T; \. A$ \2 |4 V& J# I# `% G需要添加头文件:
0 v  S# w1 P" N5 }7 {
0 x+ {7 x  z+ @; H. A- K& f
  1. #include "mbedtls/config.h"
    & q9 |* O2 ~* I2 M
  2. #include "mbedtls/aes.h"
    & E, w9 b. M  F9 ]* Q3 _4 q
  3. #include "mbedtls/base64.h"
复制代码

2 `+ A  w5 h% N2 v& abase64编解码测试代码:
* s* O4 s+ p% G- d& E4 H1 V
- J3 v1 c3 ~% L% s" [
  1. void mbedtls_base64_demo(void)
    ( r* S3 ]! @  ^- M5 @
  2. {
    0 n8 C2 z+ x2 ^6 ?
  3.         int i = 0;! P/ k, T2 p, `, @
  4.         % a" x( B/ {5 J# h2 |% f
  5.         // 原始数据& I; y3 Z6 b# v& F
  6.         uint8_t plaintext[16] = {'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'};0 Z  m' @: V% S7 V6 }
  7. 9 ~: z1 s- E' K& x+ y0 h( @
  8.     // base64编码和解码输出数据的长度, p& o! {4 \  g: L2 o6 `, A0 b
  9.     size_t enclen = 0, declen = 0;
    4 C  p5 O9 @) P$ U* T
  10. 1 z! I4 z+ m6 C6 I& m
  11.     // 存放base64编码输出9 c' Z$ u2 f6 Z
  12.     uint8_t encode[32];
    3 ~# r4 z% m+ Q: b- I% \. q, u  G$ i

  13. - Y6 r4 V& z: ?- g3 l
  14.     // 存放base64解码输出4 t( I+ W" {6 X1 I5 ]! F
  15.     uint8_t decode[32];7 P+ ^( w/ ?7 ?0 E, D
  16. * p" s7 C! C' j% R, V$ p
  17.         // 编码
    8 r; B7 g4 N8 U$ m7 K/ m9 }
  18.     mbedtls_base64_encode(encode, sizeof(encode), &enclen, plaintext, sizeof(plaintext));, x$ B/ U  y% z  c& \% y! ]
  19. % M. B+ Y% v8 T! l6 T
  20.         // 解码7 I7 B9 g6 L# a
  21.     mbedtls_base64_decode(decode, sizeof(decode), &declen, encode, enclen);
    & ~9 R/ S, R# b9 \5 l% ]7 f

  22. 3 L) C- E& {& G5 H
  23.     printf("- enclen:%d\r\n", enclen);  f  C8 ^7 n" s
  24.     printf("- encode:%s\r\n", encode);! @5 v: e) _: D* s( O0 c& \
  25.     printf("- declen:%d\r\n", declen);
    & J7 ]% E* [1 {( [
  26.     printf("- decode:");' d& A, o1 J2 ^: N4 }6 H) Q- N
  27.         for(i = 0; i < declen; i++)) Q  H, ?% S9 H4 E! h
  28.         {# J- [) n* e- Q) a+ I
  29.                 printf("%c", (char)decode<i>);
    9 d) @. m  x: D/ M4 H
  30.         }
    ! t, Q, f1 I% D( c7 m$ p4 K( e8 I
  31.         printf("\r\n");
    * s: s& D, E" g0 |7 T* h4 {% q
  32. }</i>
复制代码
8 A; ^$ B- z8 s
AES加解密测试代码(ECB模式):
0 B" J* Z9 ~: E
" h8 b; D2 S+ T( P% [# u
  1. void mbedtls_aes_ecb_demo(void)
    ( D+ \$ C" }! E" }' C, w
  2. {
    / P  X* |3 X$ H" x
  3.         int i = 0;3 q4 B  ]" r0 @# ^
  4.         mbedtls_aes_context ctx;
    " t8 T$ E8 Z" f  }8 X
  5.         
    , b) G5 M0 ?& e1 `5 m9 ^) y( l- U
  6.         // 要加密的数据' t+ G/ E; r. ^: R/ v
  7.         uint8_t plaintext[16] = {'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'};: y6 M+ F# q+ }( Y* v4 l/ K8 W
  8. ) w* g; T! Z. ?& L! ?( C; {7 S# o
  9.         // 密码1 `/ ?9 q1 l5 H' V
  10.         const uint8_t passwd[32] = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDD";- K6 e5 q0 J- U; k
  11.         
    0 ?% p6 U6 q  m$ ]" P( k
  12.         // 加密输出- e) L: |; z& J. Q" q# R
  13.         uint8_t encrypt[16];' P  C8 b9 q6 l) o2 F) S
  14.         
      k( W" E4 L. @
  15.         // 解密输出
    $ x* ^+ m! \! K% w% L2 K+ J
  16.         uint8_t decrypt[16];! l+ f  D6 T- N: w) i0 _$ M
  17. 7 S$ v: S  q: c$ O, D7 }$ L
  18.         // 初始化/ ?. X. C: m+ }1 u3 x# ?/ q1 Z
  19.         mbedtls_aes_init(&ctx);/ L  t2 K' a  ?6 E
  20. + j) U8 e) g1 m
  21.         // 设置加密密钥
    & |/ r+ m8 `+ F$ s+ V
  22.         mbedtls_aes_setkey_enc(&ctx, passwd, 256);1 k( h/ ~% M' r1 X. j; T
  23.         ! S2 L: L7 L7 B9 x% o
  24.         // 加密0 X: B% K5 `2 ]8 E
  25.         mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, encrypt);3 ~% `* ]( l  }! a* H/ ?
  26.         
    # j! h( A: I* V* y2 H" g' {+ C3 H
  27.         // 设置解密密钥
    0 [7 w3 g$ [& K* U  m$ ~( M9 K1 O' Q# k9 N
  28.         mbedtls_aes_setkey_dec(&ctx, passwd, 256);1 n/ R' G4 e+ N; ?' ]
  29.         
    . \% w2 N+ o& n2 M" o' t+ q
  30.         // 解密
    0 G4 r- b0 e: P# P1 Y0 N. x! u* n$ [( G6 U
  31.         mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, encrypt, decrypt);7 F9 A& @5 |5 ?& ]7 E7 v) O2 S
  32. 3 z( O: P2 t5 x6 ?. y3 i: X; U
  33.         // 清理
    1 P- u$ B% n/ Q* y* v- ^& g, h: e
  34.         mbedtls_aes_free(&ctx);
    . B- K. n6 w' G4 u  ^
  35.         
      Z7 g5 }" ^8 m/ ?
  36.         printf("encrypt:");( p4 z! [  E& ~; Y; v. n. |* e1 {
  37.         for(i = 0; i < 16; i++)( J/ y. N  ~% O. @+ @4 X; W
  38.         {+ M/ S# |  Y- b, g, \
  39. <i>                printf("%02X", encrypt);! V1 F2 F7 U2 Z1 i- M3 |- S
  40.         }& Q8 {( g$ q, w5 X- E: O
  41.         printf("\r\n");
    & {2 S% @/ Z2 h: N" i8 o

  42. 6 L: y( _' J" G1 ~! }. C* K3 u
  43.         printf("decrypt:");/ D  _$ A/ E8 p
  44.         for(i = 0; i < 16; i++)
    * Y* N7 O' B  f0 F+ I) I
  45.         {
    : U* h7 `- \7 F3 N) \
  46.                 printf("%c", decrypt);
    " q9 G  D$ J( _
  47.         }
    8 i" u; C0 ~* z' P" k
  48.         printf("\r\n");
    0 `9 ]2 Y! z* ~* B0 f
  49. }</i>
复制代码
' X$ W4 A" X# x4 b5 x0 ?6 _
AES加解密测试代码(CBC模式):
7 u5 L# k6 O: S# X8 x( {6 z+ V* K" Q7 X9 F- x
  1. void mbedtls_aes_cbc_demo(void)
    * D5 T4 A, x' D7 l7 F8 G
  2. {* U3 e; l# |  s. G; N
  3.         int i = 0;
    8 W0 g/ b1 y+ S4 O

  4. 3 [7 M- R: g3 T' e1 s
  5.         mbedtls_aes_context ctx;1 o' j- @5 d% y& I$ x3 O! e

  6. $ a8 ~$ [% M3 o9 b& ~; G# w
  7.         // 密码5 M" w! i0 y' i. W" u: P0 d
  8.         uint8_t passwd[16] = "AAAAAAAAAACCCCDD";
    + e6 A( P0 L* _4 b
  9. # U) J- H" L- ~7 u; c+ v9 x$ z( {* m
  10.         // 用于加密的向量表
    ( T! z$ I4 P1 N1 z0 u
  11.         uint8_t iv_encrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 };
    " E' o' v4 {- e. Y3 ~
  12. - c  p8 i( R! ]0 R' `1 B0 M
  13.         // 用于解密的向量表
    - h) c: z1 E+ _$ G( [$ V
  14.         uint8_t iv_decrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 };
    1 R& H) {2 u. Y; m# s) m

  15.   f  U' i+ ?& J) r+ {! }1 p+ l9 L
  16.         // 待加密的数据, i" @6 n7 ]. w
  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' };+ j8 u  S  {8 |2 k; i
  18. ! ?' \; P- l2 _
  19.         // 存储加密后的输出
    , l+ A/ C: e4 N0 x! B8 ?$ c
  20.         uint8_t encrypt[sizeof(plaintext)];. V" s1 S6 {( v, [

  21. ( S% \& e6 @( n4 \7 C
  22.         // 存储解密后的输出; D2 t9 Q. P6 U
  23.         uint8_t decrypt[sizeof(plaintext)];
    / R. z4 `, J: m# |+ c1 ?, \. }) ?
  24. # I3 m% v9 a- l& P& O
  25.         // 加密
    - Y; G, i8 P4 z& z  p
  26.         mbedtls_aes_setkey_enc(&ctx, passwd, 128);
    # g3 B; ?8 S- z" d2 X$ S
  27.         mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(plaintext), iv_encrypt, plaintext, encrypt);9 C- K$ j/ q# t, |. O8 C

  28. 6 C+ F+ w8 H% u
  29.         // 解密9 i6 d) P8 M6 V/ ]  {& l$ ?4 R
  30.         mbedtls_aes_setkey_dec(&ctx, passwd, 128);
    % Z5 l5 ~0 b8 F' @
  31.         mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(plaintext), iv_decrypt, encrypt, decrypt);7 i! l5 I* Q: p+ U  g5 V
  32. 2 B9 W5 ?8 R5 r# K
  33.         // 打印出加入后的结果+ |7 [+ R: s" q5 |  f
  34.         for (i = 0; i < sizeof(plaintext); i++)
    + y+ q- c' n$ k7 o0 N& S
  35.         {7 m) z* T+ |) B4 T
  36.                 printf("%02X", encrypt);
    ; R2 \. i+ `# i* n' s+ O
  37.         }5 c/ G/ ]( l/ n( v7 l
  38.         printf("\r\n");  u( i$ i  m' e+ C) P9 ?: M- z
  39. 3 _7 z( D& w# `, w7 k8 ]
  40.         // 打印处解密后的结果
    7 p, {( @  K9 ?) k1 @
  41.         for (i = 0; i < sizeof(plaintext); i++)
    0 F$ M. Q2 ]7 m" W
  42.         {' m; p5 Y6 `/ q
  43.                 printf("%c", decrypt);
    5 }  b) x* b' R1 V, D! M7 Y$ W! v
  44.         }2 K4 ~4 z" y: r! a! O# p
  45.         printf("\r\n");' Q$ w! g" _, `# n) k  R
  46. }
    + h5 R! u6 i' g" x5 t# s1 o% B

  47. 9 y  A* Y' @- [
复制代码
+ @. h% P3 f) x# \
main函数如下:
: W: ?+ J. l' f. g3 S$ Q0 \) z  y; b2 n7 o7 U$ k* f
JWNISW4TJY98}2C6W(D(ZNA.png ( K- r0 D6 [& ]
6 x, b* \  A5 \5 B) K# V2 U; k% @
程序运行效果:  y3 H3 n1 k8 H' k3 y

7 l& ]! g  ]7 z W(YRU[09DXX5A2S{B{MB7OS.png 4 Q( C& C) V- X/ _; Y, K
- e1 G3 ~3 y' {7 j
网上有很多在线AES、BASE64加解密测试平台,可以去做验证移植测试的准确性!: R  p* p5 o# ^. k: X

! b6 a* e- V' `, H8 x9 v! ?6 I, Z# p7 r& k

' l9 E& h9 r* Z5 ^- s
收藏 评论0 发布时间:2022-4-10 17:09

举报

0个回答

所属标签

相似分享

官网相关资源

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