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

【经验分享】STM32利用AES加密数据、解密数据

[复制链接]
STMCU小助手 发布时间:2022-4-22 22:00
一、头文件) S2 N) ]; }6 x# Z1 y* @% d
& q4 a' {- Z. C0 m4 ^# W$ ?
  1. #ifndef _AES_H
    4 H% c$ ]" L% T9 c
  2. #define _AES_H
    0 t2 {  k: J! a, f$ ?

  3. 8 ~8 T6 S+ e+ S7 G7 Q
  4. 0 ]0 l8 \% p2 b
  5. // 以bit为单位的密钥长度,只能为 128,192 和 256 三种
    ; x+ E: g! Y/ x( @
  6. #define AES_KEY_LENGTH        128! v$ E5 X- |- F, C" t' H9 K) \
  7. . F) [1 X) k* O8 [. d
  8. // 加解密模式
    ' }6 E- |  r: v3 ~; ]
  9. #define AES_MODE_ECB        0                                // 电子密码本模式(一般模式)
    ) V/ [, ~  P' J! N: i) [
  10. #define AES_MODE_CBC        1                                // 密码分组链接模式
    9 y# q4 \' R+ ^; O0 d8 A
  11. #define AES_MODE                AES_MODE_CBC
    ! M5 w2 h3 `9 y' |

  12. 2 l4 T7 R( D# ]2 Z

  13. - t& I& F9 }$ z+ q
  14. ///
    0 v5 W+ V9 k* @. J/ c$ `
  15. //        函数名:        aes_init
    * Y. `- Z7 s& P2 Y2 w
  16. //        描述:                初始化,在此执行扩展密钥操作。/ c. \4 V3 B% g$ t8 G
  17. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    ! A6 I+ ]: j2 i) P+ ^! F0 E
  18. //        输出参数:        无。
    2 |( f' D% {0 u
  19. //        返回值:        无。  Q7 o" a" b% P) q5 z2 N
  20. ///- r, u! s; g7 t- y# n
  21. void aes_init(const void *pKey);
    ) q) c/ E0 B$ [9 L9 W' O3 \+ P
  22. 6 G4 v+ v# j4 w) [5 a
  23. //
    0 j* x/ T0 r" P9 [3 _
  24. //        函数名:        aes_encrypt! [5 W* r) N: \3 Y
  25. //        描述:                加密数据
    % h3 Z* z7 i' ~- x+ v* Y' m& q
  26. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。; U" w8 H: P* d& u; H0 V+ o
  27. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。3 j' g$ l9 f+ d( {% o5 G) R
  28. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。" C8 h% E8 p+ N% J5 l
  29. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。! t# s- i- z$ d5 O( b
  30. //        返回值:        无。& f8 ?2 y  k% A- V* K( J' v$ i
  31. //$ h/ h5 |: i3 y) T! x6 m2 }
  32. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
    * y% Y5 }0 T6 g8 L  r7 c8 Q! I! H
  33.                                  unsigned int nDataLen, const unsigned char *pIV);
    % B7 K; f9 U! v9 E& d' x  ~
  34. & x  c" ?% N! W. J. p( @1 H
  35. //
    1 X! \. x! R( {
  36. //        函数名:        aes_decrypt2 \" V( W) {2 I% x
  37. //        描述:                解密数据
    . K  f: i4 L; U4 J% ?, L( S( T
  38. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。3 U* b" V0 ]" n+ [/ K
  39. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。; y7 g1 S+ [5 S% y/ b# f
  40. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    % U4 M& ?! P* p; n/ }
  41. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。$ `. _+ Z! T  H% \# s! i: o: Y
  42. //        返回值:        无。
    ; l' z( `" N: B  g8 ]" q
  43. //' v/ X% |  {8 X" h/ b: `
  44. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, ( P1 x* D9 x, x; G2 i
  45.                                  unsigned int nDataLen, const unsigned char *pIV);7 Z$ }4 ]0 f/ _* f1 {
  46. #endif  /* _AES_H */
复制代码

2 ]5 \6 \) |- Z: Q" I! D) E二、源文件
, I2 `! q4 H! y9 R$ E* B, {. _
5 H7 Z) o/ J/ y) R; Y# E
  1. #include "aes.h"
    # F) U, _* l- @* B' G5 @
  2. #include "string.h"3 ^' D7 `/ V& G; Z7 D- Q
  3. 9 c, H1 u1 [4 V+ u( i. E! T, @
  4. / `' o* v: v8 W0 Y
  5. // 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
      x5 b! I/ F6 J9 O) B+ Q) M
  6. // 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空" A1 a# F* i, U0 B9 z
  7. #ifndef __C51__
    * u% Q8 e3 X* K& P8 S
  8.         #define code! M) Z; ^" C" X  t( U
  9.         #define data
    6 |7 X; S. I5 D  e6 r
  10.         #define idata
    7 i8 c0 M' v8 U0 [$ z$ d: d. U
  11.         #define xdata9 l1 Y. e9 v) p9 A
  12.         #define pdata
    + |' }! R+ U4 H9 b7 x# R0 i
  13.         typedef unsigned char BOOL;& X/ X* w/ D: y* R' w6 m/ F
  14. #else" C3 F7 P$ E% J" V, X; \
  15.         typedef bit BOOL;7 Y& {! g' y1 ^3 V# ~$ d
  16. #endif( x# D" A9 B4 l, {; D+ Y
  17. & F8 n4 l. B9 N( W. E& a/ J6 [
  18. #define Nk        (AES_KEY_LENGTH / 32)                // 以“字”(4字节)为单位的密钥长度
    3 @: X/ o4 J, S, F/ h/ ]) Z1 x9 U/ z# j: v
  19. #define Nb        4                                                        // 以“字”(4字节)为单位的加解密数据块大小,固定为4
    8 N. C6 M" U) ~; L8 K
  20. * X! ~, a8 Q6 K; W1 x3 y8 L
  21. // Nr:加密的轮数
    1 t: ~) Z/ C  n" n- G/ [' N
  22. #if   AES_KEY_LENGTH == 128
    6 |/ d' A; S6 ?3 r! z+ m
  23.         #define Nr        10
    1 A( d0 ?- L! R+ e
  24. #elif AES_KEY_LENGTH == 192
    5 N3 q) ^) o+ o
  25.         #define Nr        12
    6 a8 ^+ ~& d' D8 O( i+ W
  26. #elif AES_KEY_LENGTH == 2568 T9 V, D1 p7 L- d7 G' A
  27.         #define Nr        14/ d9 `/ B1 x5 p
  28. #else  f  a3 v4 J# y; y7 C& g; {% t
  29.         #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
    7 s/ t+ ?  g5 ^9 [: S# D
  30. #endif& ~8 d( q5 c5 p7 l5 H! c1 k

  31. ' \2 E4 [$ }. U/ Y
  32. // GF(28) 多项式* V' w4 i0 F0 l' Q2 U1 M
  33. #define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).0 G6 |! O, A  X. o
  34. 8 @# d: P& Z$ U- f
  35. /*****************************************************************************$ K) @# x) C  i. @" @
  36. *  Typedef  Enum                        枚举定义
    6 O1 z* m  E8 `2 w
  37. *****************************************************************************/" P; x. U1 b/ h  \! l4 P
  38. ; f- K, A# P& C) ^* R% d) M
  39. /*****************************************************************************1 t+ T! K2 \, V$ S2 @
  40. *  Struct                               数据结构定义7 T6 B! r9 x9 ~' Z8 q
  41. ******************************************************************************/' H- s# p" C* ^! T

  42.   z$ Q3 q! f  r) Z
  43. / o, W6 A) q. O2 a! U5 p
  44. /*****************************************************************************9 m  C8 l9 z$ W4 C9 k6 u
  45. *  Local variable                       局部变量0 U& h( i' y) M0 O" g: Y
  46. *****************************************************************************/
    ; c/ U( R% V* g% \6 o  ~
  47. ! D  c7 o9 A  p8 V! H* t
  48. // AES子密钥表,当密钥长度为128位时,占用176字节空间
    $ i- S" E8 n1 a7 q
  49. static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
    5 d" D4 p8 A7 h5 Q  E5 v! A. L0 i
  50. $ J) X4 U) [- M* p3 r' p
  51. // 加密用的SBox2 S- z0 N* [2 n# F$ G, Q- `9 T
  52. static code const unsigned char sBox[256] =
    % @; j, J, s0 [' n# V. H) P
  53. {
    , G, j" ]% j6 Y+ K/ D
  54.         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    $ l  g# a- Z6 k7 `5 c4 d! n4 g
  55.         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    ' Z8 f$ i8 D  i/ ~
  56.         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,5 b0 ^+ o& v1 V  c" g' g
  57.         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    2 V% C4 y& ^5 _" k) O2 V
  58.         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,8 i; o% ]1 A) f$ b
  59.         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,1 \# J6 t7 W. a
  60.         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,, X, H$ s6 A+ T: i" Z
  61.         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,+ a% R" k6 X6 R/ m
  62.         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    ' f% L9 t2 _4 P! i
  63.         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    4 U2 N  f6 W: A) W
  64.         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,, D# ~9 l3 F8 a! ^9 ~% D$ R
  65.         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    1 S1 c/ f1 X2 K
  66.         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0**, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    8 ^1 C9 e& g7 f2 f/ i* k8 T
  67.         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,4 l: E; e( o4 r- G" j3 U
  68.         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    ! i1 r; S, R  Z" q. g6 a1 E& Y7 V! ^2 g
  69.         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 1 b6 q! x) [- r4 j. m
  70. };
    , U! f+ g, x8 w  D4 G, F
  71. ' t2 }$ r8 Q0 X/ S0 g6 `$ Z
  72. // 解密用的SBox, a, d  e" E6 g8 Z: @
  73. static code const unsigned char invSBox[256] =
    + P7 s' |7 k1 }# L9 O. a
  74. {
    ) O- @, M8 m, i* O" W2 z# \' v
  75.         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
    . c  l7 `4 f# z3 u
  76.         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
    4 P9 c$ P! [- e# ~, G
  77.         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
    ; u% ?, P/ f5 q( v6 Q  ]
  78.         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,+ B  d. K8 A6 e5 @4 |1 e
  79.         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
    ) b: ~( R8 g1 }8 [
  80.         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
    - Y" u' C  s: \" P6 g5 Q# E' V
  81.         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,+ w# J' N1 q  V  \) c9 R9 W
  82.         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,' m$ ^% n# u5 @$ g+ {: o: A/ e
  83.         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
    ' I; c% Y4 R- D) J
  84.         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,/ v! p; C( ?+ @3 d# f- H/ k
  85.         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,. L* t9 U% r3 C0 V2 v3 T
  86.         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
    9 ?1 N1 a8 {+ A# l4 f! Z
  87.         0x1f, 0**, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,; f4 r3 B+ ~5 @) s  r5 p9 }
  88.         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
    9 l* V" T% n& ^, \0 t2 O
  89.         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
    ; @' _. E+ K. ~: D$ X9 R
  90.         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d        " Y; F4 @- P6 h
  91. };
    2 H$ S; e, O, f# X1 |. f

  92. ) n1 L6 A1 k2 |3 |

  93. ) y7 P) b; R) B. Z+ z5 h( c
  94. ///4 R/ G2 U0 C5 T/ t3 ~$ }
  95. //        函数名:        rotation_word' D  t& x' X/ B7 |$ s" w
  96. //        描述:                对一个“字”数据进行循环右移。
    " C' u/ T8 L* m6 O
  97. //        输入参数:        pWord -- 要右移的4字节数据。
    1 x( u7 O2 u; J) ]! k
  98. //        输出参数:        pWord -- 右移后的4字节数据。- |* y7 B+ s1 q6 N2 {
  99. //        返回值:        无。  [4 M+ x" P6 E  U9 j/ U
  100. ///. m/ D- q7 ~1 Y5 O: P
  101. static void rotation_word(unsigned char *pWord)" V# ?7 F6 W% d4 e2 {3 }$ G
  102. {3 @- L& g, N' P/ q; v: \/ }
  103.         unsigned char temp = pWord[0];
    ( @, S1 W- W" E& G5 L; v2 T$ `
  104.         pWord[0]  = pWord[1];; J' b3 }. \4 v
  105.         pWord[1]  = pWord[2];
    1 X0 T/ }" F% b6 f; ^* M; d
  106.         pWord[2]  = pWord[3];  F* @+ R  k. p" ?
  107.         pWord[3]  = temp;
    7 A' h" j# q# z  B- f# W8 R
  108. }
    : W0 {; k6 k/ y) z8 E+ p. e

  109. 6 H2 C4 [% U" N! j, V
  110. ///2 N/ ^* N( G. |
  111. //        函数名:        xor_bytes$ J3 P) |3 z# _! D/ X  `
  112. //        描述:                批量异或两组数据。
      U; D  {8 G5 G
  113. //        输入参数:        pData1 -- 要异或的第一组数据。7 N3 J) G" V$ K, Z
  114. //                                pData1 -- 要异或的第二组数据。
    $ i) v% X0 Y% o$ w7 F; d; }
  115. //                                nCount -- 要异或的数据长度。% K! I+ `/ Z. J# _
  116. //        输出参数:        pData1 -- 异或后的结果。
    # d% i5 I/ d7 Y# w% Y. L$ S1 D3 b
  117. //        返回值:        无。- f, H4 d  v$ l# J
  118. ///
    # V$ w* ]) d/ @8 l/ C- D' i5 i
  119. static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)6 R. h; ~" j8 ]/ L: w) ^* t2 M
  120. {
    3 E$ O: R, U7 A! g
  121.         unsigned char i;8 u. h" ]: A1 \" r) n' n4 z: Y
  122.         
      x, k4 A4 O  p; v, n  J* m  n
  123.         for (i = 0; i < nCount; i++)2 N2 {) K$ _0 [4 x( J2 F$ I
  124.         {
    6 D/ e: p9 F9 N/ t' r
  125.                 pData1<i> ^= pData2<i>;! [, y1 ?! c. d4 K( U7 h: a8 A" n
  126.         }8 p8 ?& Y9 s4 z! h! e
  127. }
    : ^- o+ h6 N  N0 N
  128. & @& p; \( c  E8 }8 F
  129. ///
    2 C3 y4 i* T# z
  130. //        函数名:        AddRoundKey
    / U# f* p: l2 r0 d
  131. //        描述:                把 中间状态数据 加上(异或)子密钥,数据长度为16字节。* B4 C1 W+ ~( d; \8 `5 T2 G+ _
  132. //        输入参数:        pState          -- 状态数据。
    ! C5 O+ Y" ]% R! M' C: i
  133. //                                pRoundKey -- 子密钥数据。
    ) r1 p* q) w) L# ]- L8 w& r) l$ k
  134. //        输出参数:        pState          -- 加上子密钥后的状态数据。
    ' o, Q1 i5 X7 K
  135. //        返回值:        无。
    . H4 W6 t8 g8 d, Q  U
  136. ///3 U/ ?. `* H" T' U6 ]3 G" z
  137. // static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)
    ; J+ p" @' u% ^6 m
  138. // {: g/ c) O/ c, c' ^" s
  139. //         xor_bytes(pState, pRoundKey, 4*Nb);  F# X- c: D" G
  140. // }  J+ F& o, H4 v, t  V3 M/ |

  141. , x3 R' h4 y; U7 [
  142. // AddRoundKey的宏形式,比函数形式可以节省4字节的data数据  C4 i2 z0 x7 f: q' c
  143. #define AddRoundKey(pState, pRoundKey) \
    ) n; M( H! \- T/ u8 I6 Z" [
  144.         xor_bytes((pState), (pRoundKey), 4*Nb)
    " w7 ^& P# ^3 p9 R5 u% b' |) U

  145. " s! E# ]- @5 w' T- z" y7 i
  146. / b6 @; G6 t7 c( }$ ^' \' s
  147. ///  |1 D  p- F% a, ^
  148. //        函数名:        sub_bytes+ N# p0 D/ V9 C  ~  N
  149. //        描述:                通过S盒子置换状态数据。! `  s- t5 I9 G0 P; l7 ~$ S
  150. //        输入参数:        pState        -- 状态数据。  C, z; z- V+ a" W8 P  b
  151. //                                nCount  -- 状态数据长度。
    & O7 o$ h, @  y: H+ u+ l
  152. //                                bInvert        -- 是否使用反向S盒子(解密时使用)。% [- V  ]& n7 k0 @( v
  153. //        输出参数:        pState        -- 置换后的状态数据。
    & A$ o- j) X* W; G3 e
  154. //        返回值:        无。
    8 S( f2 _! Y5 n9 Z/ t6 {
  155. ///
    " z/ C  j8 S! _. I
  156. static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)/ c9 w. {/ H% |) Y# w0 m# H
  157. {
    % ]$ n* \7 r8 w6 }3 M# i& w1 G
  158.         unsigned char i;
    " _  p: w$ W* ?
  159.         const unsigned char code *pSBox = bInvert ? invSBox : sBox;* {! h5 C1 H) z$ l
  160.         ; N& ^  b- h( y9 d, Y. B! f% @2 h
  161.         for (i = 0; i < nCount; i++)# o5 Y1 b% F# F$ n$ U/ N
  162.         {* T8 \. Z2 A9 g4 v- u: Z& X
  163.                 pState<i> = pSBox[pState<i>];
    6 `; R6 q, n- d2 E
  164.         }! m# k/ A! `) G: k
  165. }: O0 s9 Q4 m. C  K- d
  166. - r9 V1 ?3 C2 e0 F1 |
  167. ///) u# L! P+ }/ `, e4 T
  168. //        函数名:        shift_rows! a8 o3 ?4 [7 S/ ?- W
  169. //        描述:                把状态数据移行。
    : u+ r; }* Y* G8 o  r
  170. //        输入参数:        pState        -- 状态数据。
    - h/ c/ d! R) @7 U2 I, D$ o
  171. //                                bInvert        -- 是否反向移行(解密时使用)。
      k$ d' ~: v9 r1 R& @+ g
  172. //        输出参数:        pState        -- 移行后的状态数据。
    3 P2 \! O7 u8 V  x$ r
  173. //        返回值:        无。2 @8 b, g4 A$ I: ?! S
  174. ///$ [7 v1 j4 l0 s' H; K& [% _
  175. static void shift_rows(unsigned char *pState, BOOL bInvert)
    ! `7 V8 h" B7 \+ D1 A6 w6 L" @
  176. {
    # Y& N' x" W. s- X- k8 @2 g" @
  177.         // 注意:状态数据以列形式存放!9 F7 G& \( Z1 j) E7 `' C2 `

  178. ( c, U2 r3 |0 ^* y# ]
  179.         unsigned char r;        // row,   行: r* O; Z: ~: K' V: h* s: R9 ~
  180.         unsigned char c;        // column,列
    8 z4 S# v+ n$ K9 h
  181.         unsigned char temp;
    ' @/ t5 u5 Z1 n
  182.         unsigned char rowData[4];0 `" j& k$ u% D5 G) e5 E
  183.         8 [( Y0 ]. f4 \. i' c0 M
  184.         for (r = 1; r < 4; r++)4 {, O( d% l) k
  185.         {9 ], _% |" l/ ^8 ~
  186.                 // 备份一行数据
    " F& ]' |8 b8 m2 h
  187.                 for (c = 0; c < 4; c++)' R+ I" N  Q" X, ~; i- v
  188.                 {
    7 y+ M9 z& R( a& y; v
  189.                         rowData[c] = pState[r + 4*c];
    3 G; C( m! C7 I; E
  190.                 }
    ; C2 ]; h, ~* C; `; k1 o
  191.                 . A- j, R% \5 |3 ?0 \
  192.                 temp = bInvert ? (4 - r) : r;
    5 C6 q$ f+ e) x( T) j5 j( F+ D
  193.                 for (c = 0; c < 4; c++)
    & _! }8 d. U3 z  h2 U* r0 Y" h
  194.                 {+ q* ]5 f% F5 W
  195.                         pState[r + 4*c] = rowData[(c + temp) % 4];
    ( }) n; e/ C6 ]4 x! {% y
  196.                 }
    ) |2 p' f' Y* a& E2 n
  197.         }! I9 ~4 F3 \9 w( p' p/ |
  198. }
    ; p* P" d# b' ?# X  E3 T# e

  199. + [. f0 {9 V0 y( [1 z. e
  200. ///
    * _8 W$ B* R3 y5 k: M
  201. //        函数名:        gf_mult_by021 @$ |, I$ N# f4 m
  202. //        描述:                在GF(28)域的 乘2 运算。$ V4 B8 b' \5 |
  203. //        输入参数:        num        -- 乘数。; e& g! ?5 x0 b! v  o
  204. //        输出参数:        无。+ d* R2 E/ `9 g
  205. //        返回值:        num乘以2的结果。
    5 v; P& I# V* u( x1 O
  206. ///
    * o$ b7 R% W, d) [2 a
  207. static unsigned char gf_mult_by02(unsigned char num)
    ) l) E' K: D0 X
  208. {
    % `2 |% u2 Z5 f6 r0 ^/ V
  209.         if ((num & 0x80) == 0)' d; C' l( t8 h4 j
  210.         {
    " O8 `# }  ^3 \, R8 A# ^; e$ ?
  211.                 num = num << 1;4 W" ?" z1 o2 b
  212.         }' k, d' |  i$ J- x  G$ y) A, K
  213.         else
    ) A0 N% |# R) x+ D8 V' [
  214.         {0 i. p: w2 c- h
  215.                 num = (num << 1) ^ BPOLY;. [; Y3 b  J2 V$ x7 d
  216.         }. }$ U4 {! L! ?" Q9 J3 n6 q! _8 q
  217.         7 G3 s0 x% b7 U! L( f
  218.         return num;* u4 O. Q" {8 O( Z$ ?, e
  219. }
    3 _5 ^* q1 D1 B0 ?/ J# K5 Z
  220. $ N2 X+ s6 k! e# q* K6 W7 y$ y
  221. ///! M6 j1 G( q0 _6 G/ v1 _
  222. //        函数名:        mix_columns
    $ u! k+ H  t' x$ U8 V: P
  223. //        描述:                混合状态各列数据。
    $ z  P' q8 }" s+ ]
  224. //        输入参数:        pState        -- 状态数据。
    8 x' ]; P1 h" v' i/ c/ j" C
  225. //                                bInvert        -- 是否反向混合(解密时使用)。
    0 ~9 k; H. z8 W2 M- f+ [2 |2 W
  226. //        输出参数:        pState        -- 混合列后的状态数据。, i2 [( U! {2 Z/ G) F' z
  227. //        返回值:        无。: U6 R. u. G$ `, D
  228. ///- D. i- [' r3 C6 f) x! x5 W# O
  229. static void mix_columns(unsigned char *pState, BOOL bInvert)
    ! o1 C3 @8 E1 T+ ]
  230. {' T; a9 y9 G; J6 b' u" v
  231.         unsigned char i;) P6 \" i% y' I" A+ r
  232.         unsigned char temp;
    ) l* r8 }, W4 t
  233.         unsigned char a0Pa2_M4;        // 4(a0 + a2)
    . n: d5 L0 c# H
  234.         unsigned char a1Pa3_M4;        // 4(a1 + a3)% P9 T* _# U3 a' C. A# l, O
  235.         unsigned char result[4];
    * }  `; x8 ^9 Q# Z- H2 P- p
  236. ( `  j9 Y! `, h3 N# r/ V
  237.         for (i = 0; i < 4; i++, pState += 4)
    4 I3 V% A+ b2 h! V
  238.         {0 J% R( t4 c' v2 m
  239.                 // b0 = 2a0 + 3a1 + a2 + a3
    1 }; K5 B8 e6 |4 H
  240.                 //    = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0! B6 m4 w) J# ~5 s
  241. : R: V3 r5 p4 L  f+ E: `
  242.                 temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
    / g) S- R; {" p0 J7 {' i
  243.                 result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));+ M  l( j# G( P
  244.                 result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
    0 @& C0 ?7 X& d3 k; A( ]
  245.                 result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));
    7 U' v  F' J. s) w1 k5 g+ A: V
  246.                 result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));: W' q+ ?, d" g- ~: |0 p

  247. ) O& k7 U; m2 o0 P) P# h
  248.                 if (bInvert)2 L3 `6 ^" @6 c* |2 q0 `) G, Q
  249.                 {
    # e8 N7 Y/ `5 t* D: R4 r# ^# C
  250.                 // b0' = 14a0 + 11a1 + 13a2 + 9a3 + ]; ]2 k7 e4 c. B5 {! y
  251.                 //     = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0        (这部分为b0)
    * A$ D  V7 c1 r" V
  252.                 //       + 2(4(a0 + a2) + 4(a1 + a3))4 i! ?$ @8 u! j/ F
  253.                 //       +   4(a0 + a2)
    * n+ ]! |6 b$ V' o7 r

  254. & {0 u9 X8 i8 _# @
  255.                         a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));; `) `' P6 G: ~+ c' B
  256.                         a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));
    % L9 ^. e2 o# J" i
  257.                         temp         = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));) ?2 R1 \: M: }3 ^5 }
  258.                         result[0] ^= temp ^ a0Pa2_M4;1 K6 i- Y! L: n' D0 F& M8 c
  259.                         result[1] ^= temp ^ a1Pa3_M4;
    ( u* r; c9 {" f+ _
  260.                         result[2] ^= temp ^ a0Pa2_M4;
    # p* |5 G6 @8 d& B) \
  261.                         result[3] ^= temp ^ a1Pa3_M4;
    ; K4 e3 V+ O  X; O' T) p  v7 G0 {
  262.                 }4 h0 M! e( V/ [
  263. + j- j0 S, o- v' ^. J
  264.                 memcpy(pState, result, 4);& b4 k, X' o/ @* M* Q7 Y
  265.         }
    & [5 n0 P8 h' {7 s% C7 K+ Y
  266. }( J. i* F+ U) B. g8 g2 x% ?3 [1 h
  267. % k  X+ \- D: `
  268. ///
    " c+ v6 P) @9 {9 S
  269. //        函数名:        block_encrypt
    1 x+ {/ T) D/ f* e0 _
  270. //        描述:                对单块数据加密。
    ; \. O2 g1 }& m+ l- K4 k( _
  271. //        输入参数:        pState -- 状态数据。
    9 V3 f" ~' @5 ~
  272. //        输出参数:        pState -- 加密后的状态数据。3 q5 v5 y2 T, ]/ ?" @2 Q% s# n
  273. //        返回值:        无。
    ; E' k- Y$ Q$ z: t$ r' }
  274. ///" W" e& S8 ^8 ?! H% x+ w6 U  Q
  275. static void block_encrypt(unsigned char *pState)
    1 s# [1 _! g) L6 r9 U
  276. {/ e, k6 q' S9 a: e9 \# c
  277.         unsigned char i;
    ' S" D) v. U. [3 a$ ^
  278.         + k& d& C  ~0 ~  D
  279.         AddRoundKey(pState, g_roundKeyTable);
    2 B9 @& V( l$ T4 y- V7 u
  280.         5 ]% p) |4 J: a# w4 p7 _; ~
  281.         for (i = 1; i <= Nr; i++)        // i = [1, Nr]0 M1 d( b$ e1 u( a- o  B
  282.         {0 p1 c! R+ `1 K% v
  283.                 sub_bytes(pState, 4*Nb, 0);8 G3 a5 G7 @8 V$ ~0 t
  284.                 shift_rows(pState, 0);  F$ [% W2 @1 z- ]3 m* b" g0 e, p

  285. ' D& s+ u9 D7 u* h1 u1 w. b% B
  286.                 if (i != Nr)) O' b! X0 d6 k/ ]  K" R. z
  287.                 {
    ! ]- c2 x) O  Y
  288.                         mix_columns(pState, 0);/ p1 K3 l. h0 L, k( E5 [7 B! j2 m/ ?
  289.                 }
    1 m& `2 C6 Q: P6 D( }5 |
  290. * y" g: z" V. _5 u& W
  291.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);/ Y, }' e6 n% ^) b
  292.         }4 _, {' b% l* s
  293.         / ~: W& x+ n- E1 [; G( T! J
  294. // 为了节省代码,合并到循化执行# e. B2 d" N4 }
  295. //         sub_bytes(pState, 4*Nb);) h/ i' ~0 c1 @' H% e. u
  296. //        shift_rows(pState, 0);
    5 h6 ]1 l4 J/ p; |
  297. //         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    % s4 W  H- t/ l1 K! F
  298. }
    ( R& c6 C6 @& J$ ^
  299. 2 r+ C3 o( X% Z
  300. ///
    , f. R/ z6 p% \
  301. //        函数名:        block_decrypt/ q1 y8 G0 f2 H7 r$ c( r
  302. //        描述:                对单块数据解密。
    - r' y3 R2 d& E1 ~) ~- |
  303. //        输入参数:        pState -- 状态数据。
    - a8 G& q( D& d+ l( O
  304. //        输出参数:        pState -- 解密后的状态数据。4 D7 y1 ?7 V  y
  305. //        返回值:        无。* q( Y! f8 b: A6 I% }$ c  Z
  306. ///1 l6 F1 X! ?8 P& Z3 D
  307. static void block_decrypt(unsigned char *pState)& e4 G) n' D- X# `( n# m( J# C
  308. {
    0 F# ~+ p, o4 [9 @$ d
  309.         unsigned char i;0 L, d6 p# F1 B1 N4 R1 e: {
  310.         7 T" q$ N6 Y2 A4 E
  311.         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    : ?8 _2 N+ ~: Z
  312.         - M/ |( x1 S6 l' V% D
  313.         for (i = Nr; i > 0; i--)        // i = [Nr, 1]* a. U! r6 f* Q" e5 r* {- r( G
  314.         {4 y( g$ F, I: ]6 |/ \+ c- z8 C
  315.                 shift_rows(pState, 1);: W! ^* `6 J; ?! ?" _( [4 Q6 a
  316.                 sub_bytes(pState, 4*Nb, 1);
    " {# a1 J' s/ q0 g2 w
  317.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);
    7 ^  ]5 B* d$ ^% r& Q) z! V" U+ N
  318. , r- C$ J6 p* b7 U
  319.                 if (i != 1)# n$ f9 w  O. N/ ?( f4 v
  320.                 {9 c) m4 S0 Q' K+ K
  321.                         mix_columns(pState, 1);
    % F) V, U1 O) b  g' w5 Z+ a6 K+ J
  322.                 }
    4 w8 ]- i1 L7 t! Z/ R7 B- u2 o/ y- `
  323.         }
    2 F3 E) I0 V$ Y. |
  324.         
    : |9 v% ^' z1 C! [8 z$ I. g! Q2 J
  325. // 为了节省代码,合并到循化执行' R# r4 p6 ^' R" Y. [
  326. //  shift_rows(pState, 1);
    . f: c/ R8 m. m! j% q
  327. //  sub_bytes(pState, 4*Nb, 1);
    & Z& ]7 A7 h2 f3 s- M, e6 x7 @
  328. //  AddRoundKey(pState, g_roundKeyTable);, ^0 H# E) B. ~+ h9 g  c: b1 {
  329. }; T! u/ |9 J; }1 o6 p

  330. 4 f7 i+ y/ L1 y  T
  331. /*****************************************************************************
    / P, o: }9 Q% L( x; n
  332. *  Global Functions                     全局函数6 h0 w# o4 ?8 [- `" V8 a" c4 u- _
  333. ******************************************************************************/2 o' h+ @2 z/ O3 }! t

  334. 1 L! I6 ~& B% B/ }- s

  335. ' {1 ^/ J! {& d. Y
  336. ///2 d: |, p7 M, Z& {8 X
  337. //        函数名:        aes_init! }, \5 U6 A$ ?  i+ u1 x
  338. //        描述:                初始化,在此执行扩展密钥操作。
    4 e9 C/ w1 l) z2 ?" K& o0 T
  339. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    + V% S6 s/ w5 d$ b9 n  d1 v4 }; b
  340. //        输出参数:        无。
    8 X9 }7 F; h5 U. V5 ]; N
  341. //        返回值:        无。
    4 N6 B+ n$ u  x4 Y: G; \
  342. ///
    8 M4 c- p2 A! p4 Y2 }
  343. void aes_init(const void *pKey)
    . l. p! p* ^- u- o3 Z
  344. {! Z% f& t4 w! S4 B
  345.         // 扩展密钥( ~& ]3 F! ~" }
  346.         unsigned char i;2 ]9 y/ S' m; l" c
  347.         unsigned char *pRoundKey;- b. @% X2 f& w! }. L1 @
  348.         unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
    , L1 s+ Q& F+ e: h6 G2 H5 T
  349. ' ?% \; x! _) S, g
  350.         memcpy(g_roundKeyTable, pKey, 4*Nk);2 S4 K+ D# d9 e# G* D% S

  351. ; W- n6 V8 G$ _' p" @& H8 L
  352.         pRoundKey = &g_roundKeyTable[4*Nk];7 }" ?+ J8 b# y$ f6 H
  353. " s  s7 B# p. w: k4 f% z% Q3 U
  354.         for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)
    9 B' `: b* r# b# F1 j
  355.         {
    ( J# L3 g" y+ P' l7 w0 \
  356.                 memcpy(pRoundKey, pRoundKey - 4, 4);0 m* I5 w4 r: c3 J( i9 r7 |

  357. , c8 A8 V- z$ d; s( K/ R8 a4 \
  358.                 if (i % Nk == 0)5 q4 `& Y2 ^; l
  359.                 {
    . ?& x! u7 D- f- u& b
  360.                         rotation_word(pRoundKey);
    ; d8 \) C/ `* E. b0 H) q8 A
  361.                         sub_bytes(pRoundKey, 4, 0);
    - I% b6 A; u# B6 @' _0 Z, ]
  362.                         xor_bytes(pRoundKey, Rcon, 4);
    % {& W+ a5 A) w1 v
  363. " e  X6 e5 L. ^" {5 n
  364.                         Rcon[0] = gf_mult_by02(Rcon[0]);  v4 d2 X! z2 x
  365.                 }
    ! d6 |# ^. D5 w- D3 ?* H
  366.                 else if (Nk > 6 && i % Nk == Nb)4 G6 x# E! ?1 _' d
  367.                 {6 c8 N8 B3 J7 n, h& B" F' T
  368.                         sub_bytes(pRoundKey, 4, 0);" G8 U: w0 {- S+ F
  369.                 }* d$ s: V$ R2 x8 Z
  370.   e0 C9 q, }- E
  371.                 xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);
    7 d) g" C: {% O- R" i# y" d
  372.         }
    3 O* R/ I1 f  P& b0 V6 z+ @0 H
  373. }" T" a) x# V$ N

  374. ; ^$ I- B$ u3 b  {7 [$ L2 s
  375. //. O$ e; R' W/ W( f/ k8 A! `# H
  376. //        函数名:        aes_encrypt4 c: g! n4 `5 i6 f' |3 ~
  377. //        描述:                加密数据+ o! C# R. z9 ^0 T$ q; b1 i7 p
  378. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。7 M: g8 o1 {- ]) Z
  379. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。+ U* x# j! V, K
  380. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。/ ]! v$ A$ ]1 P9 R# y  O
  381. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。
    6 h4 X/ V7 I0 S1 J
  382. //        返回值:        无。
    ) k4 ?1 l% P/ M( f. Y4 @3 `
  383. //' B2 R6 {. s, z1 [1 g! I# P
  384. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
    % I; G  p- ?. j' |4 ~2 v
  385.                                  unsigned int nDataLen, const unsigned char *pIV)! n& d( N4 y# \& a
  386. {
    8 I! r8 I% `4 ]2 `& D" t; @* x
  387.         unsigned int i;, k8 q5 F# X/ h; S$ |

  388. 7 p. m1 ]) I9 i" v, v2 S- y
  389.         if (pPlainText != pCipherText)( [- f* H2 m9 ]+ j) i& `
  390.         {' ?4 U% g, v) {3 |
  391.                 memcpy(pCipherText, pPlainText, nDataLen);) o) G# F0 S. {$ a# d) y
  392.         }
    2 ^* i! U4 g. q& g

  393. & W2 y2 M( c) x: t/ c
  394.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
      P) h0 g5 v/ W: h  m& R
  395.         {$ X- s$ @- E" O+ z; r' D
  396.                 #if AES_MODE == AES_MODE_CBC4 y8 h  M6 E' A  o) e$ |6 y
  397.                         xor_bytes(pCipherText, pIV, 4*Nb);/ }2 ~% q! w6 f, F
  398.                 #endif" h3 e( _1 X0 \0 R
  399. ; z% s; |  X& _% T% D, t# R+ {
  400.                 block_encrypt(pCipherText);8 M+ {9 l# ^# L* D! C2 m
  401.                 pIV = pCipherText;
    # `: u' F8 o0 V" a7 R; Z
  402.         }
    2 M, S) K  J$ j7 @
  403. }3 s% w* v2 H9 D0 s- @

  404. % l$ ~: D: |) D- R5 p% P
  405. //
    ' d+ h% }/ S6 K, o0 h( m! V: H
  406. //        函数名:        aes_decrypt+ L. K8 \) Z6 i9 X, {/ W9 g
  407. //        描述:                解密数据* K& N0 P+ f6 V/ n1 J4 d6 s+ \+ H
  408. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。7 e* @' ~# d: X: a* [* B
  409. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。2 |7 m8 X+ y/ N8 B8 J: l
  410. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。/ w2 s; T8 d1 X
  411. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。
    8 Q: o- g# T" H) V1 [  W
  412. //        返回值:        无。) w8 H7 B( u1 r4 H4 S
  413. //
    ( f- m: F) D3 S& s9 I
  414. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
    $ U- Q3 ~6 J2 C6 h
  415.                                  unsigned int nDataLen, const unsigned char *pIV)
    4 T% i" \) h, o. W, H
  416. {; T& ]- D- H$ _
  417.         unsigned int i;
    ! h1 n% p( Z% R2 M- c

  418. " R1 z+ ]3 O$ H
  419.         if (pPlainText != pCipherText)( l: `" B9 G# k! l
  420.         {* G2 K0 W$ m: K! D
  421.                 memcpy(pPlainText, pCipherText, nDataLen);; _" X" u- q. L, H' N
  422.         }* |- r! o4 ^: S! G4 L* W
  423. 0 p' `3 l% q: b
  424.         // 从最后一块数据开始解密,这样不用开辟空间来保存IV
    8 n) W* [6 G, H8 S' L
  425.         pPlainText += nDataLen - 4*Nb;
    ; E- A& x% h$ y! A: x
  426.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb). ?- \3 E$ }& f8 x
  427.         {5 s  T: m; e8 `
  428.                 block_decrypt(pPlainText);5 @2 u6 r% B/ X6 I9 U3 h

  429. : q$ C, P- W. d4 I* P
  430.                 #if AES_MODE == AES_MODE_CBC3 \1 f/ w; c5 K
  431.                         if (i == 1)1 u! p9 X' F2 e2 h2 L
  432.                         {// 最后一块数据$ l" I$ e  r( {$ \: c4 x- u% l0 P' g
  433.                                 xor_bytes(pPlainText, pIV, 4*Nb);" J8 _. X) n4 J! b) I5 T5 b# ?
  434.                         }
    8 n/ P1 \; D- y5 v% m7 n
  435.                         else/ O* @9 p2 a# _5 Y2 Q9 x0 G
  436.                         {
    " k) o% O" y8 S9 Q# j1 c8 F  U
  437.                                 xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);3 F# B6 T% t: g% b
  438.                         }; U% o5 U- \6 \* G! X8 x
  439.                 #endif
    0 N# [( N4 i; Y  q1 ^$ l
  440.         }: k4 Y- ^+ g  }; ~" M, l" Z
  441. }</i></i></i></i>
复制代码
' J4 G6 F1 a$ B- h  p$ M
三、使用8 B: b+ N1 u) M8 \) x- E
使用注意点:
( W2 k2 m. A, L+ y1、AES_KEY_LENGTH取值只能是128,192 和 256
% X$ e" @* Z1 b7 e. b, x. C2、密钥和向量表长度为AES_KEY_LENGTH/8个字节
1 g7 X( g8 X% {& u6 }! ~3 |3、加密、解密数据长度为AES_KEY_LENGTH/8的整数倍字节6 j9 o* p. t7 R7 K: C, b
7 D$ q6 N0 n. r- R8 u" N; W
1 H: L+ \" Q7 s, v$ \6 l3 M: _
  1. int main(void)# n5 m- ]: j. e/ R9 P
  2. {
    / T% Y+ _  D+ r. ^
  3.         u8 buf[16],saveBuf[16],descryptBuf[16];6 ~9 D( g- L* r- o! C
  4.         u16 i;6 t! W' R* E. \) V; ?
  5.         unsigned char AES128key[16] = "123456789abcdefa";//秘钥) p. K; c! j' u$ b1 y
  6.         unsigned char AES_IV[16]= "0102030405123456";//向量表
    . g/ _" ]3 f. D0 V  ^0 B% n
  7.         delay_init(168);                  //初始化延时函数; j9 h/ j# s* b, R  N8 `$ m
  8.         LED_Init();                        //初始化LED端口9 K1 r# ?5 k7 k1 u
  9.   ?: m+ K4 @: S4 G0 \
  10.         aes_init(AES128key);//AES初始化
    & k. [! P5 \4 s2 q4 Y
  11.         
    ! ]: l: V% \8 |: n
  12.         for(i=0;i<sizeof(buf);i++)
    1 `% L4 ?: k( r; c5 P* a! Z( _
  13.         {3 m: Q0 U9 z1 S4 d, i: Z6 [, F- l
  14.                 buf=i;
    : ]- W! ]' V: G& [' ?  M
  15.         }
    $ P- O5 _; W' z& F4 o3 r5 o9 L6 l
  16.         while(1)
    & b9 H0 S' ~* P' W
  17.         {- E/ e3 P4 }0 H$ }. ^# b- A
  18.                 aes_encrypt(buf,saveBuf,sizeof(buf), AES_IV);0 {* S. z, ~( ^+ Z# I
  19.                 8 O5 {. E& z& ]0 j% q  a1 E0 p+ E
  20.                 & Y* [* k/ T/ k9 g! l- z: P; e
  21.                 aes_decrypt(saveBuf,descryptBuf, sizeof(buf), AES_IV);
      Y- T6 U7 D& W' r6 h+ i9 a' x
  22.                 - A! `" ~9 [; \! z
  23.                 # C3 n' S# A$ B
  24.                 GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0对应引脚GPIOF.9拉低,亮  等同LED0=0;" R: ^" E7 ~) ~4 U7 }
  25.                 GPIO_SetBits(GPIOF,GPIO_Pin_10);   //LED1对应引脚GPIOF.10拉高,灭 等同LED1=1;
    : e' f% e1 w  ?
  26.                 delay_ms(500);                     //延时300ms, @  _$ `* F' }
  27.                 GPIO_SetBits(GPIOF,GPIO_Pin_9);           //LED0对应引脚GPIOF.0拉高,灭  等同LED0=1;% U; b7 v( X+ P2 [
  28.                 GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉低,亮 等同LED1=0;
    + D6 F( i6 I/ Q$ c3 {0 ~
  29.                 delay_ms(500);                     //延时300ms" X% u* J: }: s% G
  30.         }
    6 n6 W" w1 \- z- K2 _
  31. }  j: Z1 y' {: _" o* p. X+ r

  32. 5 \* ]; Y' ^& D& `& S$ _4 Y

  33. : X; X7 y8 R( h6 R
复制代码

$ @' e. X# }! @
收藏 评论1 发布时间:2022-4-22 22:00

举报

1个回答
立码赚 回答时间:2023-3-1 21:25:28

AES加密这么复杂?

所属标签

相似分享

官网相关资源

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