STM32U585主打了数据安全,当然也提供了多种方式。我们这里用B-U585I-IOT02A开发板测试 PKA加密~也就是大家经常在计算机领域听到的公钥加密法~# u7 J; z& [. w) S( ?( c0 y7 C8 g
我们先来看看一些导图:
, \/ Z$ ]6 h/ [/ D% j3 ~; @应用场景:
! J i( \3 J! u6 @
1 W8 E$ ^! S; o% V3 r' X! W* K
4 x# M3 r) u- z& f7 g0 q& x7 O
完全硬件自发,无需CPU干预:4 P; L9 o8 [2 O/ I& W* K
6 O: V, d/ a, A) s使用流程:6 Y5 L! e' s1 J# `8 k
" i" l" o0 a" s4 j2 Y1 }1 f8 N/ Y) I$ j
" M3 H" \$ \8 [( L7 U8 I好,由于全在MCU内部,这了也没有什么原理图,我们直接开始CUBEMC的配置:) m. C% h! s9 ^4 |& r
5 o! X" ?9 T5 d
6 }% D6 O) G0 e$ }/ a: ^
$ C i3 N5 q8 h2 U3 p7 l4 q" d
P" A- Q7 z: y# x- c; n$ D: [# |
) R" c4 g5 p: P1 X6 C4 ^' }
0 v- ]2 q5 J# B2 H" x: V- [
# G& o3 Z1 U! S7 @: D
$ o9 a h, J+ h: ^6 x$ X
自动生成代码,我们添加我们的私钥及公钥对,对其进行测试:
6 }5 C1 ]. S6 I' x8 f- PKA_HandleTypeDef hpka;
z; o( x5 e9 ?6 d# Z% w - & H" W8 q6 ?& f
- RNG_HandleTypeDef hrng;! _5 A* @% _& K9 V2 ]5 e# ^% ~
; L$ b8 A u2 ~ X7 w5 t- /* USER CODE BEGIN PV */) i W% g4 U6 X, ~# j4 J# Q
- PKA_ModExpProtectModeInTypeDef in = {0};) ~) L0 {; N: O' n* S
- S5 S, C( F6 P3 Z- /* Input vectors */
6 U/ r/ t& B6 o3 `; U' D - uint32_t input1_OpSize = 32;
" J9 k0 u5 G9 E, f0 o' e - uint32_t input1_ExpSize = 32;( R4 X% G& o' |8 k2 u6 k7 {; m
- uint8_t input1_1[32] = {0xE4, 0x88, 0xD8, 0x11, 0x76, 0xE5, 0x06, 0xFA, 0xB7, 0xC2, 0xFC, 0x5D, 0xF3, 0xCB, 0x75, 0x55, 0x34, 0x3F, 0x45, 0xB4, 0x78, 0x52, 0xBA, 0x7E, 0xFB, 0xF5, 0xB1, 0x2A, 0xF4, 0x0B, 0xF4, 0xB3};
- @5 G; N- I8 c. K5 C - uint8_t input1_2[32] = {0x12, 0x28, 0x49, 0x3A, 0x81, 0xFE, 0xCA, 0x62, 0x2B, 0x2D, 0x83, 0xCD, 0x97, 0x2C, 0x28, 0x23, 0x39, 0x76, 0xF1, 0xF3, 0x71, 0xCE, 0x16, 0x84, 0xA0, 0x37, 0x98, 0xE0, 0xC7, 0x0B, 0xF4, 0x39};: C2 {. n* q' G, ?. B9 K
- uint8_t input1_3[32] = {0x45, 0xAB, 0x14, 0x95, 0x48, 0x22, 0x69, 0xC4, 0x8F, 0x1E, 0xCA, 0x23, 0x0C, 0x1F, 0x5A, 0xB4, 0xBC, 0xE7, 0x12, 0xD8, 0x50, 0x09, 0x54, 0xBB, 0xE2, 0x1D, 0x2A, 0x39, 0x86, 0x3E, 0xDB, 0xFB};
/ T1 A7 G9 T4 v+ a4 t - uint8_t input1_4[32] = {0xE4, 0x88, 0xD8, 0x11, 0x76, 0xE5, 0x06, 0xFA, 0xB7, 0xC2, 0xFC, 0x5D, 0xF3, 0xCB, 0x75, 0x53, 0x50, 0x7D, 0xA2, 0xCD, 0x98, 0x24, 0x33, 0x76, 0x14, 0x8F, 0xCF, 0xA3, 0xF5, 0xCF, 0x4A, 0x88};5 I. n* _% h* r- F0 f
- uint8_t output1[32] = {0xD1, 0x2F, 0x36, 0x6C, 0x61, 0xB5, 0x66, 0x48, 0x61, 0x17, 0x8A, 0x1E, 0x6B, 0xD0, 0xE7, 0xBF, 0x66, 0x0A, 0x2B, 0x07, 0x9D, 0x4D, 0x82, 0x68, 0x7E, 0xB1, 0x9D, 0x29, 0x94, 0x43, 0x6D, 0x39};4 \, o" N9 o* C/ O4 {
: I' _" s9 A; U& A$ b* k+ X+ v9 |- uint8_t buffer[32];
8 l) r( x1 X8 C5 e! P9 q( M
) j, F8 t3 R4 V- __IO uint32_t hal_EndOfProcess = 0;: o5 h8 @! Z, n
- __IO uint32_t hal_ErrorCallback = 0;
复制代码 计算结果与预制值得比较函数:! I$ n4 _% O9 ~
- static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
复制代码 在main函数里面添加:! l# M6 d" o) b6 v
- /* Initialize all configured peripherals */
/ x5 d% W( {4 h3 f - MX_ICACHE_Init();- ~1 T+ P& j+ R# W y
- MX_RNG_Init();* ?7 L3 q6 {; I, v, R' Y
- MX_PKA_Init();
2 I( h8 g& H* p, ` - /* USER CODE BEGIN 2 */
+ {8 o& D0 a6 `7 d4 S7 ?6 V - ' E3 ^2 B; u# O$ V9 C+ K* F
- /* Set input parameters */1 X! U1 c+ g0 c
- in.OpSize = input1_OpSize;( e1 C6 l7 t8 h- u a( U; W3 h
- in.expSize = input1_ExpSize;+ N3 i4 V+ N& {2 ]/ s
- in.pMod = input1_1;
/ J) A7 E+ V) c- f. b6 @ - in.pExp = input1_2;9 S _+ D6 n9 N. a ]6 U* E; _
- in.pOp1 = input1_3;
) p! n& W3 W7 W( a2 s, ~* k - in.pPhi = input1_4;
0 e2 Y! v# o7 E, B - 0 q4 ^" L' J5 e$ o8 S
- /* Start PKA protected Modular exponentiation operation */) e5 X. ?: z9 U$ f9 ^0 i0 z
- if (HAL_PKA_ModExpProtectMode_IT(&hpka, &in) != HAL_OK)3 H% |( L e2 Q
- {8 l% r" G. {) E% l2 y/ o
- /* HAL PKA Operation error */! K& S8 r' l, f2 A
- Error_Handler();
& q9 U0 V9 q: R7 D8 i7 ?/ V2 j - }$ g9 ?# G, {9 F2 Z
- 1 _8 p; S8 n& b" y' K7 r. ^
- /* Wait until operation finish */
2 A% K" ^$ B$ q/ V - while (!hal_EndOfProcess);
& G; P# A7 n6 M& i1 |# s$ s - hal_EndOfProcess = 0;
6 q! }5 E5 H K
. B, o" W( N v+ a- /* Retrieve computation result */
O3 `: B! Z' ?; x - HAL_PKA_ModExp_GetResult(&hpka, buffer);
' S2 \! i$ w' c: i9 _
; H2 v% T2 O( X3 P2 C- /* Check retrieved result with expected result */) s8 O, X3 U0 t! t5 f
- if ((Buffercmp((uint8_t*)buffer, (uint8_t*)output1, 32) != 0) || (hal_ErrorCallback == 1))" j' q& \8 K8 V. _6 E3 @+ ]1 o( P
- {
8 d: t! f5 `6 n9 |' l1 z - /* HAL PKA Operation error */
6 ~3 J3 D/ Z* r/ L0 F - Error_Handler();
4 p4 n. [/ b0 `+ i - }
复制代码 一些回调函数:
( L, N2 U; F3 H T2 c& t! Z- P" l- /**
0 b# d+ d+ U4 v - * @brief Process completed callback.
! h( V6 ]0 Q3 U* }" T3 P( s4 r - * @param hpka PKA handle
1 B2 M5 s4 \9 s; h7 V - * @retval None" ]4 ~ @# M1 F3 H( U
- */
5 f5 U+ H8 {7 H0 J- V' h - void HAL_PKA_OperationCpltCallback(PKA_HandleTypeDef *hpka) Z$ r! r7 \" w: d
- {4 I# o, N9 v$ l& q7 T6 F
- hal_EndOfProcess = 1;
" g5 h2 C& O# \# A - }
( N8 n5 c' R5 g- C" ?( [$ d - 0 R; m* W) x. S
- /**
0 r& j. W+ k7 H - * @brief Error callback.4 r e, g4 M& y/ k" }
- * @param hpka PKA handle
4 f& X6 w- q3 z/ g" j - * @retval None
# A! h& {0 B( T4 l6 h4 t - */. |8 S. @8 N$ x) @$ H
- void HAL_PKA_ErrorCallback(PKA_HandleTypeDef *hpka)
+ J: s1 d; b2 j/ c& v5 h% r% E% q2 p - {9 d0 j4 a& k, e& ]6 g3 f, s3 X5 J
- hal_ErrorCallback = 1;
0 }" O* Y0 X# D" w$ K" y - }3 Q: T% @9 A9 `7 a' `* o- G: S
8 a7 @: n/ B, o- /**
* I1 `% P n# o - * @brief Compares two buffers., t* Z7 w) I4 B/ ^+ g
- * @param pBuffer1, pBuffer2: buffers to be compared.3 L9 h4 E3 B2 P* \8 z8 l' ?
- * @param BufferLength: buffer's length
# ~, n. {5 t! Z" B! T - * @retval 0 : pBuffer1 identical to pBuffer2+ |) S7 y9 I2 F
- * >0 : pBuffer1 differs from pBuffer2
* M/ [; u+ {; J& L( f - */4 l5 v$ z s! o, L Q/ e, v
- static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)0 t& J& }2 o8 w* k2 n. l, w
- {
( \6 j8 ~3 A( C# \& ^ - while (BufferLength--)
' `9 t/ b' \7 S6 o! U9 s - {6 b/ ^5 Q. G' o3 x' F
- if ((*pBuffer1) != *pBuffer2)1 {4 s. i9 Y) k
- {9 D6 y7 l8 W. Y8 [4 J" E# s9 \
- return BufferLength;
" z* l* N. d# J4 w& \3 @2 Q - }
# |! K2 W$ K5 K3 s4 ]2 X' Y/ l - pBuffer1++;
& S) _( P2 R0 t; b: T$ m$ H; \ - pBuffer2++;
H0 q5 p. Q( O6 Q( f2 k4 S/ w - }# R# B7 D+ x# }3 E$ b/ t
% _9 ?* f4 n7 t' X- return 0;
% D! h) `- l# l. ?" {! t) I- G - }- b4 n6 P* c- P0 S* t7 j
复制代码 我们在while开启LED循环,只有前面秘钥验证正确后,才能执行到该处~: l. [9 V+ d+ D# D4 r7 `3 I# x
- /* USER CODE BEGIN WHILE */# L. t9 q* @0 o& q6 b+ R3 j
- while (1)
0 s1 n; W) H- j - {
3 } G- J6 s/ ^0 o1 F7 b5 o! X2 ` T - BSP_LED_Toggle(LED7);
; G5 r2 b Z: G$ N - HAL_Delay(400);
/ [ x/ n. B0 W, C9 ` - /* USER CODE END WHILE */( w& }- J/ P, l1 b
- 2 I/ U* V2 @- O
- /* USER CODE BEGIN 3 */
- P1 b1 Q8 @6 X - }
复制代码 编译,下载查看,测试通过LED闪烁:
) ~( ^' u/ u- E
. ]9 ]' y Y. u, e7 e7 W
y4 q+ _2 p. ~
用PKA加密的好处就是有多种模式可选,而且不用CPU干啥,也无需外围加密芯片~s是个不错的选择!
& d- F, Q& Y" y9 p当然,这是有大量的兑换机制有ST及其他密码学人员帮我们弄好了,其实也是挺复杂的。对于我们开( E% S+ d5 g- M& F/ K$ N; O
发着而言,直接拿来用即可~无需知道下单的鸡长什么~当然有大神因此去读密码学也是不是不可能~$ d9 c c5 M' M* Q
|