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

工程师笔记 | Crypto算法库使用技巧 —— 基于STM32 AES GCM应用提示

[复制链接]
STMCU小助手 发布时间:2021-9-7 16:48
. O" j9 `4 [6 l. L% t& Y
引言
' l0 G2 \- C9 D0 z
3 |  \- ?. W! |8 C
& U: ^% o1 @- y4 U; y( p( u4 Y! k5 X" ^
X-CUBE-CRYPTOLIB 是基于 STM32 的 Crypto 算法库,支持对称密钥、非对称密钥、哈希等多种算法。正确地使用 Cyrptolib 算法库,可以在应用程序中实现数据加密、设备身份认证、加密通信等多种应用层所需的安全功能。相反,若不能正确地使用算法库往往会带来加解密数据错误等系列问题。+ e, b# E* \2 H8 c' r  ~# ^
8 i+ }+ C9 Y( X+ z2 u/ o
! O0 M* U3 P" h
关于 STM32 Crypto 算法库应用中的常见的问题之一就是应用程序没有使能 MCU 的CRC 模块,尽管输出的数据和期望值不同,但加解密函数的调用并未返回异常。本文在此描述另外一种没有正确使用算法库的情况。; C" o% a2 A# p& I7 t

- i( m& j* G6 B( f: N# K& R7 _
问题描述

! G! n9 t# S. Z0 [% j
% S7 w& Y* `; c5 U6 ^  V& O( U8 M) V6 c  i8 q' _) a# `6 x* ]
客户应用项目中需要在固件更新过程中对固件进行加密并验证,根据推荐采用了 AES- GCM 算法完成该任务。下载的固件通过 AES-GCM 进行加密,并带 TAG 可以用于验证固件来源的合法性。在项目的代码中使用 X-Cube-Cryptolib 进行 AES-GCM 运算。上位机使用 cryptopp820 加密库对固件目标 bin 文件进行加密,然后在 MCU 上通过X-Cube- Cryptolib 加密库进行 AES-GCM128 解密,解密数据没有问题,但是 TAG 数据总是无法校验通过。2 b5 M: s4 [# U& z3 E! X

) G7 i. K4 `- v: I
问题分析与定位
2 Q/ h9 ]- K$ z/ C  K5 ~% O

# l1 _! `3 A$ M' V, `* z* ]' \! M& @* o5 b  d$ i! z
正常情况下,当调用 AES_GCM_Decrypt_Finish(P_pAESGCMctx, NULL, P_pOutputSize);执行后,AESctx.mFlags 结果会提示是否通过校验。如果校验成功,该值应该等于 0x22,而运行结果中看到的却是 0x12。* ^; y( ?. Q( `8 k& a8 y1 H7 C1 u
. p" f. N& k; I' ~$ n' S
确认库函数使用方法
) e1 l5 c' I7 P将调用 AES-GCM 功能的代码放在 X-Cube-Cryptolib 中一个简单的测试程序的环境进行测试,查看是否有该问题,结果发现测试程序中 AES-GCM 校验是可以成功的,但是集成到客户应用中时就无法成功。那我们接下来重点研究应用程序环境。8 C# Y. e, N9 E/ |5 @% v  I, V- s6 Q
- b/ C6 J9 e1 @% N/ w3 M
应用程序环境. T9 y: c; y/ L: R9 X  r( i
应用程序使用了 FreeRTOS,基于 IAR 编译环境。0 U& S, Z" F% v/ C/ r! g% [) s

  ]0 }, e" [2 Q) L2 l" s5 `4 {. U查看库文件的使用
( y' l  i  [0 Z确认使用了正确的库文件。5 O1 F1 x5 i6 ^8 b- r, y3 U: [. v8 D

3 z. p+ r/ l* o; R2 \' P  B. l+ e确认是否存在多线程访问2 D5 F( N" @# D0 w* d- V. s: b& D4 ~
AES-GCM 的函数会在几个线程中调用,而且确认不会出现同时调用的情况,不存在 raise condition 的问题。3 _& p2 s! j' t5 f
# d/ Q! U; O* R
查看内存使用情况
$ ~; V, U/ x; [8 u4 e$ p最初怀疑是否因为任务栈溢出造成,于是查看内存使用情况。7 q2 V7 A( e, k4 j8 R' T7 u
IAR stack size: 0x4800
: z* o1 d* u) m* d- J3 iIAR heap size: 0x4000
5 s0 j+ F: C# C6 W( mFreeRTOS heap size: 85KB# v7 n' A7 ^( A. Y
执行AES 运算的线程 stack size: 2560B& y1 ~4 X: [$ j9 V9 S( K

) L8 U8 ^2 i$ ~6 ^& K' X通过 FreeRTOS 的 uxTaskGetStackHighWaterMark() 函数查看该线程还有 500 字节左右剩余空间。" q+ m) Z0 @  ?0 _
5 T6 K: V7 X5 L, k9 D
AESGCMctx_stt 结构的大小有 2360 字节,AES-GCM 加解密函数需要的 stack 大小大概在 450 字节左右,但是应用代码中将该变量定义为全局变量,以便可以在几个不同的线程中使用,这样可以确认线程栈大小没有问题,不存在 stack overflow 的问题。
8 X- @0 \1 o4 [9 ^
% a1 k% Q2 r: ^- R查看生成代码的.map 文件. L7 q0 J  v7 K7 W& J! S6 S
通过比较,所有 cryptolib 中的 symbol 在 map 中的大小都正常,唯一有问题的是 AESGCMctx_stt 结构变量的大小。
* [% P' r0 C6 W5 V# Q: a- [应用代码.map:AESctx 0x2002f1f4 0x8f8 Data Gb AES_GCM_Decrypt.o [1]9 d3 w( E7 A* I: b1 c. X1 ^7 J( g, V
正常测试代码 .map:AESctx 0x20002e64 0x938 Data Gb AES_GCM.o [1]
1 S% j) \* E# w: c: s' c5 ~0 s+ F
- K9 j, [& G3 }6 ^" K/ ?验证不过的问题应该和这个结构的数据有直接关系,接下来研究是什么造成了这个不同。
# P' |# N  B7 m/ p
* e: D+ d  R4 n$ h5 T% Y查看项目使用的 crypto 库头文件, c. u6 W* q/ I6 o
经检查,INCLUDE_AES192 和 INCLUDE_AES256 两个宏定义在 config.h 的定义中被注释掉,这将导致 aes_gcm.h 中 AESGCMctx_stt 数据结构的成员变量 uint32_t amExpKey[CRL_AES_MAX_EXPKEY_SIZE];的大小发生变化,因为CRL_AES_MAX_EXPKEY_SIZE 的定义根据INCLUDE_AES128/192/256 是否定义会有所不同。% \- J0 h$ D# h( H8 [" ]( R7 v" M1 ^) y3 {

, q# b9 [9 ~, ]1 U0 s

' \) U- P" E' e8 U//#define INCLUDE_DES ((uint16_t)0x0001) /*!< DES functions are included in the library. */
+ b+ |) M2 U# Q, X0 u2 v//#define INCLUDE_TDES ((uint16_t)0x0002) /*!< TripleDES (TDES) functions are included in the library. */
/ A% z+ @- x3 k$ O9 ~: ^#define INCLUDE_AES128 ((uint16_t)0x0004) /*!< AES functions with key size of 128 bit are included in the library. */
& z' e" p; g9 I4 U, k//#define INCLUDE_AES192 ((uint16_t)0x0008) /*!< AES functions with key size of 192 bit are included in the library. */
, r2 J2 t+ ~: c9 L" w, I6 y( h7 U' ?//#define INCLUDE_AES256 ((uint16_t)0x0010) /*!< AES functions with key size of 256 bit are included in the library. *// A0 w3 v4 Z5 v! s2 k
//#define INCLUDE_ARC4 ((uint16_t)0x0020) /*!< ARC4 functions are included in the library. */# i, w) c7 ]" ?; X1 y( {
//#define INCLUDE_CHACHA ((uint16_t)0x0040) /*!< ChaCha functions are included in the library. */  D" [2 u# M: U) W
//#define INCLUDE_CHACHA20POLY1305 ((uint16_t)0x0080) /*!< oly1305- AES functions are included in the library */
0 x4 y% U4 ~+ A' H; x& }
. I9 w" d% G3 K
问题解决
, h/ M2 f" U1 a) }, P" e

4 d0 e7 o! E/ D2 a  T5 r将 config.h 里面被注释掉的两行定义打开,重新编译,此时 TAG 验证能够正常通过。
1 |, t- w! q+ O& [1 l. S6 d#define INCLUDE_AES128 ((uint16_t)0x0004) /*!< AES functions with key size of 128 bit are included in the library. */
# y* s0 b: A) P& P#define INCLUDE_AES192 ((uint16_t)0x0008) /*!< AES functions with key size of 192 bit are included in the library. */" s( D( K. y7 Y6 G- q  c' M5 m
#define INCLUDE_AES256 ((uint16_t)0x0010) /*!< AES functions with key size of 256 bit are included in the library. */# [' P8 s4 ^: g( W

3 o% R' Z$ B/ P+ \5 k
小结

8 V' _# a# P2 c简言之,如果使用 X-Cube-Cryptolib 库的话,作为用户就不要改动 config.h 的内容, 不可想当然地自行调整配置。其实,库是预先编译好了的,所有的功能都已经包含,只是链接的时候根据用户使用到的函数去链接最终的目标文件。这个客户就是按照以为关闭某些配置可以节省代码空间的想法,贸然注释掉了他以为自己不需要的功能,造成数据结构大小发生变化等,影响加密库的正常使用。2 m+ N& `& c$ W. p( Z$ i
: Z+ g, D- Y) f6 k  G! O  F; r$ j
收藏 1 评论0 发布时间:2021-9-7 16:48

举报

0个回答

所属标签

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