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

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

[复制链接]
STMCU小助手 发布时间:2022-4-22 22:00
一、头文件
/ F" ?( t/ K  M4 v. k1 ?
0 [9 W6 q% ^, [, U5 N4 p- y
  1. #ifndef _AES_H) \$ V, x0 {) {: S$ X
  2. #define _AES_H
    # {3 P( }+ C0 g3 c( j

  3. 7 @; ]5 G+ J! g2 B

  4. ' E5 r9 o' P/ p0 n+ M/ |: l
  5. // 以bit为单位的密钥长度,只能为 128,192 和 256 三种
    ' F1 `1 |. Z( U" c# }
  6. #define AES_KEY_LENGTH        128
    : a% J5 j- W2 W

  7. ( O  Q2 g1 L6 y2 L# d; ^6 Q9 u. |
  8. // 加解密模式# t  }3 z8 X; d0 C( c8 _
  9. #define AES_MODE_ECB        0                                // 电子密码本模式(一般模式)
    & `" k7 @$ q. C) [# x1 [
  10. #define AES_MODE_CBC        1                                // 密码分组链接模式
    / x' A- L2 R: `6 u* P% b
  11. #define AES_MODE                AES_MODE_CBC, m. v6 y1 r1 L, R
  12. 8 a! I" }# m( C8 R

  13. 2 {6 I1 M$ |% x
  14. ///
    8 C! w" z$ ~5 @$ d  m" V1 ^6 `7 G
  15. //        函数名:        aes_init4 w* q( g9 S# ~9 H6 ]( ?
  16. //        描述:                初始化,在此执行扩展密钥操作。0 }0 K9 A1 j* l& C
  17. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    $ z2 `4 r! ~/ w2 w
  18. //        输出参数:        无。6 e  W/ r4 S, u' H5 |
  19. //        返回值:        无。
    ; `" Q" d- o  y0 p5 y% y8 N. `
  20. ///
    * E0 S" }& f9 F
  21. void aes_init(const void *pKey);( X( W9 n+ U" _  X2 ?/ r
  22. , q% @  {" x8 D( t5 u
  23. //" G# A- z; e- o' u8 O
  24. //        函数名:        aes_encrypt2 ~$ ?: \( x. M( F$ h
  25. //        描述:                加密数据1 S9 w0 Y3 h; E5 }
  26. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。, U8 r( D* A# l+ @
  27. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。8 `3 u8 P/ B1 m5 P. I% Q
  28. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。* f/ s( m# ~2 h8 ]4 P
  29. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。2 l. L% U8 z7 P9 W4 O3 u
  30. //        返回值:        无。
    & H% g# ^& b, p6 n" ?, d
  31. //$ C7 O: \- W* [9 s/ r: {
  32. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText, ; w6 l" `" g. }& v% g4 e
  33.                                  unsigned int nDataLen, const unsigned char *pIV);
    6 ~' Q, m+ |" }& M

  34. ( P6 q# F$ r- R1 X& N6 h
  35. //
    . _2 ?% R. m% Y, @6 D" ?* k
  36. //        函数名:        aes_decrypt
    / |+ J9 `* ~& f9 A% k7 f# w' t9 k
  37. //        描述:                解密数据- ~' [9 n+ F! D% q5 B5 j8 M  \
  38. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。
    - o  w4 e* H+ c- t. i& p
  39. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    & N$ Z3 g' I9 U2 X3 o4 O. |  H: b
  40. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    8 [: y: p; j6 `: ]8 v  n- i
  41. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。
    / n) I9 Z& m, @: H, z# K
  42. //        返回值:        无。
    : U/ O  _0 ]" `- L' v; ^
  43. //
    $ u; l+ y* [8 |& f/ m6 t
  44. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, 1 f4 ~# \5 t* Z/ I/ s2 P, k" p/ \; ^
  45.                                  unsigned int nDataLen, const unsigned char *pIV);  ]+ a6 Y' R5 {/ X' c0 y; K1 o
  46. #endif  /* _AES_H */
复制代码
0 e, A. _7 |8 z/ F, s
二、源文件
( J- u! a. C" r( R" c  B3 q1 G1 V& f0 H) y" f1 \# p+ h/ i9 ?
  1. #include "aes.h"
    + m0 V0 b5 |: Z/ w4 }8 _$ e6 [$ Z
  2. #include "string.h"9 t' t2 [- A! ^$ Q+ W. @

  3. ' G2 W" C+ E& W* o1 J1 k  t. X/ A. U
  4. # m- q& y- s: W0 i" Z0 |
  5. // 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
    ' y0 i) Z2 A; l2 i% P' T. H" I
  6. // 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空
    $ N! x; I7 b, R1 n/ ^
  7. #ifndef __C51__
    : P: N& P7 t- B! T) m
  8.         #define code
    9 C0 s: L7 \6 b
  9.         #define data. x% F; W: h' C. T3 @
  10.         #define idata& S* H5 J7 a7 y! G; i9 _
  11.         #define xdata. L3 `; u9 V( H9 j4 M: j9 ^
  12.         #define pdata
    / h; q2 J) D) @7 `+ P0 a- h$ @
  13.         typedef unsigned char BOOL;# I4 K1 x1 `1 i( ~% }6 {9 @: P
  14. #else
    5 t' ?1 e% x* R- m6 \0 Z- y4 d/ Q; F
  15.         typedef bit BOOL;$ l, N3 S) @5 C5 L$ H& O: A* P
  16. #endif
    3 T+ |, m- j4 }: x1 e( y2 b: T5 ]

  17. 9 ]: G  ~' v' J( y, ^7 b6 U- X
  18. #define Nk        (AES_KEY_LENGTH / 32)                // 以“字”(4字节)为单位的密钥长度
      U2 J$ l" x! \0 |( ~% k
  19. #define Nb        4                                                        // 以“字”(4字节)为单位的加解密数据块大小,固定为41 t0 Y! [5 v) Z  K7 i
  20. 7 `) B  q  x" m  n& a
  21. // Nr:加密的轮数1 Y% E7 U) V% G3 D
  22. #if   AES_KEY_LENGTH == 1281 Y8 t) {7 j) ]7 ~( w# F$ Y
  23.         #define Nr        10" f! ]  l; W; V/ z' l6 o
  24. #elif AES_KEY_LENGTH == 192- m# B8 j4 r1 A" l8 H
  25.         #define Nr        12, n. u, U- k" |8 c6 R" I# C! o
  26. #elif AES_KEY_LENGTH == 256$ M. O7 \1 B* Z. w; ^
  27.         #define Nr        143 S9 d7 L" u% s7 ]. q
  28. #else' E' ~) j, C& s2 \$ {3 ?1 U7 d9 [
  29.         #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
    / }7 [4 V: c& r8 v; N
  30. #endif: F1 q* x, n; P2 K5 _

  31. , j$ B% o8 }4 _; }5 s# ?
  32. // GF(28) 多项式8 s# s* _1 Y# _/ n8 {; `0 O
  33. #define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).3 E. Y) U$ n* j/ A" u( n7 U
  34. ! s) t. V# W7 W: R9 @- v
  35. /*****************************************************************************1 j( E8 q+ y0 F+ o
  36. *  Typedef  Enum                        枚举定义
      f8 c( H6 X8 o+ Y0 a, m# K8 C! E
  37. *****************************************************************************/
    / H) `8 q6 ]/ t- A
  38. 4 G6 Q/ \; W. L
  39. /*****************************************************************************: }% U: w5 J! L8 c. {$ k
  40. *  Struct                               数据结构定义
    + Q( p) I. L. }" Q- Z) R, I
  41. ******************************************************************************/
    : B# g5 ?* G" S9 c
  42. 8 h% [5 c9 M6 x) z
  43. ; e% Q3 }+ f: \6 {3 m  A$ w/ s
  44. /*****************************************************************************2 [, {: C1 i9 U6 ~7 ]
  45. *  Local variable                       局部变量" a3 o$ C$ j# U
  46. *****************************************************************************/5 S; `6 m, @: P. C" w' B

  47. ' |  [" K/ m& f6 u8 X1 y& Y
  48. // AES子密钥表,当密钥长度为128位时,占用176字节空间
    / n+ m8 V& ?" [3 E; |4 l
  49. static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];( ^7 k) t3 S2 a

  50. $ y3 ?5 n7 B  ^$ i7 W& t. |+ g2 V7 Y2 Q
  51. // 加密用的SBox
    3 D- K/ Z5 p9 p& r9 X  p
  52. static code const unsigned char sBox[256] =
    4 I0 e8 R& a5 B) `# I" q- S
  53. {) P% B. B. |/ Z' q2 P
  54.         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    - ~/ J8 K) q1 p, k
  55.         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    - B: J) `! X& `# ]  j
  56.         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,$ ]6 l5 Y+ }0 L  J7 C, Q& Q7 Y% i" D! T
  57.         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,5 c6 z$ H  W+ G, }! K/ l7 \
  58.         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,) O  Z  D  t# {2 F3 A# G; O0 t1 c8 U5 I
  59.         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    1 R0 ]+ E% w6 L: F/ Y# {. O
  60.         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    $ w, A/ _+ V( n- ]% Y
  61.         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,* Y/ T' J- _; I2 ?( F$ u
  62.         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    # e2 l" n) F0 o+ E1 m
  63.         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,/ `$ o0 u! v* Y( i6 U
  64.         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,1 V& R4 }8 G: r8 h$ l5 w
  65.         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    ( Y+ b0 ]7 d& v- t. q, @2 \) e
  66.         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0**, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,' J0 X- o0 k; V
  67.         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,: G- q" w7 `/ x; [$ h( ?
  68.         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,# k# q" M6 E% B# x: x4 F" b
  69.         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
    . Y0 Q2 W" K/ _9 F/ q
  70. };
    9 _5 K* r: a* O. E' V. o0 c

  71. , H5 r0 f- e8 u/ v+ J4 F$ \
  72. // 解密用的SBox
    - u6 G" ?0 R$ ^- \2 h+ X9 |: N
  73. static code const unsigned char invSBox[256] =
    / p  n0 }+ R! A% o4 L6 p
  74. {7 ?# X( A: Y6 J' ^" f
  75.         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,( y8 v+ W' O8 h( Q+ t
  76.         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,9 R' v1 i+ z7 V9 z
  77.         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
    5 h& T5 |3 [* D
  78.         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
    1 Y4 u" I" y6 E3 x+ e4 q4 ]& |
  79.         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
    - {  K0 M2 N3 B4 e: o6 f& n
  80.         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
    . j. z; v9 b0 w+ D* @- T
  81.         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,% }4 I# @: e, J8 U* H0 r1 K
  82.         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
    7 U& I! f) \5 R0 c3 ~/ f
  83.         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,! o+ }. ?: I0 k9 h5 z" {3 M" \4 B) K1 `6 ^
  84.         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,: w4 J9 \. O1 ~0 C  P8 w
  85.         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
    : ]+ L. M) J  h+ d3 R
  86.         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,/ ~+ R2 M8 D" S1 b+ c
  87.         0x1f, 0**, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
    $ ^: ~: u2 l; S
  88.         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,2 ]) V! J- _1 G. F+ H
  89.         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
    6 o, g1 x( W$ z! d4 l: {9 y, Q. F
  90.         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d        
    * a7 p  ^- c9 e, K0 `6 S2 |
  91. };
    ! w6 p. U/ C0 l' |

  92. : [' e3 ?% c/ q2 w0 {3 U
  93. + O3 ]2 @2 F. {3 e' P
  94. ///
    0 A7 ?% M0 j  m* g
  95. //        函数名:        rotation_word. @, n, V8 |/ @; D
  96. //        描述:                对一个“字”数据进行循环右移。
    3 K+ W+ J  D& f: h% ]) u
  97. //        输入参数:        pWord -- 要右移的4字节数据。7 E6 d( E  [% z# E5 `6 m
  98. //        输出参数:        pWord -- 右移后的4字节数据。' R: D5 L. f3 H; p* ]& y4 z8 `
  99. //        返回值:        无。
    ! ~& H$ T: C- |3 V; F1 _
  100. ///, C/ h1 N' Y2 b! i1 ^- o
  101. static void rotation_word(unsigned char *pWord)  Z7 r( a, s% @
  102. {
    # r' b% O5 X' A+ i6 n
  103.         unsigned char temp = pWord[0];' }3 E$ f; U& S" r7 l: ?
  104.         pWord[0]  = pWord[1];
    0 f5 O( I# Q; w- M! x
  105.         pWord[1]  = pWord[2];" ~6 x8 f, Y, N. p6 P% v
  106.         pWord[2]  = pWord[3];
    1 N6 s) _! z8 s: D8 O$ y
  107.         pWord[3]  = temp;
    6 a8 N: k$ i% {4 @
  108. }
    , t6 Q5 q4 ?* O- w

  109. ) f4 H) T* x/ u
  110. ///" J- B3 X2 \. a1 Q5 }; h
  111. //        函数名:        xor_bytes
    : T8 H( E/ t  f; M% {/ K# o0 B* V6 h; L
  112. //        描述:                批量异或两组数据。( Q/ N& y1 D$ \2 q" Z, Z) _" H
  113. //        输入参数:        pData1 -- 要异或的第一组数据。$ u. o& }$ N2 g7 p6 J
  114. //                                pData1 -- 要异或的第二组数据。
    ) D- R8 \0 z( y7 ~& d8 L2 b
  115. //                                nCount -- 要异或的数据长度。4 _/ h) j- @, J' x; Z  S* I
  116. //        输出参数:        pData1 -- 异或后的结果。
    0 l& Y0 s; e2 R3 V
  117. //        返回值:        无。
    " ~. H3 k+ W2 u6 e: T9 E: L! o4 Q2 n7 h
  118. ///8 H( |* N' A' Y& J
  119. static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)# G+ e* _+ O. u
  120. {
    7 y9 P: D! _( n8 m- s1 C, f. W! I$ N
  121.         unsigned char i;, f+ M+ i4 [: C5 e
  122.         
    , r+ F  u0 N. W4 x4 e; `5 F
  123.         for (i = 0; i < nCount; i++)1 W& @8 S8 `( f; \+ d( o
  124.         {4 v3 p2 K% u% N7 s7 P
  125.                 pData1<i> ^= pData2<i>;
    4 Y7 t: @+ X0 y$ i# o
  126.         }, x' q3 T* v, I( O8 P- h& R
  127. }2 X: a, v' F/ [

  128. % u/ c) C1 `$ D/ i
  129. ///
      }/ v9 u; g* ?' p
  130. //        函数名:        AddRoundKey! o. _2 b$ p/ u
  131. //        描述:                把 中间状态数据 加上(异或)子密钥,数据长度为16字节。+ q* s1 T. ~5 j& T  C2 }6 Y  f' s. b/ {
  132. //        输入参数:        pState          -- 状态数据。
    : F8 ~/ i* y( w/ C; W. H- Z
  133. //                                pRoundKey -- 子密钥数据。
    & C; g8 |* T! L$ y
  134. //        输出参数:        pState          -- 加上子密钥后的状态数据。
    - T- ]/ M$ z! C6 h, a& Z' m
  135. //        返回值:        无。* G" O8 }! W% Y" c: @
  136. ///
    3 P, v$ f6 s' o- p
  137. // static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)+ K% x* M6 N9 \( u& j* t
  138. // {( E% s3 z4 P3 _- k7 N8 l
  139. //         xor_bytes(pState, pRoundKey, 4*Nb);1 X9 `" ^" A9 n$ \% \( Y
  140. // }2 W% k1 _% |: U8 |5 W9 n
  141. # b/ J9 d3 \; e& e
  142. // AddRoundKey的宏形式,比函数形式可以节省4字节的data数据
    ; x- F' W" [! q7 o% Q
  143. #define AddRoundKey(pState, pRoundKey) \
    $ F* |& S* W6 c/ i$ m
  144.         xor_bytes((pState), (pRoundKey), 4*Nb)5 v$ ]0 O: P2 A, b+ G1 C
  145. 8 Y+ `' L' h( Q7 r: A, G6 H& B8 j" ^, s

  146. * M6 a) l) @+ y
  147. ///, k3 `5 v* _/ f- f3 d' ]
  148. //        函数名:        sub_bytes
    9 U$ F! Q7 b3 b/ c) a7 Y
  149. //        描述:                通过S盒子置换状态数据。( H5 _0 J' h; v3 f
  150. //        输入参数:        pState        -- 状态数据。/ q" C& M* `, w4 Y- s) D; \
  151. //                                nCount  -- 状态数据长度。
    0 f. H6 p9 t$ O0 J3 |
  152. //                                bInvert        -- 是否使用反向S盒子(解密时使用)。8 E  g/ Q3 X) ?% H9 ]
  153. //        输出参数:        pState        -- 置换后的状态数据。3 U% e" s2 C, I& r7 A! q" z1 ?
  154. //        返回值:        无。
    5 o2 l3 [$ ]( H7 T) E7 }# t
  155. ///# v4 Y- c& D8 u( B' `; G
  156. static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)
    3 f) w, ?7 R$ {( F5 v
  157. {# n& W  ~, N. R
  158.         unsigned char i;! B/ H0 @! e4 n3 E& t
  159.         const unsigned char code *pSBox = bInvert ? invSBox : sBox;0 p" H1 G6 ]! b' p! `! G/ _
  160.         # \( P; `" H+ I! J$ G
  161.         for (i = 0; i < nCount; i++); r* g" F- i. h* Z* p2 y
  162.         {
    + [* E$ a( T+ C
  163.                 pState<i> = pSBox[pState<i>];5 f  j3 {( l! `% y# b
  164.         }
    ; Y$ P& ?+ D( {% v5 l, b& [+ w
  165. }4 x2 V7 O2 o: k) g+ H) o  V" u
  166. 6 B- u. n' S  I; z; G
  167. ///3 ?. G! v; ]/ ]! f' w
  168. //        函数名:        shift_rows
    8 r0 ]8 Y3 ~$ x% F# A, f% y5 D
  169. //        描述:                把状态数据移行。
    8 f/ C; q* m( [
  170. //        输入参数:        pState        -- 状态数据。
    # v$ T5 e: h) H6 c) n) Q1 Y
  171. //                                bInvert        -- 是否反向移行(解密时使用)。
    % V" a' e  u$ I: l7 f& F
  172. //        输出参数:        pState        -- 移行后的状态数据。8 c. w, s% a  K; @% h
  173. //        返回值:        无。
    ) c6 b4 C. H9 `
  174. ///5 {# i/ w8 h4 C& o, W; n( w
  175. static void shift_rows(unsigned char *pState, BOOL bInvert)8 i/ K* A. B& V1 G
  176. {
    " N5 @+ l$ ?" V3 t- R% N
  177.         // 注意:状态数据以列形式存放!  K( o: N6 }$ A0 |8 S% r) T( u

  178. 0 b# ?' d' b; V* F( a, D( O
  179.         unsigned char r;        // row,   行
    . D% v8 b3 g1 B) E" R$ b1 ]) c3 {; @
  180.         unsigned char c;        // column,列6 v' h( L- L3 h8 H. w( {
  181.         unsigned char temp;
    : p7 j: f2 ]9 c; g! u+ ^
  182.         unsigned char rowData[4];# W2 i; b- ~. n+ u4 k+ n6 r
  183.         
    2 n/ h# k+ [  a* m1 k
  184.         for (r = 1; r < 4; r++)) h5 K! L+ j* G' S
  185.         {
    1 J* D9 j# Q# _# A7 b+ Y1 K1 q7 p
  186.                 // 备份一行数据
    % }- f& v$ i/ K& w  J2 y' \
  187.                 for (c = 0; c < 4; c++)9 ]1 o" p$ K: Z4 B
  188.                 {( f6 W) H0 \, a' F3 j
  189.                         rowData[c] = pState[r + 4*c];3 ~0 f2 s/ p1 n, l! H
  190.                 }
    ! K, V& p4 E9 s% b
  191.                
    ) l4 n: b& p$ O6 s8 L
  192.                 temp = bInvert ? (4 - r) : r;
    % M$ C$ h, }: B5 j  L# D, H
  193.                 for (c = 0; c < 4; c++)
    + x8 v9 K, u  e. N2 C2 Z
  194.                 {
    8 l% {+ f# ~; H, o3 o" @- _" S
  195.                         pState[r + 4*c] = rowData[(c + temp) % 4];9 m  I4 x) |; x7 N$ i8 C
  196.                 }
    % o. L' ^& g. i3 H
  197.         }+ R6 ~% f0 p" ~2 j! h' j
  198. }
    3 v) Y1 c; k6 r7 J

  199. ( ^' @) X7 k& s  Z0 g) T
  200. //// Z& u, v0 [% _- q  l3 E# A
  201. //        函数名:        gf_mult_by029 K/ ?4 H) i2 t! u
  202. //        描述:                在GF(28)域的 乘2 运算。! K: D* \5 f5 J$ ?* w/ U& E- m3 _
  203. //        输入参数:        num        -- 乘数。
    : [4 Q: D) C$ s% t5 U) N
  204. //        输出参数:        无。$ c% D$ ~- C$ B" O0 a
  205. //        返回值:        num乘以2的结果。
    ' d2 J  Y; T9 \) n
  206. ///6 I: b) [* @+ _6 Q8 o3 L
  207. static unsigned char gf_mult_by02(unsigned char num)! G: `6 }0 F* w# k# S- W/ B0 U
  208. {+ e2 n6 o9 g7 y! [
  209.         if ((num & 0x80) == 0)
    % I' Z) \# N* a. L# Y1 r( r5 ?2 d
  210.         {6 {) ?- j# ~8 K/ O
  211.                 num = num << 1;
      Q( U# T  A5 s# F& m8 q
  212.         }, `7 ^' Q  g( L+ `. O
  213.         else2 G/ K* ^" w' t/ H
  214.         {& S9 @: b9 N: ~; A5 G( V
  215.                 num = (num << 1) ^ BPOLY;
      f8 Y$ R/ ?3 p; ?9 N. h3 f: P, D# H/ P
  216.         }& K9 J- Z$ O# ?; q
  217.         % c/ z  D  C- v' H8 X# H1 N
  218.         return num;* N) @- w; O, O3 i# i, w
  219. }* o% `2 u/ x( Z2 c" C: n

  220. / e! S% \, O& K6 k
  221. ///
    , I) L+ @0 o" C! s
  222. //        函数名:        mix_columns' h( P/ ?& h" I. \' J
  223. //        描述:                混合状态各列数据。
    3 g4 b# K' C: F5 t
  224. //        输入参数:        pState        -- 状态数据。
    2 {0 p$ W- |7 n
  225. //                                bInvert        -- 是否反向混合(解密时使用)。
    ; k0 C7 ?- W( t$ I7 l7 C
  226. //        输出参数:        pState        -- 混合列后的状态数据。
    6 n. w" Q! Q) x1 p2 y
  227. //        返回值:        无。
    $ i8 t# i  Y/ [/ X0 @% V
  228. ///0 }; ?  u0 F. S/ ^
  229. static void mix_columns(unsigned char *pState, BOOL bInvert)2 D3 z+ X) ~" X" ~1 G6 @
  230. {9 y+ v6 R* |& {! g
  231.         unsigned char i;
    2 O7 G( t+ R7 e, P4 [  M# t
  232.         unsigned char temp;2 C7 A: |* o2 v( ^! z9 ]
  233.         unsigned char a0Pa2_M4;        // 4(a0 + a2)
    , \, c  d: ^3 J. _9 t4 C; K
  234.         unsigned char a1Pa3_M4;        // 4(a1 + a3)1 ~( @6 B; T) v/ t  z* U  x0 }/ X
  235.         unsigned char result[4];2 v& i- H2 b: s+ \& v/ a& f
  236. : M1 ]- |$ C1 J: p
  237.         for (i = 0; i < 4; i++, pState += 4)
    0 \( j' K1 e6 v
  238.         {( @; ]5 g; [4 v; S0 M- u
  239.                 // b0 = 2a0 + 3a1 + a2 + a3
    7 v; N  j2 K9 w. r4 k# M
  240.                 //    = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0
    - s7 H! N% ?% [+ T
  241. / v8 N  @( K! S7 f0 d
  242.                 temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
    ' l0 v; E1 p8 C
  243.                 result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));
    # |" H5 U1 q7 C/ a; v' T
  244.                 result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
    5 S- \! C: k; l; F
  245.                 result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));
    $ w" ^+ ?! m' L" K
  246.                 result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));6 t3 D. ]2 L: d0 f2 i( D
  247. + O3 A) c9 R7 }: S( O0 W4 [
  248.                 if (bInvert)
    & I* J# R+ _+ {4 x% ~
  249.                 {
    3 n/ I% i2 o6 ^, G7 v. e
  250.                 // b0' = 14a0 + 11a1 + 13a2 + 9a3 $ }8 m% ~( U. {0 Q3 v8 p
  251.                 //     = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0        (这部分为b0)# m; [* ?2 A8 t! O- B  j
  252.                 //       + 2(4(a0 + a2) + 4(a1 + a3)). ]0 U0 {2 s- d2 s( ~% C: D
  253.                 //       +   4(a0 + a2)
    , ~3 m" \5 }! A* p, g
  254. 5 \- j* V  P, b& Z
  255.                         a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));5 r+ [( K% G3 K; k
  256.                         a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));7 g5 n% l: Y/ i. _% a5 |% j
  257.                         temp         = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));0 h6 ^0 x0 J6 b- ~* v/ L
  258.                         result[0] ^= temp ^ a0Pa2_M4;6 n9 T/ D/ X, h' _
  259.                         result[1] ^= temp ^ a1Pa3_M4;$ e9 P7 y2 c' d4 ?
  260.                         result[2] ^= temp ^ a0Pa2_M4;* N- h& S+ U7 ^4 H: l9 l
  261.                         result[3] ^= temp ^ a1Pa3_M4;$ g9 ~- H0 W& k; {
  262.                 }; x6 m) g4 E- i, t9 O6 K

  263. 9 P# k3 [4 e; `1 Z
  264.                 memcpy(pState, result, 4);; K8 R# H- t9 a6 r4 d4 u
  265.         }7 P& H' v# c( `! M) A4 h6 D  v) z" e$ [
  266. }7 U4 [7 T9 D& |

  267.   Z/ _) v5 g- l2 m( L; w' _9 W
  268. ///! V  K! N' p" T  }# G; F6 _3 E
  269. //        函数名:        block_encrypt
    " g' z6 H  M  G& {5 Z$ w* X  t# k
  270. //        描述:                对单块数据加密。+ C+ B( p1 {3 Y
  271. //        输入参数:        pState -- 状态数据。) j9 E. E! D2 q, V- a
  272. //        输出参数:        pState -- 加密后的状态数据。6 y8 h; q+ e$ y3 K% Q" p
  273. //        返回值:        无。
    , t7 M; g4 }* h) X4 {
  274. ///4 z0 P$ w& e; M9 m4 n: a
  275. static void block_encrypt(unsigned char *pState)" w* i8 I4 M7 s( Y$ E
  276. {$ E+ t3 C% H% \% i
  277.         unsigned char i;. L, ?# H% f3 v# d3 R
  278.         - ~* e5 N& x' Y0 e( T; s
  279.         AddRoundKey(pState, g_roundKeyTable);, R( ]+ r; Z1 C* ^2 }  w
  280.         2 s! U! \' [- S* ~, o9 I
  281.         for (i = 1; i <= Nr; i++)        // i = [1, Nr]- t* F  X8 K* A, g) n1 T$ Y
  282.         {
    2 Y* F, H$ i4 X7 N7 y2 N# B
  283.                 sub_bytes(pState, 4*Nb, 0);
    1 h6 X, Z1 P& `5 c+ e3 A9 e9 G
  284.                 shift_rows(pState, 0);2 z) [  Z7 |0 j" l

  285. , m: d- ^. }0 x, ~( f
  286.                 if (i != Nr)
      {7 p% Q! p$ e: ~
  287.                 {
    . n0 ?5 f7 C4 I* {" v' _
  288.                         mix_columns(pState, 0);
    , C, D. A+ R+ G* ]1 q7 E
  289.                 }6 h. X$ K" b* o" L; Y
  290. / W9 ]: C7 p( F9 q5 W
  291.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);
    ' ]( V' A* t& p- C/ ?
  292.         }
    * v7 n" D* J) K7 g
  293.         , q, A# t1 q( D+ l
  294. // 为了节省代码,合并到循化执行
    ! l* m  X  u- a. b$ g, u
  295. //         sub_bytes(pState, 4*Nb);
    $ A# _0 T+ J& @" s- U. b9 b! ^
  296. //        shift_rows(pState, 0);$ N- b- P: r8 Q' ~; ]6 z
  297. //         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
      i' ^+ O  @% @$ K
  298. }* [9 ~' ?; l+ Q* q
  299. / w5 w/ d' d' n- W# V4 d
  300. ///6 ~6 j: w$ Y% J1 P
  301. //        函数名:        block_decrypt
    * w7 I9 l+ |' O, [. x
  302. //        描述:                对单块数据解密。
    8 v" a2 ~1 O% \! M  G! Q
  303. //        输入参数:        pState -- 状态数据。! M- C: b$ `& T  E( _* h+ P
  304. //        输出参数:        pState -- 解密后的状态数据。
    3 m9 c0 f6 S( Z( q3 @& u
  305. //        返回值:        无。0 I. h8 j1 w. b2 j1 u9 A7 t8 M
  306. ///
    " v) X6 A' g9 r% m5 d
  307. static void block_decrypt(unsigned char *pState): F6 [+ ~1 D9 M+ ?, u
  308. {0 A" o4 s; K) e9 C; K# M1 C
  309.         unsigned char i;
    0 i! ?( \# f$ C) p3 \" a
  310.         
    6 R% q; U; l5 e  e# `6 O# f3 r
  311.         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    & Y( r( R5 k0 A4 D
  312.         9 c; X2 {; ^) q& p
  313.         for (i = Nr; i > 0; i--)        // i = [Nr, 1]
    ' p6 M# ^1 M1 F* l
  314.         {
    * A) i; Y: a+ q; [1 S
  315.                 shift_rows(pState, 1);
    0 s  c4 Y$ O5 `- j( t4 a
  316.                 sub_bytes(pState, 4*Nb, 1);
    8 S( [1 L) v& v7 ~, a" b
  317.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);
      L5 p! U: A& f5 O. h9 u0 U7 E4 l

  318. - G( f8 n/ K. ^( [5 O, E
  319.                 if (i != 1)2 w- ]8 @. `4 ^
  320.                 {; `$ }6 h2 Y3 S2 l0 u0 w& Z1 z
  321.                         mix_columns(pState, 1);
    # b' v. d6 E' ~, ^5 m) c* _
  322.                 }3 U  M5 z( i; i* Q& x7 s
  323.         }9 I3 @! ]! k) E1 U( `2 x2 R
  324.         5 X, T6 _; ?+ c4 Q- x
  325. // 为了节省代码,合并到循化执行5 u0 K- Q4 W- c) r) [
  326. //  shift_rows(pState, 1);
    ( U! j+ \0 u" R( _2 U8 l9 W
  327. //  sub_bytes(pState, 4*Nb, 1);* o" v6 W' L: i% X- Y, [5 [. S- K
  328. //  AddRoundKey(pState, g_roundKeyTable);7 k8 P. n" y- ?7 t# D
  329. }. `% Z- {# O9 |" t9 M
  330. 2 t2 d1 j+ A* A  d/ A
  331. /*****************************************************************************) g+ S  s+ b! n; H. Y
  332. *  Global Functions                     全局函数
    . }5 g8 B: U8 N: [9 i* ~% g
  333. ******************************************************************************/
    6 f+ X: \# L- m( h+ T( I$ c0 ?
  334. : p9 Y0 K3 c+ s! K3 p
  335. 0 ?# L+ y6 C! _% }7 d) R$ p+ t
  336. ///9 o6 I, h: d. y2 j5 l9 ]
  337. //        函数名:        aes_init
    ; e* G! A0 ]$ [1 c
  338. //        描述:                初始化,在此执行扩展密钥操作。, e3 l2 G1 Y: Z0 Q* R% T
  339. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    ) b# m6 j. q" y( q
  340. //        输出参数:        无。0 V0 y* q; ]' E! a
  341. //        返回值:        无。. A6 H, o9 d6 X* g  N1 Y
  342. ///5 T" S7 P7 N0 N* b4 I. @
  343. void aes_init(const void *pKey)1 g: s# }' a7 u& U
  344. {' m$ q: K" u9 _  r! F
  345.         // 扩展密钥8 u, x& T9 T. K
  346.         unsigned char i;
    , R# h* u4 E9 U
  347.         unsigned char *pRoundKey;( W# o8 v- m4 c- u0 D0 X' R
  348.         unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
    6 s/ [  |" @; J7 q. O, k4 V' D

  349.   C9 I/ q" f8 d8 f7 h9 m
  350.         memcpy(g_roundKeyTable, pKey, 4*Nk);
    & s/ r( ?! z$ r6 Q) M- J3 m

  351. * B! \/ W* E5 Y9 B
  352.         pRoundKey = &g_roundKeyTable[4*Nk];2 Y3 i: c: w  h$ y  u
  353. & p9 u! R( n4 ^
  354.         for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)7 W$ O. K' ^0 y! Q; Z9 r- g
  355.         {7 V: K( N4 l' T2 L
  356.                 memcpy(pRoundKey, pRoundKey - 4, 4);
    . n1 O, [; d# S+ `3 _
  357. 2 J5 N5 ]" p2 s4 {5 a
  358.                 if (i % Nk == 0)4 i% F6 R# h8 F* o2 t1 Z3 U0 O$ }
  359.                 {- S6 \: V6 I# Q$ O
  360.                         rotation_word(pRoundKey);
    4 ]3 p  `" p# t! R: m6 a' K
  361.                         sub_bytes(pRoundKey, 4, 0);" m$ h! _: `7 S
  362.                         xor_bytes(pRoundKey, Rcon, 4);
    ) Q7 }( i/ K0 S

  363. ) T" d6 L; h8 v3 N9 o" R1 ?, z
  364.                         Rcon[0] = gf_mult_by02(Rcon[0]);
    , n8 h# O. N' k% X
  365.                 }
    ( n- Z3 X3 L2 w  A
  366.                 else if (Nk > 6 && i % Nk == Nb)
    & w8 x' ^' l9 i) w/ I
  367.                 {* K: @3 o" K- H1 w& v# S
  368.                         sub_bytes(pRoundKey, 4, 0);
    % o( Z. I# f3 c6 A! l  I0 U4 A
  369.                 }
      |' p4 |' Q* N1 ?5 l2 F
  370. 2 g; a* }% x. s: ?  I/ z
  371.                 xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);
    % X9 i4 [7 x: a4 ^1 C
  372.         }( m  \# U' U/ T4 @& B/ O
  373. }6 _& c3 C+ s; _* w' }) V, E8 A" K

  374. 4 U6 j5 W1 }4 H* I* K+ Q# p
  375. //# _. u; c& {' g9 p8 d+ s
  376. //        函数名:        aes_encrypt4 L1 Q' ^- y% ^$ J, x8 x  M) Y0 r9 R
  377. //        描述:                加密数据0 R6 c" Z' Q+ U7 m' `' f/ W
  378. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。
    & ]* I2 Z+ H  W, O) c* `
  379. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    4 J  h8 z& m, e' O
  380. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。1 C: j  p' \4 c/ ]
  381. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。+ }) y) c. @" @
  382. //        返回值:        无。. R4 j- i, O5 E3 M
  383. //4 m6 o& I' N0 U' w" {
  384. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
    4 x9 v# O) \2 y) g$ t2 P: k) ~: o7 t
  385.                                  unsigned int nDataLen, const unsigned char *pIV)
    2 X# g1 z% q7 b8 N4 K' Q( H
  386. {! s: P9 l- B, H) i, f" H4 ]
  387.         unsigned int i;9 n( a5 H! A2 n) ^, H
  388. ; x& M; G" ]' _# m2 ]
  389.         if (pPlainText != pCipherText)
    # U! f( O  T( V  [
  390.         {* x* F& f' M7 n) D* `2 J
  391.                 memcpy(pCipherText, pPlainText, nDataLen);
    - u" O, q2 O% c) ~5 }) v
  392.         }
    , c/ R! X7 ]2 M4 g, c' j: A0 t
  393. 5 t% d/ P# y, K, {5 Z
  394.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
    + _7 \% y* ^+ u# h& L. i, o
  395.         {
    # \" D: A4 ~; v9 M$ i
  396.                 #if AES_MODE == AES_MODE_CBC
    ; M. S8 `" s; E. r3 _
  397.                         xor_bytes(pCipherText, pIV, 4*Nb);( ~. h9 S; R5 g
  398.                 #endif1 A2 v6 ?' L$ q0 n# B

  399. % C+ v3 }, h6 H+ k3 f' ]' I+ N
  400.                 block_encrypt(pCipherText);
    ' z1 y  q4 ^4 Z. S3 S
  401.                 pIV = pCipherText;* w- p% V) {5 s! \( Y
  402.         }
    % `5 g% U: {6 R
  403. }. O- R7 A2 z( G; f, c, d% ^; ]

  404.   ?5 {9 c. b; ~, g2 `
  405. //. _7 R( A4 \% Q; D/ {2 ~
  406. //        函数名:        aes_decrypt, P# M4 F7 J4 D; d# l# {+ b' R
  407. //        描述:                解密数据! @% @# X, }9 c% o
  408. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。
    6 ]2 {5 M; N( V( o( P( b
  409. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    ! {, h0 t$ o8 R. T% b5 @4 R3 `
  410. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。$ f6 u# G. W& O. b7 o8 W0 T: }
  411. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。
    $ w# Q4 g; t' p
  412. //        返回值:        无。
      |8 J; P" Z/ l% j
  413. //
    ; r" @# P- `: ^# I
  414. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, 0 }7 L, H5 B7 i7 h( ^- `' `/ O" p& a1 p
  415.                                  unsigned int nDataLen, const unsigned char *pIV): {+ Z, d: y% R% }4 [* T: v
  416. {
    5 i+ u- @3 A' n
  417.         unsigned int i;/ Y! N6 W9 V; `& k3 N& Y
  418. 0 a! ]) ~& j( `2 Z) w6 o
  419.         if (pPlainText != pCipherText)
    " z$ J2 f. q# L% j$ k# S: R/ X
  420.         {
    4 Q( c: M2 T2 R8 Y  j: \! O
  421.                 memcpy(pPlainText, pCipherText, nDataLen);
    3 {, U% g3 J* P; |
  422.         }( y. w8 v7 N& ]$ H3 O

  423. * b" {+ B' q& }+ b7 ~+ p! m
  424.         // 从最后一块数据开始解密,这样不用开辟空间来保存IV
    * Y1 |8 V% Y! j6 U* g, x
  425.         pPlainText += nDataLen - 4*Nb;
    - A. t, |1 n4 z# `/ x+ Y, j
  426.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb)/ ]: S5 r% _( G
  427.         {
    . V7 ]' d9 d; V6 Y/ N: Y
  428.                 block_decrypt(pPlainText);
    % Y# e" f' L& F+ Q

  429. 4 V% W! K) M2 a8 k: K& ^+ n
  430.                 #if AES_MODE == AES_MODE_CBC" S# K- H9 Z7 j- M0 e! J  l; E% g
  431.                         if (i == 1)2 N. z" {8 y5 d$ p+ j
  432.                         {// 最后一块数据5 v: M9 N! k* P$ V2 r
  433.                                 xor_bytes(pPlainText, pIV, 4*Nb);
    + {1 `! u7 B9 h, c, s! g
  434.                         }; V' E: M0 C/ b2 `' a
  435.                         else
    9 y3 S: O) w6 P3 ]. s# |
  436.                         {
    : V! N8 R, ^; X6 V0 B
  437.                                 xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);
    . L6 T  z% t) G3 P& B  h9 u# ]
  438.                         }
    , P0 ~6 ~& f  \) B9 v
  439.                 #endif, J. f7 r# |, B8 X
  440.         }
    3 r- ]4 i8 K, [. ?: b  p( p& _, e
  441. }</i></i></i></i>
复制代码
. t5 L7 U  c9 [6 |8 P' c
三、使用
4 _; v+ i7 i# y: \使用注意点:
4 z6 y8 ~+ T  m9 S* P5 v1 w1、AES_KEY_LENGTH取值只能是128,192 和 256
8 ]8 H3 R; o# u) W) I+ k4 Q2、密钥和向量表长度为AES_KEY_LENGTH/8个字节1 _) X$ O# r2 ?. @! s
3、加密、解密数据长度为AES_KEY_LENGTH/8的整数倍字节
% o* @) [0 f  R
7 S: S8 D, F$ L; ~- U3 b
& c; |( N% q4 s
  1. int main(void)
    9 g) O  ?" G) A0 y
  2. { 4 U: g/ l5 m) @( C- h* W9 y, `
  3.         u8 buf[16],saveBuf[16],descryptBuf[16];0 A& {. k$ i+ n' P0 g" A1 h
  4.         u16 i;
    # E# P- Y$ Q3 y- A$ I1 _
  5.         unsigned char AES128key[16] = "123456789abcdefa";//秘钥; B* ^+ [, @. `' a6 ^
  6.         unsigned char AES_IV[16]= "0102030405123456";//向量表
    6 P8 @: P" J8 A5 L5 [( A7 c. U
  7.         delay_init(168);                  //初始化延时函数" {/ }1 J1 \; S' ^
  8.         LED_Init();                        //初始化LED端口
    ( [/ p3 w0 C% Z. D% u, G
  9. % E) J; b0 ]: x: c" N2 R
  10.         aes_init(AES128key);//AES初始化- A. S0 c+ p. X. U
  11.         - J! t+ p7 w  B, U1 l+ N. C6 K4 K6 {
  12.         for(i=0;i<sizeof(buf);i++)
    ( J6 ~6 E$ ]) m
  13.         {
    ( ^9 S- B* z, ^1 j  S5 ?; \
  14.                 buf=i;
    $ U5 m+ ]3 V& N& ^- D+ Q" b
  15.         }
    7 m" M# K# \. c
  16.         while(1)2 k. Y  p2 @4 U1 U
  17.         {
    0 d! y$ P# ?/ s) M6 H
  18.                 aes_encrypt(buf,saveBuf,sizeof(buf), AES_IV);/ S) ~( l% v/ ^. `
  19.                 ( ^: s% f% F+ L6 r9 @
  20.                
    . i& m" ]4 r, k+ w
  21.                 aes_decrypt(saveBuf,descryptBuf, sizeof(buf), AES_IV);/ |' B! Q( u" ]: z# x$ b& d8 t, T7 G
  22.                 5 W. i+ b6 f6 o5 F% I2 y
  23.                 ; P3 O2 u5 n- T) v7 U' w9 m) U
  24.                 GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0对应引脚GPIOF.9拉低,亮  等同LED0=0;
    # E7 s& D6 f& r) i3 U
  25.                 GPIO_SetBits(GPIOF,GPIO_Pin_10);   //LED1对应引脚GPIOF.10拉高,灭 等同LED1=1;
    ) `- ^3 G/ ^/ g2 z/ V
  26.                 delay_ms(500);                     //延时300ms
    7 O4 \( Q  K( e  \% I+ s7 M
  27.                 GPIO_SetBits(GPIOF,GPIO_Pin_9);           //LED0对应引脚GPIOF.0拉高,灭  等同LED0=1;
    - O0 \# J2 r3 s( ]
  28.                 GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉低,亮 等同LED1=0;! ^' I# b+ T% D) x
  29.                 delay_ms(500);                     //延时300ms- m& e) ^, c' R# b& q6 G& W1 P* n
  30.         }2 ~" t  Y& p( Z: N, A1 a6 {  ^$ p
  31. }4 Z4 I2 N* K( G3 I3 b) e* \% x, U5 e

  32. ; `. I9 T  z) {; H8 j5 P/ @/ r
  33. # i3 X! I5 A" E. f7 S0 w
复制代码
7 Z8 l& Z8 r" t6 J: O
赞 收藏 评论1 发布时间:2022-4-22 22:00

举报

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

AES加密这么复杂?

所属标签

相似技术帖

官网相关资源

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