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

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

[复制链接]
STMCU小助手 发布时间:2022-4-22 22:00
一、头文件) v7 z4 x4 L% ?6 \/ D) x+ h6 I: w
6 M. {1 J! c: H
  1. #ifndef _AES_H% O& c! r* l* C& y' @4 C' r, Q
  2. #define _AES_H
    1 D  [' k- r3 R% E' ~) w- N( r
  3. 6 g) \+ h; J- X8 ^+ m

  4. % L3 x4 E* k0 W. t& J
  5. // 以bit为单位的密钥长度,只能为 128,192 和 256 三种7 Q. H1 Q+ c! q4 q
  6. #define AES_KEY_LENGTH        128
    , A1 ?7 @: ?7 ^- J" C
  7. , \7 _: J% \+ M, ]4 Q0 @1 a
  8. // 加解密模式
    ; y5 T7 {& Q0 l! `/ t2 L7 Y# h* v
  9. #define AES_MODE_ECB        0                                // 电子密码本模式(一般模式)5 w1 S5 A$ ^* D% e4 B  z
  10. #define AES_MODE_CBC        1                                // 密码分组链接模式
    , H) C9 a1 }. r# u  z/ H
  11. #define AES_MODE                AES_MODE_CBC
    7 T9 }' V! Q4 G/ W& {1 {8 E5 q4 g* I
  12. ! Q' m- U/ b+ [/ ?3 h

  13. * e+ N# |0 Q  l2 n' \
  14. ///
    , b2 `7 {$ N+ F% G! }7 b
  15. //        函数名:        aes_init9 _: U" [! H1 S  g
  16. //        描述:                初始化,在此执行扩展密钥操作。
    ; R8 ^( z9 M, j7 D% Y
  17. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    " T$ H+ D" t* t* G7 m" l9 j$ s
  18. //        输出参数:        无。* Y* _4 O$ R) d, r
  19. //        返回值:        无。) b! @+ U9 K" P" C
  20. ///4 u4 A8 X! C# E; R0 K
  21. void aes_init(const void *pKey);9 O$ u, c# _) [) H& M5 |- K" a9 }
  22. / H* @4 P( D3 E' I
  23. //
    3 d. [+ C3 U' q8 a" p
  24. //        函数名:        aes_encrypt
    5 ]7 j5 S& A% ^% _1 p
  25. //        描述:                加密数据
    5 f6 w0 U" y3 j7 C, S, P
  26. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。/ g0 t) Q' t; h' z
  27. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。% K2 G: ~( y. `+ r+ ~
  28. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。8 g# l6 G5 G7 x- s  @3 Y
  29. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。
    + N+ n( W; ]8 Y& A' h9 K: B1 G2 V
  30. //        返回值:        无。
    $ _/ u3 A; f2 `9 t' Y, ?
  31. //6 M7 h& [+ G# `/ g( t. a
  32. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
      ~' v+ f3 n" p! h; i% [7 k- D
  33.                                  unsigned int nDataLen, const unsigned char *pIV);2 g; ^1 ?% E4 q8 g: c5 E# S

  34. ( H0 D) q& `* A6 a
  35. //0 r+ b/ v2 c! w
  36. //        函数名:        aes_decrypt
    3 O5 i5 b+ ^0 R+ j9 [
  37. //        描述:                解密数据
    8 m, v8 k3 M# w5 Z
  38. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。, |8 `* G6 Q2 e* G  `
  39. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。+ X9 N% M1 ~% F1 ]1 E6 P
  40. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    2 w1 o% X. R- Q/ F3 ?. |0 }( o
  41. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。3 \( T. `! C: e( c9 @- C% c
  42. //        返回值:        无。
    ( j7 y/ ?  U3 ]# Y3 [& L0 j7 ?2 }
  43. //6 k* p. d, r$ w" D. v& ~8 D
  44. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, * Z0 r8 V; c9 _/ I  N
  45.                                  unsigned int nDataLen, const unsigned char *pIV);
    2 V2 X. X& t! L7 a) m0 ~% k1 D
  46. #endif  /* _AES_H */
复制代码
( k! W; ^* h2 |9 C; e* S
二、源文件3 s# V1 i$ p7 }4 H2 `
- o5 Y/ _. M* |$ a, P" b1 p0 y
  1. #include "aes.h"8 O! q* b% o2 i4 i; e  p, w' @) O. y
  2. #include "string.h"
    6 c' \9 t2 z  B$ K# O
  3. : g1 n- \* Y$ Z9 g+ F" n0 d  Y+ O; `

  4. $ E: x) h: c6 n' O$ i5 w/ n
  5. // 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
    0 A  P1 \5 m* J
  6. // 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空3 y9 Y8 N* ^7 d6 b' s9 H
  7. #ifndef __C51__  N# D- t$ Y4 q
  8.         #define code' d. `, Z  _! ^+ H: h9 _" V& T
  9.         #define data* ], u6 c! t9 p9 M
  10.         #define idata' E) O1 W7 Z: l5 N& G: w% q3 C) g2 Y; t
  11.         #define xdata
      E; u; c! j, x! J+ A
  12.         #define pdata  M4 r$ c  G, W6 w$ R, g
  13.         typedef unsigned char BOOL;2 W# j7 a: Q9 n. m8 `( B% [( q  X
  14. #else% B3 \6 K$ M7 m- g8 Y" o# Y* A7 \
  15.         typedef bit BOOL;- o7 Z! v! j# k' e: }9 ?1 n# s
  16. #endif
    1 i5 s& V+ V+ Z% S) P) g6 r

  17. & S( D9 i+ x! @2 ]6 C
  18. #define Nk        (AES_KEY_LENGTH / 32)                // 以“字”(4字节)为单位的密钥长度
    * q1 @* V, q  L$ F% L
  19. #define Nb        4                                                        // 以“字”(4字节)为单位的加解密数据块大小,固定为4
    5 f4 @- O& {7 [+ z, K
  20. & o+ J/ L, i- j# B& Y1 P
  21. // Nr:加密的轮数; b" s" F9 f! i: v: N
  22. #if   AES_KEY_LENGTH == 1283 T' P. S& s( P% s) r& _. \
  23.         #define Nr        10
    / ^* j! c5 Y; ~
  24. #elif AES_KEY_LENGTH == 192
    " h/ X, {; E3 [5 Z4 D
  25.         #define Nr        12* Y' X7 k, i5 v" a* r$ {
  26. #elif AES_KEY_LENGTH == 256
    - C9 ?. T5 o& b6 r7 ?7 _
  27.         #define Nr        14
    ( [! m9 N' C4 z" r* r. H+ k% h
  28. #else) m3 _" b9 a3 M# e7 c9 c9 }+ }
  29.         #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
    1 i8 h0 o/ h/ Y7 `. E1 x
  30. #endif
    ; f# U4 p. q3 K' e0 z2 \. l

  31. 3 x6 Y$ V, L. x# h4 i  g5 G3 }
  32. // GF(28) 多项式# A( w9 s& O! T0 O
  33. #define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).% y% M0 W7 @  N

  34. ( [1 b' [, P  j3 |
  35. /*****************************************************************************5 T( ~7 t  c3 n3 V  l
  36. *  Typedef  Enum                        枚举定义4 f' X/ R. v" x  f
  37. *****************************************************************************/2 v% u0 r  P: z) m# c
  38. 5 t- `  h$ Z4 j/ A
  39. /*****************************************************************************
    ) H* n  u& S& k* R' y6 v
  40. *  Struct                               数据结构定义+ E1 j+ \( ~) K% y; q0 S
  41. ******************************************************************************/
    8 {! k' W6 t7 ?

  42. + E# c7 ?7 P. g; V- r& Z! h1 r

  43. / M* c( P5 \+ Q5 o* Z4 c
  44. /*****************************************************************************2 T9 c# Y! H7 _0 a  [
  45. *  Local variable                       局部变量
    9 v4 M$ `0 L8 S! o) W' S
  46. *****************************************************************************/' I( x* V5 j7 {0 X

  47. " ~7 k% c' ?" E, E! c
  48. // AES子密钥表,当密钥长度为128位时,占用176字节空间/ e0 \- s& b( C; q( C% }
  49. static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
    ( f4 T- x& D0 r: w

  50. # B  y' y" I" z. D% d
  51. // 加密用的SBox1 c7 P( ^3 \9 ^; N) |
  52. static code const unsigned char sBox[256] =
    8 N2 Q' U" p% E6 O, p! t! W
  53. {1 P" }( |9 l* c, H2 M
  54.         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    - d! z/ I- S; c: `; H* P' p0 M* z$ |
  55.         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,7 H4 v: _  S/ N8 o
  56.         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,8 M" }+ ^5 r  w
  57.         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    4 {) S8 g" Q# ?& G
  58.         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,' Q! c2 T% Y3 T$ g; O
  59.         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    5 N# A" Q0 u" S: w+ O
  60.         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    & I* ~! P; |8 f6 h$ B
  61.         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,  b: Q( [1 }* A# J
  62.         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
      I" L* y) m: Z8 {/ e+ k
  63.         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    & H# O! ]. T( k2 i5 C$ g/ l7 u1 }
  64.         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    ! o- |3 x' O1 j4 }! c1 b% S
  65.         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,$ G- P+ s7 T( r/ `: z) n% V
  66.         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0**, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,- D  _1 I" c$ g7 x4 \! f; V
  67.         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,2 q" f$ @3 C4 `, v" L; A3 w  ~) [
  68.         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,* m: ]- n+ W2 a/ ]7 Y0 \8 X
  69.         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
    8 N" C; e1 C. u
  70. };
    6 o7 I$ Q1 Y+ \5 i% _
  71. ! s) v2 o. ~2 Q; m; M3 ]. d8 z' O
  72. // 解密用的SBox% e8 q6 H# ^9 Z% L) h; [4 P2 S3 M
  73. static code const unsigned char invSBox[256] =
    ) z% V( P" ]4 t& Y! s5 L- q1 x
  74. {
    2 u# }- R1 X6 e7 O' `
  75.         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
    4 P' H1 E5 X' R$ D9 S! V- [( Z
  76.         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
    " n! L* z3 k* K$ n6 ]6 p3 }+ A9 X
  77.         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
    ) i1 v& O$ f6 I
  78.         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
    2 e1 p5 i6 s, s* x
  79.         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,: U1 ^/ y" E, }
  80.         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,3 r( N/ r# q2 A1 i' ?1 Q
  81.         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
    5 z1 T# S+ i' k: {( {$ x5 \) Y6 F
  82.         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,  @; r1 j" Q/ p# `: J
  83.         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
    0 ?8 n' K  n5 j8 k( G9 d
  84.         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,* @0 t5 M% m- o* T
  85.         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,6 p3 M1 Y6 B$ O, v: H/ D5 {
  86.         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,. z, T% u* X( Y! Q
  87.         0x1f, 0**, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
    - A) P& G/ @7 j2 s2 [0 d' o& B
  88.         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,/ H# `! C' ~3 n# Z* q
  89.         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,2 V& a4 U0 I9 c9 j  U
  90.         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d        4 ~2 W: t* v* L9 z" ^- }4 o
  91. };) O2 R7 f6 t, e) l$ s7 l

  92. 6 k' ~$ O4 b/ |4 {7 A+ l: b, x

  93. 7 K5 Z  N$ I. V( g
  94. ///
    , ?6 w3 Z1 H0 c1 g0 O! s
  95. //        函数名:        rotation_word
    0 H- W4 N3 c  J$ B, W3 p
  96. //        描述:                对一个“字”数据进行循环右移。
    % w0 C7 W5 ^) `+ ]
  97. //        输入参数:        pWord -- 要右移的4字节数据。7 a8 A- b: U) u9 L  I
  98. //        输出参数:        pWord -- 右移后的4字节数据。
    % r  y+ d7 a* G8 X3 t; O
  99. //        返回值:        无。
    8 p* T9 A% ?* i
  100. ///
    0 j4 t8 u$ h) t
  101. static void rotation_word(unsigned char *pWord)) x, \4 W  J2 X" e# _# _0 K3 s; q
  102. {
    & b; S5 I, k' E, i3 {* Y4 c7 q0 O
  103.         unsigned char temp = pWord[0];7 F  o: R* |9 }
  104.         pWord[0]  = pWord[1];# m1 a, ?1 a8 _' H1 t1 t- a. c" j7 u4 V
  105.         pWord[1]  = pWord[2];
      z7 z3 N& a% W( C: |, `( w
  106.         pWord[2]  = pWord[3];8 |2 R  Q2 b5 w/ M$ p8 M- s
  107.         pWord[3]  = temp;
    - U* J0 I3 j" s3 E, g
  108. }
    0 b6 V) h9 W- S3 q9 G& @

  109. , [& B& o/ L5 [
  110. ///
    / X, G$ {4 z9 `3 ]+ b
  111. //        函数名:        xor_bytes
    ' v3 ^# u' {3 p# v3 f+ J* f* S5 T
  112. //        描述:                批量异或两组数据。
    $ r: o: N/ g  q
  113. //        输入参数:        pData1 -- 要异或的第一组数据。
    1 W% m" Q5 p7 k! u: u
  114. //                                pData1 -- 要异或的第二组数据。( @' P+ Z5 Y( j; m$ l& U7 J8 ^& ~4 r
  115. //                                nCount -- 要异或的数据长度。
    0 w; G- c/ P7 S7 O7 P7 p/ M, \
  116. //        输出参数:        pData1 -- 异或后的结果。( ]4 Q. D, G' i8 x3 C3 S
  117. //        返回值:        无。
    # z* ~2 v/ d6 D) k) S
  118. ///
    + ~- g7 n% e. b: }, ?( I
  119. static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)7 b% h, a& [! t' V: z4 E
  120. {
    : M5 `% _  B& F" a1 z7 h) u
  121.         unsigned char i;  @+ V5 ?) |3 E% \! U
  122.         + ~) k( _8 }. m8 T7 j. M6 ?6 m1 `- z
  123.         for (i = 0; i < nCount; i++)
    % N* f# v& z: n6 V
  124.         {
    ( s8 x" n2 V( F" H; y
  125.                 pData1<i> ^= pData2<i>;
    0 u1 K0 V' O' H
  126.         }
    ( m* z8 o, A9 d! p* }
  127. }/ C( ^( L- x) J9 u/ {

  128. 9 Q8 w* S: L% u. b) l3 y! a3 ], H
  129. ///
    : {- J4 F& M  p$ q" Y
  130. //        函数名:        AddRoundKey
    5 _$ @5 k8 T! ?6 T8 h8 g
  131. //        描述:                把 中间状态数据 加上(异或)子密钥,数据长度为16字节。( b0 B1 f- I( m( r+ j% Y1 |# w/ N
  132. //        输入参数:        pState          -- 状态数据。
    5 B8 |. q# @( v4 |( D
  133. //                                pRoundKey -- 子密钥数据。
    " Q7 J1 ?9 z+ g; z3 H
  134. //        输出参数:        pState          -- 加上子密钥后的状态数据。% \% Q1 R, l  v
  135. //        返回值:        无。7 T  P! k( g7 Q: E" i
  136. ///
    + g) F: \* f9 N* A& \/ w) M. e5 L
  137. // static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)( P/ x! o0 x4 j' x! L" O: B
  138. // {( i9 G0 H5 `# ?9 m3 _# L+ L' M
  139. //         xor_bytes(pState, pRoundKey, 4*Nb);2 i: M! C9 R* W' G* _' L# W
  140. // }9 s0 o7 ]: l: c: t! W
  141.   M5 J9 Y7 v- b5 ]0 f' z" y
  142. // AddRoundKey的宏形式,比函数形式可以节省4字节的data数据2 _2 {2 i: ?# X) @% M: L
  143. #define AddRoundKey(pState, pRoundKey) \4 @; H3 g" e* G; v9 c+ k2 e) u
  144.         xor_bytes((pState), (pRoundKey), 4*Nb)
    4 q9 B$ r. J4 ^( K: }

  145. 1 B& [, O$ w3 X# F  x. r7 ?6 s1 v
  146. / g4 @; z; j3 e
  147. ///
    # Q( d5 {& ]; Z1 S/ N0 B+ i+ L
  148. //        函数名:        sub_bytes
    % r2 T( k# H# E9 H2 ]
  149. //        描述:                通过S盒子置换状态数据。" f3 ]) D5 V' |8 k) `! L
  150. //        输入参数:        pState        -- 状态数据。% Y' e! Q  Y7 J. W" g
  151. //                                nCount  -- 状态数据长度。/ B" w! y' S" e$ ?) }
  152. //                                bInvert        -- 是否使用反向S盒子(解密时使用)。8 w7 B! m% K+ U# V. R7 \
  153. //        输出参数:        pState        -- 置换后的状态数据。' `# p. `, z, D% B' t
  154. //        返回值:        无。3 |% o4 k0 U+ O2 s
  155. ///: M  x# b- J6 p- x
  156. static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)( w9 g( _7 I/ Q1 v+ h0 \  _
  157. {
    ' J3 _* W' G  C
  158.         unsigned char i;
    - C% `( }; L7 I  `8 K" b% G
  159.         const unsigned char code *pSBox = bInvert ? invSBox : sBox;
    " _+ b! r" f, j* o8 Z
  160.         
    , u, b7 w, `, D# P4 P9 k. Z6 m7 _
  161.         for (i = 0; i < nCount; i++)' C( ~8 v  }+ U. }) w% L1 k
  162.         {
    " t3 T6 P' [, A( @1 y+ b
  163.                 pState<i> = pSBox[pState<i>];; j% d/ B/ j& `, ]9 O
  164.         }
    # G% T5 b  [( e
  165. }
    9 L* z2 h& E& s! s) c( o, c
  166. / o. b6 {- W. C2 k
  167. ///- y. Y' B2 X% x2 f* K
  168. //        函数名:        shift_rows' x  Q7 D9 ?! Y4 g% q, `
  169. //        描述:                把状态数据移行。7 A: d( \3 {6 k  m" ]: L0 P: j6 U
  170. //        输入参数:        pState        -- 状态数据。
    $ y0 c: W' @( b" c( v9 w: Z
  171. //                                bInvert        -- 是否反向移行(解密时使用)。
    # f% J& r" e5 E: }% [6 j3 Y
  172. //        输出参数:        pState        -- 移行后的状态数据。9 f& o4 ], u! n; m7 S4 n( \* b" z
  173. //        返回值:        无。" z3 J* n+ Z" i- [+ `# e3 w
  174. ///
    / Z( m; i$ B: u' y; i$ Y4 b
  175. static void shift_rows(unsigned char *pState, BOOL bInvert)6 N+ V7 Y4 g- P7 ?
  176. {
    3 B3 h0 b! }  W$ G
  177.         // 注意:状态数据以列形式存放!
    . [5 j# ^. G) r# `/ }) }
  178. , g9 T  n* f4 b$ R+ S9 m% |* C
  179.         unsigned char r;        // row,   行( i4 v3 v. x9 {' C1 E9 X
  180.         unsigned char c;        // column,列
    - x9 U4 t; F6 @$ ?  h
  181.         unsigned char temp;
    3 f2 e' u8 i3 {' G+ a+ n* X
  182.         unsigned char rowData[4];
    / [  D2 ^8 J! Q& G: H2 |
  183.         
    6 O: r, \7 ?7 x3 e5 ]
  184.         for (r = 1; r < 4; r++)8 g- {& v1 `2 N- y' h' L$ A
  185.         {
    ! @: ]. ^$ b, G8 c
  186.                 // 备份一行数据7 P! ~( b) @! o" |8 c2 [+ C. ~  i3 V. j
  187.                 for (c = 0; c < 4; c++)
    % W, f# r+ {0 a$ N! N
  188.                 {# r$ r  s( |5 J5 h$ q
  189.                         rowData[c] = pState[r + 4*c];! v% j* A; c' d, y
  190.                 }
    2 p3 v8 [! r* }( u  P
  191.                 8 w$ h/ x. O3 ^& _& b  I0 q. ?1 s, C
  192.                 temp = bInvert ? (4 - r) : r;7 C. G' o$ k! k% L" ^) j% T
  193.                 for (c = 0; c < 4; c++)4 [) n/ k0 j( u/ X) ~- ^- s
  194.                 {, [0 K* ^8 s( q4 F3 e
  195.                         pState[r + 4*c] = rowData[(c + temp) % 4];2 ~6 {4 [2 h' |
  196.                 }
    ( l7 c9 n, Y! a: J1 y6 x
  197.         }$ w- s, R* v4 I7 \2 v- c
  198. }
    ) h8 V0 h. e8 c& q  S& y

  199. + `6 j6 j% ~. D8 O- T
  200. ///
    9 u  m0 L+ k/ Z* W, S# N5 l
  201. //        函数名:        gf_mult_by023 v9 Y) c- ^5 G
  202. //        描述:                在GF(28)域的 乘2 运算。8 N% l9 d; K, p( ^& P
  203. //        输入参数:        num        -- 乘数。
    , i3 N, O' h- r3 k
  204. //        输出参数:        无。( ?, O3 d% T; [. R
  205. //        返回值:        num乘以2的结果。% `! L% T# Q8 k1 P5 P5 l
  206. ///
    3 A  r; Q. `& C' X2 a' g# I. A
  207. static unsigned char gf_mult_by02(unsigned char num)
    5 G. t/ o3 a+ n% i" @! g
  208. {
    3 B! G& s8 {, u3 U' Y% Q5 O
  209.         if ((num & 0x80) == 0)/ E; s: k7 v: n) ^' @
  210.         {
    4 \& g4 g  ^# D- ~! E
  211.                 num = num << 1;0 z3 K- n  J7 j/ s, d
  212.         }. k3 y, ^7 G$ v) D
  213.         else
    4 x+ p  ~6 X* F" @
  214.         {
    , A1 E6 N2 G, q6 `2 `8 H4 j' F2 |) Q
  215.                 num = (num << 1) ^ BPOLY;
    + o/ [( w! S- T
  216.         }
    5 P; c/ H3 j3 q) B$ {
  217.         / w' e: k2 o0 S+ q
  218.         return num;
      z% b# a9 r" k# ]" W, g% {
  219. }
    0 W0 M0 O' F; Z- u; }. U
  220. 4 p9 w0 U  a  Q6 n, m
  221. ///- E$ c8 }& y# x
  222. //        函数名:        mix_columns1 l3 B( p1 A, w( C
  223. //        描述:                混合状态各列数据。, a- b0 J0 d& l% J3 V) K! J( {- ~: H+ Q
  224. //        输入参数:        pState        -- 状态数据。
    % k7 Z! M  J6 ?. a% v
  225. //                                bInvert        -- 是否反向混合(解密时使用)。
    ) V2 ]% }  o; G" `5 a4 y
  226. //        输出参数:        pState        -- 混合列后的状态数据。
    - C! k( I0 A! U5 Y/ Q9 f
  227. //        返回值:        无。. i/ [% Y6 T/ p% f3 u0 ~: |
  228. ///: P. b3 y+ T; b. X/ C. w: K
  229. static void mix_columns(unsigned char *pState, BOOL bInvert)/ f+ M. \) Q2 @  h5 N. y& ^
  230. {
    ! f- @; A( G( c; |7 X9 K
  231.         unsigned char i;, z, s$ \5 ]& e) z
  232.         unsigned char temp;
    8 h2 |. W, R2 @3 ^
  233.         unsigned char a0Pa2_M4;        // 4(a0 + a2); F2 q! b& h2 f) F
  234.         unsigned char a1Pa3_M4;        // 4(a1 + a3)
    " [  z- P& D: X5 E4 ^4 h* p
  235.         unsigned char result[4];
    8 \7 X1 I( J6 c, p

  236. 5 p5 d4 v! K+ Z6 H& }7 \
  237.         for (i = 0; i < 4; i++, pState += 4). s8 K  K5 w9 c- B" c; c& H
  238.         {
    1 b4 @, ]) l$ k0 b9 G
  239.                 // b0 = 2a0 + 3a1 + a2 + a3
    1 H/ F+ V  ?6 ?: c
  240.                 //    = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0% ~4 f+ l4 g/ ?

  241. # ]+ m* p7 s/ m( {1 q: B' z/ J
  242.                 temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];: H6 f  J5 N& l' T: f
  243.                 result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));
    ( \, M  Z) B/ V; ]: \( R8 h8 K' \
  244.                 result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
    8 m3 E! i+ Q& p& A
  245.                 result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));
    ) t" X6 L* ~1 Q4 b5 o* m# e1 g4 Q
  246.                 result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));1 a# {* H/ e9 Y
  247. ( f! f/ @# l5 w( K. N& \! Z( U+ ]
  248.                 if (bInvert)% n5 C. O! I0 o( ~
  249.                 {( a  m, l, P* A$ Y
  250.                 // b0' = 14a0 + 11a1 + 13a2 + 9a3
    2 E0 B2 A% O3 l# b* H/ r0 p
  251.                 //     = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0        (这部分为b0)$ H8 |" c3 J/ `, V6 w1 t5 N1 r
  252.                 //       + 2(4(a0 + a2) + 4(a1 + a3))8 W+ n2 o; o7 x7 N
  253.                 //       +   4(a0 + a2)0 A4 n+ x8 U* B* ?( E

  254. ! A" Q1 ~* p2 ]5 j
  255.                         a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));  m- q$ I- `1 ^! `
  256.                         a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));. E7 c+ _) h8 C
  257.                         temp         = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));
    ( X' H4 m/ O5 E6 d) @' b* _7 N& y
  258.                         result[0] ^= temp ^ a0Pa2_M4;
    # [+ N. b' s/ Q
  259.                         result[1] ^= temp ^ a1Pa3_M4;
    : q( Y6 e: C' w+ Y
  260.                         result[2] ^= temp ^ a0Pa2_M4;
    0 X, b$ H( l# E  y4 `/ J
  261.                         result[3] ^= temp ^ a1Pa3_M4;( _2 X1 F7 u& ?2 q3 b4 h2 ]
  262.                 }: a( {: w2 X0 ~
  263. 1 ]% A1 @& B( i2 r3 Q3 V/ H; Q; m
  264.                 memcpy(pState, result, 4);# E' h' \$ Y7 U
  265.         }
    0 ?1 N, l8 I6 t6 l. z( B1 T
  266. }
    * M' V' Q( P3 d* h

  267. 0 g) V2 a" [. J) ~) W
  268. ///. `+ s0 G( L8 X% w+ k3 U
  269. //        函数名:        block_encrypt" T- z2 l8 @( c& ~. ^
  270. //        描述:                对单块数据加密。9 l7 E+ R. ^( q
  271. //        输入参数:        pState -- 状态数据。: k/ S) [5 w# R7 H
  272. //        输出参数:        pState -- 加密后的状态数据。
    3 Z2 d9 b! x8 K; ]1 z( Y/ {& O
  273. //        返回值:        无。, Z1 w6 n- V4 K4 m1 s
  274. ///
    4 W$ Y7 X: h( e( e/ u3 G6 P/ Y& G
  275. static void block_encrypt(unsigned char *pState)
    5 ^8 K. Q+ `) U
  276. {) A% Z% w8 `$ `; ]& i1 }
  277.         unsigned char i;$ |6 c2 r" W' V5 K
  278.         
    $ d4 @+ [0 i6 D5 C3 }0 o; q0 r: }
  279.         AddRoundKey(pState, g_roundKeyTable);
    & J& B& Y/ J* L7 w% d, ?" W% W
  280.         : V2 u  Z/ A; l
  281.         for (i = 1; i <= Nr; i++)        // i = [1, Nr]
    ( k  a, j! |/ ]4 U& X( V+ |
  282.         {
    # s* Q6 q. L2 B* Y3 k
  283.                 sub_bytes(pState, 4*Nb, 0);2 u- O* d2 r6 B3 p
  284.                 shift_rows(pState, 0);
    " K! b" W# L# D4 @  K

  285. 5 J( p! n0 {+ d" z0 j& w  Y
  286.                 if (i != Nr)
    $ I7 R- S" n+ B( ]) m. b; ?: D' m+ w
  287.                 {2 m: a. v' ~% A* x  C# O
  288.                         mix_columns(pState, 0);+ t0 l3 x- z6 A1 P) a8 Q1 P+ g
  289.                 }
    # g; g( V0 @; }/ `' ~

  290. 0 F/ k: M) P- b  b2 D
  291.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);& u8 U: q: s3 x- I' W
  292.         }
    0 g, ?4 P+ ?6 Y" Y# J' M
  293.         
    $ B7 |* ^2 b$ Z' Z" b
  294. // 为了节省代码,合并到循化执行
    & E: `! T) H* D7 d
  295. //         sub_bytes(pState, 4*Nb);0 l' Y2 ]! b% M$ D
  296. //        shift_rows(pState, 0);
    9 i3 E8 I4 t4 }" i* Y' u
  297. //         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    6 K9 f7 J  w6 F
  298. }
    " T$ A* U$ Z( A0 [. n

  299. / H+ Q( R  i6 O; h
  300. ///
    1 t" Q5 ^. s" S# ~  P3 n
  301. //        函数名:        block_decrypt
    4 F" t4 E) @3 J( ~: `0 h4 B$ J
  302. //        描述:                对单块数据解密。
      c, t6 _' i4 `
  303. //        输入参数:        pState -- 状态数据。  W/ Y2 X! Y; b/ u( u/ c, y# r2 E
  304. //        输出参数:        pState -- 解密后的状态数据。
    % Z9 U, E& P3 J3 v4 t1 r
  305. //        返回值:        无。
    * p& c: Q% W/ S1 x" @* u; k/ N
  306. ///
    ' m7 T, H$ i6 X( ]7 j7 k2 Q7 e/ c& O
  307. static void block_decrypt(unsigned char *pState)
    * [# t4 f% |  Z! t
  308. {
    ; ~" d) E; X4 |+ C: r" x3 m
  309.         unsigned char i;+ r0 b7 j6 O. n3 U0 }; O
  310.         
    3 d+ `; P: s8 T. r0 o
  311.         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);+ J) y) ]7 Q$ c4 y* a+ ]
  312.         
    " {2 i) N$ l& k( f; X" c
  313.         for (i = Nr; i > 0; i--)        // i = [Nr, 1]  b8 v+ \1 R* v' \+ y) i, A$ P" K
  314.         {
    4 a! T/ N% D6 V9 Y% E
  315.                 shift_rows(pState, 1);
    " q8 G8 h+ E& e; @
  316.                 sub_bytes(pState, 4*Nb, 1);- f( [+ }& [$ U2 Y6 a. R! M+ d" B
  317.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);* p5 R9 A/ H/ p1 c7 U
  318. 6 l. D2 g5 k3 W% c
  319.                 if (i != 1)
    ! x. D& K2 H) A" R
  320.                 {
    $ C8 ]3 V- X9 A. _  |' ]0 I
  321.                         mix_columns(pState, 1);  B3 r; b# E, a% n, b+ ^+ l
  322.                 }5 s, e- _8 {. I3 z) h7 _
  323.         }1 ^, x9 M5 Z8 [) H
  324.         
    ) ~/ c+ I4 B( d. H4 F  K5 r
  325. // 为了节省代码,合并到循化执行
    6 E- e7 W$ G) O; ?
  326. //  shift_rows(pState, 1);: J1 W, ~7 U# i  \/ D
  327. //  sub_bytes(pState, 4*Nb, 1);
    ' A8 w4 ]" p, p" l4 ^% Y
  328. //  AddRoundKey(pState, g_roundKeyTable);. F+ a4 @7 t3 Q1 {9 X% _& F
  329. }
    ; X  l3 ]7 Q# I$ s5 o
  330. 2 }2 v9 B/ l% q; s( e2 B
  331. /*****************************************************************************- V# ]3 E- G# @8 P+ K" S
  332. *  Global Functions                     全局函数# h2 B+ t' [! a4 [2 q* X. Q
  333. ******************************************************************************/
    - o& G8 z; }: v$ `$ N5 J4 |& X; D
  334. , O3 s- [; ~! F( P: [

  335. 0 h' @6 \4 `9 x' ^& H3 ~
  336. ///( p& Z; R! M/ o
  337. //        函数名:        aes_init% ?* I" `# c+ L& ^) V* |
  338. //        描述:                初始化,在此执行扩展密钥操作。
    9 P  j# B, ~- K+ G2 l4 p! G
  339. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。, v2 P: c* C  u5 [, r$ R! }
  340. //        输出参数:        无。5 h  f+ z8 E2 @
  341. //        返回值:        无。
    ) o  C* i; K* a- k. T! Y
  342. ///9 N9 R( Q; j7 k2 O
  343. void aes_init(const void *pKey)  i* {( G* j8 x, g
  344. {
    2 E1 i7 d6 ^) Q/ m: P# n
  345.         // 扩展密钥. M% s- L3 m0 s, j; J7 A
  346.         unsigned char i;4 Z% O# G1 h/ G; k' S4 c' f
  347.         unsigned char *pRoundKey;+ C8 ~8 q3 l! W4 N. t
  348.         unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};; |, U+ \4 ]1 s  W( k  {
  349. . K7 q8 n9 u" o3 |# ]; D
  350.         memcpy(g_roundKeyTable, pKey, 4*Nk);( R0 `0 V: n- j6 E( @

  351. # L- M0 l7 }% p* u. ^2 u
  352.         pRoundKey = &g_roundKeyTable[4*Nk];4 p' t! u1 H+ `2 A; h1 {% s3 F

  353. 5 v; x5 `  |* t# Q
  354.         for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)
    . K2 M9 |1 M7 ?. P
  355.         {
    4 M( u# N# Q" r: v- N
  356.                 memcpy(pRoundKey, pRoundKey - 4, 4);- j' q$ r7 Z4 U- R: s3 y! A

  357. % E6 `- S" d; P+ ^) f1 l- u/ d
  358.                 if (i % Nk == 0), K) b/ x3 W; t- B# M, M% H4 Q
  359.                 {
    . Y- F8 W2 ]1 S+ m
  360.                         rotation_word(pRoundKey);
      s- y) N5 q7 _; U/ |: P4 }7 L
  361.                         sub_bytes(pRoundKey, 4, 0);, p& t4 _; S* B3 M& O% o6 ?
  362.                         xor_bytes(pRoundKey, Rcon, 4);; W2 T/ M) W& Y$ V/ q

  363. & z- C" t+ ~1 \$ F1 Z+ T$ A
  364.                         Rcon[0] = gf_mult_by02(Rcon[0]);9 P1 ]/ ^. z% c5 F- \
  365.                 }+ L- _& Y8 Q6 ~6 F. I8 d: t( t
  366.                 else if (Nk > 6 && i % Nk == Nb)3 W, V, B0 }0 c7 `% ~
  367.                 {
    8 b- Y; Q3 I. \! I$ x% W% O7 [* ]
  368.                         sub_bytes(pRoundKey, 4, 0);# y3 `6 V& O( U6 s
  369.                 }
    + Y1 x6 ^& U1 E+ j

  370. 2 z, D2 [; o5 a; X# x' _
  371.                 xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);
    2 B( W  j  M+ O9 L' l
  372.         }6 D) K; u3 ]' w! E% |1 a: n
  373. }
    2 C4 \3 |/ L! t3 @

  374.   c5 h% l9 y% f% x1 f
  375. //  F/ ?# a) R6 K5 Y, k" z+ U
  376. //        函数名:        aes_encrypt5 b% @, Z" ]) p- S; [
  377. //        描述:                加密数据: M: J$ H& k& }* Q( N. z
  378. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。
    8 k4 C) D3 W- x- \( r( G
  379. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。. n; h: K( B: |# C3 e
  380. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。+ a; W* f9 `  l$ }# {
  381. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。' i5 y3 |! T/ x5 |5 C/ X0 d; |
  382. //        返回值:        无。, ^8 A, e3 c& ~0 ]4 }
  383. //
    7 @" y2 A, c  Q
  384. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
    # Z  V0 B+ x7 C$ _
  385.                                  unsigned int nDataLen, const unsigned char *pIV)
    & g, P: Z( A6 p
  386. {
    4 N2 r! ^: X8 O
  387.         unsigned int i;/ ]+ W2 _* W' E9 ^

  388. 6 h- ~; o+ l! h! }
  389.         if (pPlainText != pCipherText)1 j* e% m2 e! N. C4 A. N
  390.         {
    + Z. n9 l7 S% n) K8 M6 u
  391.                 memcpy(pCipherText, pPlainText, nDataLen);
    % e6 }; s$ p6 Q# ?! A" _
  392.         }
    - x3 `: Z4 Z; S7 j8 h
  393. : \/ i% V7 V5 ~$ v
  394.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
    2 @! n% \4 w9 [; @' o) H
  395.         {
    , D; ~+ G8 k: A' h1 m) ?( a
  396.                 #if AES_MODE == AES_MODE_CBC& |, [. }1 Z. j, j! ?
  397.                         xor_bytes(pCipherText, pIV, 4*Nb);
    # _7 k" y; j7 }( ~3 r6 m1 W
  398.                 #endif6 E$ I- a/ G3 k3 m$ ~0 D' `
  399. 1 u/ c# h1 ?+ h/ o. x! P  {" M  t
  400.                 block_encrypt(pCipherText);
    2 S( U1 d# P3 |! Q
  401.                 pIV = pCipherText;3 u/ C4 f( W* w/ K
  402.         }
    " h9 z- T6 H8 U$ V8 A7 p2 _$ r' _
  403. }
    + Y8 b: h1 z$ r

  404. ; `7 M. M' p$ Y6 u* l4 v
  405. //8 I! k8 K. c, t9 ]7 J% X1 J% o% y
  406. //        函数名:        aes_decrypt
    % \& l+ Q$ }; G7 |* l' G
  407. //        描述:                解密数据
    2 I7 x; R- h4 ^3 P5 l9 N% x* k
  408. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。# w1 S9 j: [  N$ Y# Q5 r& z
  409. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。1 I( u% `' t8 B, \0 w4 |
  410. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    * Y4 \7 r' c* D9 x
  411. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。0 m8 f! N; [5 _* V% D
  412. //        返回值:        无。8 U* J! U' `9 ~
  413. //
    6 y( _$ w* A: k7 k
  414. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, - m7 X- [7 b+ J: y) s# o* y
  415.                                  unsigned int nDataLen, const unsigned char *pIV)3 X( ?1 M) F8 l; y
  416. {; M* j$ B' v* n( T3 U3 h7 t# o$ K: t" W
  417.         unsigned int i;
    & N# B1 g: b6 D7 O# \2 m3 t* T
  418. 9 _8 V! p) }6 E9 @
  419.         if (pPlainText != pCipherText)
    8 z# d& J6 n3 P8 s: C& D0 U, z3 Q
  420.         {
    + C1 A3 m8 N/ j, `& z
  421.                 memcpy(pPlainText, pCipherText, nDataLen);
      }% G% H( Z8 J' [( Y$ b
  422.         }8 `9 t7 T* B4 s9 Y( S3 k0 i7 g
  423. ) e0 g% s; Y1 G8 J. D
  424.         // 从最后一块数据开始解密,这样不用开辟空间来保存IV
    , s. o6 V' _3 w  s! p/ K3 m2 `& R
  425.         pPlainText += nDataLen - 4*Nb;8 ~2 ~. T9 d8 U6 O
  426.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb)# l* ~/ m$ ~& M9 m) x9 c
  427.         {! O& m! x/ ^& g8 a5 b# N: e
  428.                 block_decrypt(pPlainText);
    3 z8 z- c' e' c! s

  429. , A/ g9 ^6 F& _) U& c& `
  430.                 #if AES_MODE == AES_MODE_CBC+ ~2 D  k$ F) }9 e4 [
  431.                         if (i == 1)7 `% [! |0 `+ _- H0 f
  432.                         {// 最后一块数据
    + [9 Z: ~: b8 {7 W' K$ |6 }( p
  433.                                 xor_bytes(pPlainText, pIV, 4*Nb);5 v) I7 ?) c4 }0 A, q) T
  434.                         }
      F+ g0 y9 }: [
  435.                         else( l7 i. i2 K* S" F
  436.                         {) W2 w- F4 h" O. b( s) l. x
  437.                                 xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);; E# l; J2 F- k; t
  438.                         }* f% i6 N, }- ^  W; t
  439.                 #endif
    ( z( Q: t0 ~! y6 k- l
  440.         }
      O; ?# E- w: Q8 h9 n+ Z% |) A. o7 Z
  441. }</i></i></i></i>
复制代码

" o( n( M# R& M* H9 F) c$ u三、使用6 m& [  \/ ]2 m/ g: _7 n
使用注意点:
9 H. t9 p( v3 G" {1、AES_KEY_LENGTH取值只能是128,192 和 256
8 [. G- \  v. x2、密钥和向量表长度为AES_KEY_LENGTH/8个字节
& i/ r) e9 K" r) X) z5 u% g" h5 S3、加密、解密数据长度为AES_KEY_LENGTH/8的整数倍字节
2 M$ a& A6 }# T( h, Q4 B0 y% G
, y6 _% i% K& ~/ Y$ g+ @/ A9 k
) o$ Y" U7 [1 P: y6 P3 x0 X
  1. int main(void)
    6 o. h6 Q% n% {$ h6 [' |) R- I
  2. { 7 X, S. L" e/ O' f5 O, q5 r
  3.         u8 buf[16],saveBuf[16],descryptBuf[16];
    1 m" s+ i- v4 H' `0 ~
  4.         u16 i;
    % w' h/ X' {9 ?% a; b; R
  5.         unsigned char AES128key[16] = "123456789abcdefa";//秘钥
    : l8 Y8 r! C. V- G
  6.         unsigned char AES_IV[16]= "0102030405123456";//向量表9 x3 T. t& e+ V/ s
  7.         delay_init(168);                  //初始化延时函数
    , @3 E( R; U' K+ d; Z$ G/ g4 y( U
  8.         LED_Init();                        //初始化LED端口
    5 x1 ^/ m) }) }7 A  U# }( }
  9. - ~/ C$ Q( h1 m0 x% e
  10.         aes_init(AES128key);//AES初始化
    ( T$ Y) s4 y& I6 t, H0 S
  11.         
    1 R- W% |; p' |" B% E
  12.         for(i=0;i<sizeof(buf);i++)) f0 f2 E2 c/ F  U7 i% |
  13.         {* ]. H! R( ?: c
  14.                 buf=i;
    ! {! G" H7 Y; ?# F% ~
  15.         }: f5 Y1 M& v5 l/ y# ]
  16.         while(1)
      f! }8 ^2 B0 g& P8 L" O* {
  17.         {- g8 v) J' `; c) p
  18.                 aes_encrypt(buf,saveBuf,sizeof(buf), AES_IV);
    & l2 O$ {; f& T' n  Z8 @
  19.                 ' O/ x! S2 W0 P
  20.                
    4 o& |& j& H4 P* i$ _" @
  21.                 aes_decrypt(saveBuf,descryptBuf, sizeof(buf), AES_IV);% S  r8 i2 e2 e  m) D
  22.                
    6 s( c2 ]. S- J5 E7 j
  23.                 9 b9 x# K% h. c$ M7 h
  24.                 GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0对应引脚GPIOF.9拉低,亮  等同LED0=0;
    - j- N0 F) m1 [2 J( r' `* }3 t$ Y
  25.                 GPIO_SetBits(GPIOF,GPIO_Pin_10);   //LED1对应引脚GPIOF.10拉高,灭 等同LED1=1;5 R# ^+ s6 ?0 S& U( e; C
  26.                 delay_ms(500);                     //延时300ms
      I+ }1 }1 ^0 j, {" `/ H' g
  27.                 GPIO_SetBits(GPIOF,GPIO_Pin_9);           //LED0对应引脚GPIOF.0拉高,灭  等同LED0=1;
    ) U1 A# d& V. o# {4 h
  28.                 GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉低,亮 等同LED1=0;
    1 J( @, S: y5 {; k8 \' j+ \7 d
  29.                 delay_ms(500);                     //延时300ms
    / ^& \1 W- ^7 Y$ x, j& @
  30.         }0 V& U' j. E4 j
  31. }$ @' M  z# [# J' Z  ~
  32. & f" l/ u5 p3 s* O, E# Z: e& q

  33. 5 S1 @3 |6 A3 S7 V$ \; v; n
复制代码
" G1 _3 }. c4 [& f2 p: e, v
收藏 评论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 手机版