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

信息安全专题 | 安全存储(2)STM32WB的用户密钥存储 (CKS)

[复制链接]
STMCU-管管 发布时间:2021-6-15 15:50
我们都知道STM32WB是双核多协议无线微控制器,即主频为64 MHz的 Arm®Cortex®‐M4内核(应用处理器)和主频为32 MHz的Arm®Cortex®‐M0+内核(网络处理器),支持Bluetooth™ 5和IEEE 802.15.4无线标准。双核的好处是可以优化对资源的安全使用,保证和RF协议栈相关处理的实时性,并可同时提供电源管理的灵活性。
; C: {& d. H$ {3 `1 M4 U2 m" Q' M! Z! e, ]7 Q1 P: j6 n
STM32WB的信息安全是以双核隔离为基础的。2 U8 X% P/ v# W* m3 l
, h% W0 {1 F2 D6 m
STM32WB双核架构和双核间的隔离机制
" o: I- y0 b% r" }- B% P
11.png
- Y9 M9 N0 r0 d7 J+ U
- F' s  D7 ~0 T! I

! F  ?" Q9 a  i! x5 J
  n5 V; d- \+ K! b0 d调试端口访问:1 l0 ^4 e  C1 T

+ g; w9 h& T% c6 N1 |! [
/ e2 e. O8 J7 q+ _2 n$ w& I
出厂的芯片缺省关闭CM0+一侧的调试端口访问,即使在RDP0的状态下也只能调试CM4内核。. X+ t9 J3 m0 K! F7 z

" I' Y$ l- ]3 Z- d) `* TOption Byte:  b4 r! M. f! F+ k* |3 m6 ]

' M6 F# ^0 R/ ?  K

5 M/ G7 g5 X6 t# N/ n( wOptionByte中包含双核隔离相关的安全设置,例如CM0+才能访问的Flash区间等等。这些OptionByte受到保护,无法随意被修改。缺省出厂芯片已经使能CM0+的保护,相关的一些OptionByte设置无法通过调试端口或CM4进行修改。
2 J; p' \  e/ X( a, j
8 m  d  z5 m% V: Q$ G4 A* y: Y0 F片上Flash:; c" n, m) I! y. @+ V$ R
3 D0 a, O& @; W

7 t5 g8 r3 [+ {+ R$ S6 g# {, cFlash的一部分只能由CM0+访问,CM4无法对该部分Flash进行读、写、擦。
9 C( X* V+ X( D8 f; x& V
9 \8 a5 g+ v9 u3 F1 e$ ?# S  B片上SRAM:5 F. ~9 |2 i( |$ w7 ^
1 y- M5 h. ?+ N- a/ n( v

9 ?: o4 m& ~3 }. sSRAM的一部分只能由CM0+访问,CM4无法对该部分SRAM进行读、写。+ r1 V5 }: X4 v3 w4 o& y1 L- Y

( i8 r8 v. T9 M: T. aCRYPTO硬件资源:如AES,TRNG,PKA
" _9 a6 g; a# }$ X' W
- \% v2 h4 ], H5 \) M8 V0 C
/ E( E1 Z; v$ {! y+ ~
系统上电复位时,缺省CRYPTO相关的硬件CM4可以使用。CM0+内核可以通过修改SystemConfig相应的寄存器使得这些硬件资源只能由CM0+内核进行控制,也称为把这些硬件资源配置成Secure访问模式。其中当AES1被配置为Secure时,CM4内核无法访问密钥寄存器,但是依旧可以访问AES1的其他寄存器使用AES1硬件单元进行加解密操作。' A' g( |* r! k
( E. {, t$ u4 K3 @) c
CKS (Customer Key Storage)

$ C: ~) Y( O; T1 F7 v* M' A
2 u4 R# [  C1 |* d' X( \& bAES算法是应用程序中经常用到的一种保障数据机密性和完整性的方法,例如用于隐私数据的加密存储、加密通信等。其中,密钥作为最敏感的信息也需要受到保护。# z& Q  D! G6 Y* W* F
" m( w  v/ ~2 n( b9 H4 m) O
4 S4 y7 W/ R; `3 G9 D7 |7 X
STM32WB的CKS功能提供在MCU上的密钥安全存储和安全使用方法 :- Y3 M6 p2 R, j& w  w, F

2 c9 v/ c# o* N" g) L- F' O! u
$ s0 K7 [- v* O3 C0 O
存储在片上安全Flash的密钥无法通过调试端口获取(即使在RDP0条件下)
( f8 z. @: d) Q% w/ p2 h+ d8 E. l% K+ c5 U9 I6 t( f
- Z( e. [" ]* x& f, A
运行在CM4内核的应用程序代码也无法获得片上安全Flash中存储的密钥,避免软件漏洞带来的风险
' A& t' ?/ w3 C2 S6 L$ b$ v4 B$ ~1 A7 e' h* w( F# N

! x5 x8 @7 {9 ]. C* J5 l/ m3 K应用程序代码依旧能够通过CKS和AES1硬件模块使用存储的密钥进行加解密操作 ( ~% I5 X" N) x! w/ F  x7 W3 W

" ^5 E' D% _/ f, C: O

' V3 K1 M- M4 v- @  Q/ gCKS能够存储多组密钥,应用程序代码可以通过密钥索引来指定AES运算所使用的密钥
+ a" U+ O* g! F! W; W. k( U3 ~
12.png

) j1 g6 g& |' ?  |
用户密钥存储
8 O7 t: y( U; V; y* `/ d

9 a5 ~% h  _2 {5 R! v2 c

6 E8 y6 N/ ^8 [2 ~) X4 f用户密钥存储在"安全"Flash区域,用户代码和调试端口不可访问 ' D8 L; Y5 t$ F# Y! `
- j$ c. \1 }  h! o

# l1 ?$ d; t: w' LCKS最多可以存储100个用户应用密钥(用于AES运算)
% L' O/ Z) b) b- |! @) e! Z& f# O/ d0 R. I' S
/ ^" w5 r1 ?8 v9 H- Y
允许存储128位或者256位的AES密钥 8 I' d5 \/ j3 i7 U4 Y; ~
* J5 n* E/ Y' p7 ^9 z  d/ v; w
对密钥的操作只能通过用户代码调用FUS接口完成
- L7 k+ c, O# k; t9 ^
) _! S: m" O1 ~

4 O; c" M  V4 h7 ]把密钥写到“安全”Flash区域,需要安全的操作环境 8 e1 r6 B+ Q4 x0 n8 V! T2 W( L
13.png

% n( ^: k, C' l; p5 s$ A+ X% e1 L/ A1 \. V% }
用户密钥的写入 (Key Provisioning)

4 r5 j6 f4 {) J" X; T% O$ a( u
1 l& Q  S$ e, W* y, C

0 b/ ]2 \. W+ t% b可以通过用户代码完成,也可以通过CubeProgrammer的GUI或者命令行完成 9 i7 \1 r0 M2 H1 G7 }! j
写入应用密钥的明文//simple key,需要安全的操作环境 $ V8 }7 N2 ]: \7 r1 G
' [) w' R$ P* _% ?+ ^% D
9 e% x  {$ Y2 N4 y% d1 c, H5 ^  e
写入应用密钥的密文//encrypted key,无需安全的操作环境 * F  [' }% |2 q. g$ x3 [! u& J" Q

/ _7 T  p1 x5 X5 @# ]2 Y
% n; D* G. Y- W4 `
基于AES-128 GCM * X3 d. E  v( m1 w. V
$ U, t, w! S8 p$ L, ?3 Z0 _
" }9 [* r, k1 U) O/ H3 X
写入用于解密encrypted key的密钥的明文//master key,需要安全的操作环境 9 X; ?2 c+ r5 S! W) T6 x

7 A# x! e& `8 Y) G2 w. V该操作在手册中用“write”或“load”表示1 K/ W# J$ K3 q: g+ c" j
14.png
. ^0 S: I; _( ~% }
, ]$ r/ R3 f$ k/ d8 N# e6 p/ z* r
) X, y- Z$ B9 c: p% Z
用户密钥的写入通过应用代码实现
9 }3 {2 y% m. {8 y2 u; X$ k
4 T2 b' z. Z. T% y" J

5 ^6 z5 D0 g- ~3 W参考例程:
' h- R" k, W# MSTM32Cube_FW_WB_Vxxx\Projects\P-NUCLEO-WB55.Nucleo\Applications\CKS\
6 P4 R& S. g1 Y" o
2 @! L. a( x: Y
1 d) f& y& W0 w- c6 T
给CKS_param赋值0 `% c9 X) y% v1 J
  1. typedef PACKED_STRUCT{
    : k0 V8 p. S7 f: Q4 d
  2. uint8_t KeyType;
    . y, b4 v, p, f1 G( ~2 f# Q+ F! O
  3. uint8_t KeySize;
    8 F. H7 K2 n; f- g* f
  4. uint8_t KeyData[32 + 12];
    9 n4 ?0 Y; N7 P2 l) a2 K
  5. } SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t;
    5 L* U, X. M8 e! I
  6. SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t CKS_param;# F' q, l# l* J7 }
  7. CKS_param.KeyType = …;
    4 s0 x  J% x; E& p: Q6 _
  8. CKS_param.KeySize = …;
    / S) \: o7 f4 F' f: g" H# d$ y
  9. memcpy(CKS_param.KeyData, pKeySimple_128, 16)
复制代码

# ]% ~+ D' e2 ^$ [# v调用FUS服务:SHCI_C2_FUS_StoreUsrKey
+ E. K% R& ~/ D" q3 O输入:CKS_param结构体 % b6 l/ w! ~+ l. u4 ]: a

; W, @2 s! l( K! y' N

! L) j9 g& D5 {. ^/ B输出:芯片为该密钥分配的索引! W( d' ^) E' m6 X. Z
# U$ @- \* {, q/ K

  1. ( x7 g; a) u5 I$ f9 B+ u0 u
  2. SHCI_C2_FUS_StoreUsrKey (&CKS_param, &key_simple_128_idx );
复制代码
15.png
1 C2 e1 |; A2 F- O
" S% N6 ^, @9 Q- X: I6 U6 o" x3 j  h

  X  c0 V, M  x
用户密钥的写入使用STM32CubeProgrammer GUI实现

/ P  b. l5 @/ `, f+ z% L; f* c; e& E" k: S7 n$ g* U0 h/ H

( e/ L1 a0 l# g" ]7 N2 w

6 P% d4 h2 ^! b4 ZSTM32CubeProgrammer 从2.4版本开始支持 " A* t; g4 `+ `& f' C
芯片切换到系统 Bootloader 启动运行DFU,
% k( U3 _5 x; z. a: E1 s1 M
* g1 @" p8 u2 j& Q- K
" m2 B1 U' v& W+ c5 Y7 R5 u* l, O
STM32CubeProgrammer 以USB方式连接芯片
" s  g# V! G/ |* p3 n! Y6 j
16.png

7 k$ e5 \: q% s0 B* Z! u步骤:选择KEY文件 ——> 指定KEY类型 ——> 写入KEY9 ?( d3 S4 `/ ?! G4 T
17.png

$ U  Q" t0 L6 F* e/ V5 O/ l* f
! I5 D1 z1 C: e0 P; A/ Z
+ _3 r7 c" z5 a4 G
注意:GUI界面没有返回为该密钥分配的索引,需要用户自己记录3 R3 E0 ?$ J# N! h4 q2 Q3 n: _
7 c' z' ^1 C% ^3 k9 Y- W% m

, N$ z- W) {) ~1 m# Q* y8 B! l
应用密钥的装载和使用
7 b0 Y/ {$ h$ g" N" Y6 v" {
Load:AES1的密钥装载
& f6 f, k4 q1 X$ c. ?; v  KSHCI_C2_FUS_LoadUsrKey (key_simple_128_idx) * p0 N3 h6 f3 t, {5 i
该操作会把AES1密钥寄存器配置成Secure
6 ^1 F7 D: i0 x, t3 @  `5 }% v8 ~SAES1@SYSCFG_SIPCR + L0 G( Q0 S% G( n4 C
只能由运行在CM0+上的FUS来配置
# n$ Y, }7 s4 L2 v0 v运行在CM4上的用户代码可以读取其状态 % i) l! }8 @9 G2 h9 E  N! |2 }
安全状态和AES1时钟是否使能没有关系- ]6 d% `2 N1 I) C& q# X  L
18.png

- b" a( j% S3 M, a6 i; |8 ^8 [" L# a0 M. j/ c- u! N* @

& K& Z' O+ I- t使用步骤
. b& R2 e, R: T
6 _$ r2 ?+ @; ?% Y
7 @7 W' f$ Y" Y3 ^6 P
Step1:AES1模块初始化 8 {- M) O/ G! {

: }1 g; Q+ Q( F7 d; x
1 z& g& D* S! q$ c7 G( c9 P: t
初始化结构体的pKey,设置为空指针即可 1 S7 t, u$ n3 ^1 Y+ s
6 p8 q  \+ W, \/ X& a5 ^5 c' s
! m6 v; ~; [- P0 e- p
使能AES1时钟 6 _& L2 b% F. }* s5 X, u

9 _# S* P9 d& ?( L- W4 T$ Q; H

; w2 z( t2 r6 v, DStep2:密钥装载
2 P' c* O6 }' E& g% Q1 r2 J  ^/ G% U4 j
& K8 _3 e4 K4 `7 y+ U( ~
要在AES1模块disable1的时候 (EN=0) ; V# u8 O" d7 Q4 [2 Q

+ w' c* Q1 X+ ?3 A7 v7 W/ i; \" A
% _8 |3 L  W7 t
Step3:使用AES1做加解密7 }" x9 _2 |4 k, b+ x

: l8 L2 S- M+ ?" f
  1. hcryp1.Init.DataType = CRYP_DATATYPE_8B;8 \! W, U  \5 x( T1 d
  2. hcryp1.Init.KeySize = CRYP_KEYSIZE_128B;& ]6 K; D% Z5 D
  3. hcryp1.Init.Algorithm = CRYP_AES_CBC;% m: |" q" m' w6 p( T1 h
  4. /* Key will be provided by CKS service */7 p( X3 k" f! g* o3 o: O
  5. hcryp1.Init.pKey = NULL;
    + i0 N' I  C; D0 M) i. r9 a/ a
  6. hcryp1.Init.pInitVect = AESIV;
    : N" M, M% s) n- q4 \; F
  7. HAL_CRYP_Init (&hcryp1);
    ( E+ B' S+ u. H
  8. SHCI_C2_FUS_LoadUsrKey (key_simple_128_idx);% e9 N; L3 l" \$ ~" n
  9. HAL_CRYP_Encrypt(&hcryp1, Plaintext, size, EncryptedBuf, timeout)
复制代码
应用密钥的使用

) R! g% [& C' w, u
# d4 I% f8 G# V+ `1 o) W+ J" q- vLock:9 u5 d. i, n) F9 Q2 S5 m

" G" n5 H' S9 q7 R

- s' k& |9 |4 {. O; W& P$ n·SHCI_C2_FUS_LockUsrKey (key_simple_128_idx) 0 N" A7 `, h0 n& k. h/ ^; o
·对某个key lock之后,将无法再对该key进行 Load操作,再次Load该Key时FUS API返回 错误代码0xFF;但是不影响已经在AES1密 钥寄存器中的key3 G. s# e9 H! v) e* Y  R8 r
·对该key load的禁止操作,会一直生效直到 下次系统复位
. o! l1 ^' i, _9 j% c; g; j% M
* u5 s: n7 Z  @9 u& o, C. O注意事项:关于后续更新
" |  N. h) ~& A! B3 [1 G1 G3 _3 I2 g. Q
2 m0 i- G& N; ^1 t# R( D
·为了避免有效密钥一直存在于AES1密钥寄存 器中,建议使用完毕后Load一个dummy key 或者disable AES1 ! l# e( ^- H( B2 y# e( X& }
·后续FUS版本(从 STM32CUbeWB1.11开始)会增加API:Unload# K3 i$ q" k* \3 M/ e. G! I
·早期出厂芯片预装的FUS版本较老,在FUS 升级的时候,通过CSK存储在芯片里的用户 key会被擦除 " a" U  `5 u) E+ A
·从FUS1.1.1.1或者FUS1.2.0开始,再做FUS升 级,不会影响到已经存在的用户key 应用密钥的使用
; w2 V7 M, G( s6 w
$ y3 V& g5 v5 Q/ H( }( M, x+ |

' ?& Z+ R, \* z0 p. w6 J
小结

! p8 Y3 t1 T6 v. M7 v6 _/ x+ k( ?
19.png
. c6 D3 H/ o3 p% K! X

  L* _. l/ ]5 K9 Q: j
" x$ C9 I! K( g, U3 t5 |# n! ^
使用CKS对AES密钥进行保护,与传统的直接将AES密钥存储在Flash中的做法有明显的优势:7 u* u9 S* Z5 c

  X. G. |" S- `; X/ |% l

7 Y5 T& o- e" J* ]CKS存储的密钥数据无法通过调试端口获取,已经存储的密钥数据,即使在RDP为0的情况下也不能通过调试端口访问。$ s* y1 \) r, S: B0 ^

: \4 C5 c2 C+ W: a& w6 C

7 Y/ y7 O- S7 b' k密钥使用过程中应用程序代码虽然可以使用密钥进行加解密操作,但是始终无法直接获取密钥数据本身,降低了软件漏洞可能带来的风险。* V; I. {. x; W4 N2 G8 i+ q6 ^( K
6 P% A" Z" ]# j; s7 o' _3 }
0 z. f6 E2 q$ S

" p3 O3 ]4 t# o: V
# R" n& f8 G) v; o( o6 g2 s
& Q* D5 n$ ~9 I6 m: n
  t( f- X; s! ]8 A- A9 A3 L. G+ {2 a

* E$ x+ s# k$ w; i) K/ j6 o2 B
赞 收藏 评论1 发布时间:2021-6-15 15:50

举报

1个回答
ghost110 回答时间:2021-7-5 15:16:12
详实、详尽、详细。学无止境!& ^/ O6 A8 g. s) y  E& X5 g

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版