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

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

[复制链接]
STMCU小助手 发布时间:2022-4-22 22:00
一、头文件, B0 N+ ^0 A+ W) J/ i
6 u' P1 |3 m0 Q  ?7 a! w: q* u9 G
  1. #ifndef _AES_H: [' u4 _6 j8 p
  2. #define _AES_H) T4 B9 r' h4 z

  3. : o# a+ E9 d4 X" U" D

  4. + Z, J: X8 k  C: N  y4 q/ T1 p, J( o. ?
  5. // 以bit为单位的密钥长度,只能为 128,192 和 256 三种
    - L) h* v0 {! S7 g3 p. r
  6. #define AES_KEY_LENGTH        128
    7 R  f* M5 v) F& ^- X# w- e
  7. - N0 F- v/ y) T
  8. // 加解密模式9 U& q& h: q4 N1 m  {/ j5 g
  9. #define AES_MODE_ECB        0                                // 电子密码本模式(一般模式)
    , ]/ L$ S8 P6 w, r1 i
  10. #define AES_MODE_CBC        1                                // 密码分组链接模式
    # M" n6 d2 m, Y; q5 v
  11. #define AES_MODE                AES_MODE_CBC
    8 X: o, M7 d$ m  n% f

  12. ( B0 h; h7 t( ?: P
  13. % `/ j9 l8 j1 x! J  s/ L/ A
  14. ///; e& ?' J2 _! r  e/ O  ?
  15. //        函数名:        aes_init' S/ B3 S9 h+ @
  16. //        描述:                初始化,在此执行扩展密钥操作。
    / q/ p1 y% @& S& A
  17. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    * s3 s2 i/ ^* Q, r, I
  18. //        输出参数:        无。
    ; |7 T1 h. j( k( G2 G# I
  19. //        返回值:        无。
    9 ]* j  U7 E& W7 H7 I* ^7 g
  20. ///0 F/ f& E, T+ M
  21. void aes_init(const void *pKey);
    , L, ^+ g# z2 H8 {0 r# C$ f
  22. - Q' U4 z$ t5 V$ @$ o
  23. //1 |& _7 ?- W! l5 D' p" C
  24. //        函数名:        aes_encrypt
    . s) k7 ]7 a) u9 U
  25. //        描述:                加密数据& p6 B& U' r; j- n: s9 g$ v# S' M
  26. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。& {- d" M: y; ^
  27. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
      W7 i* M+ F, h% r4 D
  28. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。$ ?$ m. V8 Q, h/ C! ~
  29. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。
    5 o( o& Z  t  \% Q/ s* L
  30. //        返回值:        无。
    - J4 I; E" h+ X. y) j" a- Z
  31. //: R1 |+ _$ J3 L  S; u7 w. x: J/ `2 n/ i
  32. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
    8 W; P+ s/ R$ D$ P
  33.                                  unsigned int nDataLen, const unsigned char *pIV);
    0 n8 m7 }6 G5 M" G

  34. - ?- g" r4 Q& D9 l' W
  35. //  r1 M  f* d" U6 k2 q0 {4 ~8 J9 f
  36. //        函数名:        aes_decrypt) N( C; I4 f) [% r
  37. //        描述:                解密数据
    & s! c% `, Y- C# M
  38. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。% n& T7 `* X/ D# k9 x3 n% l
  39. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。" h( m& r$ y4 q3 R3 n; N
  40. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    * a- A9 O0 d& O4 D
  41. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。6 x' y1 s! o6 G5 U% Q
  42. //        返回值:        无。" B) T- ^: g0 b' e0 [! {
  43. //' N( i! L/ I* e. D+ R6 u/ `
  44. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, * v3 Y0 y; H: d2 d, N' @2 G
  45.                                  unsigned int nDataLen, const unsigned char *pIV);
    9 T6 P% a# z% a$ R/ |6 F: F* X
  46. #endif  /* _AES_H */
复制代码
3 I+ e5 e/ |3 h. v
二、源文件
) u7 \4 g: s- z) I1 x* v
: ^, l* ]/ |' }
  1. #include "aes.h": F$ ^( Y: l% t& u0 @7 n9 g
  2. #include "string.h"% s, N1 n3 `* J7 k6 L) A1 T

  3. 9 X# X+ [5 J/ Y$ L  V5 U
  4. 1 f' t+ f4 Z0 p7 [6 w9 k- i' A
  5. // 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,4 V2 k9 J, c8 B/ g# h- }" s' ~
  6. // 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空
    & A5 J( E3 Q( v" j9 ^
  7. #ifndef __C51__1 O9 n* f% z8 @  _4 s+ \4 T
  8.         #define code8 H- T9 L) C% G' v
  9.         #define data5 q0 F8 T0 c- z
  10.         #define idata
    7 P/ e; x& B* o% n$ ~+ x7 z
  11.         #define xdata$ w- m. _" P& C( _
  12.         #define pdata
    + ]4 }2 b' m7 e1 h6 \
  13.         typedef unsigned char BOOL;: O6 w  n( c5 U/ A8 y- V  G
  14. #else) Z1 @8 Y& L- v6 x9 P( N$ m: L
  15.         typedef bit BOOL;
    0 g' {) z5 |6 N- ]( Y4 Q
  16. #endif6 B" Z' q! h+ ], ]5 h& r( e

  17. : _4 l# g* }5 Q
  18. #define Nk        (AES_KEY_LENGTH / 32)                // 以“字”(4字节)为单位的密钥长度
    6 J5 {- o5 T. f
  19. #define Nb        4                                                        // 以“字”(4字节)为单位的加解密数据块大小,固定为4
    . G/ x6 `* _5 L- r: Q6 Z8 C8 z

  20. # {+ O- X! n1 X  W- S/ O0 P0 S! g
  21. // Nr:加密的轮数
    , e# P( H: q; f8 Z1 W& A/ n
  22. #if   AES_KEY_LENGTH == 128. h2 `2 `( e- e
  23.         #define Nr        10# S& ~0 v* T$ A1 T' S7 c1 t' }
  24. #elif AES_KEY_LENGTH == 192
    3 _" b' k" i5 G0 ^1 E
  25.         #define Nr        12. p. i) B- j, S3 L% c2 P; t! M
  26. #elif AES_KEY_LENGTH == 256
    8 @# M# t" S8 T* p# |+ G9 A% d
  27.         #define Nr        14
    " h; @3 S- x0 {
  28. #else. w( z) l3 w# }* ~
  29.         #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
    0 k' W8 H6 _* }4 D5 `, N: w% T. q
  30. #endif
    - Y" d" Q5 |( E. P5 ~. C
  31. # X6 X% X7 x& m7 G, L8 j$ `, P
  32. // GF(28) 多项式$ n# n. e' s& e9 L/ Q
  33. #define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).% b2 H, i8 f" b5 G
  34. . Z0 E8 t$ g5 n3 b9 F: `
  35. /*****************************************************************************
    9 P' G0 c& E9 V* N9 U
  36. *  Typedef  Enum                        枚举定义
      W5 j+ |3 X* A7 S  \6 e# P0 e
  37. *****************************************************************************/( U* m, G) w. J6 ^; t

  38. 6 C6 S* ]% o( P6 X- u2 ]
  39. /*****************************************************************************
    6 u  K( M' }- H9 m  k0 i, u& F# M
  40. *  Struct                               数据结构定义
      d* j) d9 m' m' A+ k# U4 V
  41. ******************************************************************************/& K9 `/ o6 i+ ?3 V% E/ q
  42. 7 A& v0 s3 O7 z# L8 F1 h4 t* b& Y

  43. ; ^5 |# L1 m& S
  44. /*****************************************************************************7 [& K) }" S: B4 p
  45. *  Local variable                       局部变量
    % c! E9 w& k( E& |
  46. *****************************************************************************/+ w  ?6 b2 Q$ A" ~0 n/ O+ T

  47.   D# T  E# b- X( m
  48. // AES子密钥表,当密钥长度为128位时,占用176字节空间
    4 T% B$ N- z: q6 @/ A+ m
  49. static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
    + G! f8 K/ ^7 a: a) _2 l: f
  50. # I- k9 N. G0 n9 Y
  51. // 加密用的SBox7 J) g; _0 c6 e1 O
  52. static code const unsigned char sBox[256] = 3 H' L/ l9 y, q* i6 ^$ X7 Q
  53. {! x0 _! q, Y$ ]3 F' B
  54.         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,9 j( g" b1 L" f0 F
  55.         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    " b. k( ~3 y  E, o& k" ?
  56.         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,. T' E1 n4 Q! k2 a
  57.         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    + x- Y( G9 |% [* i
  58.         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,  x+ L" _; K! O
  59.         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,8 _, S) k9 e" `- n' v
  60.         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    $ c- H( {1 d) y# o: Y$ A
  61.         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    $ `$ r) w% S3 c; _( j! C% }
  62.         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    , j5 E0 X7 t( E
  63.         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0 d* @9 |, U% n& C# O& p
  64.         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,# U/ D" d% t, S% Q6 f
  65.         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,+ o2 b5 x; j9 M4 M8 \, W
  66.         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0**, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,$ P  J1 M6 E  _! ^, @
  67.         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,0 ?; D- l' V8 W. m" f
  68.         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,6 u: U2 A; u4 V. i0 g6 x2 q
  69.         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 4 n7 y$ E3 |7 R* D1 u3 L! r
  70. };& \8 `3 u8 n6 ^
  71. + f' b: U: _; Z9 W, b
  72. // 解密用的SBox
      I2 J8 W! v  \8 y* }/ @+ {2 _
  73. static code const unsigned char invSBox[256] = - N8 @) n6 r' r
  74. {
    ( {! a2 [- O; W3 Y0 C
  75.         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
    6 x, n& G3 O. `! z& M1 l
  76.         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,2 o, g3 {8 q& H
  77.         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
    - Z& r* D8 c1 I5 W+ L( W
  78.         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
    / H6 n$ P, }* L
  79.         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,0 ~: z5 `; A* l* }
  80.         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
    ( \( Y7 X$ U1 ?+ g" n% E" \7 J
  81.         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
    , {4 K) ^! F9 b7 X
  82.         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,. R: q8 n; G. T8 d9 `$ w
  83.         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,/ N" b4 O) x; F" t2 K( U8 y) y
  84.         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,5 k  D2 V! n8 H* h/ M
  85.         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
    # t, V. h% u9 a- n/ g8 x8 e
  86.         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
    + E4 T" V. M( K: l6 ^
  87.         0x1f, 0**, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
    8 Y6 m# l# o0 Q4 o" W
  88.         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef," y1 C: L0 M! K7 V+ X# n
  89.         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
    : V0 l2 d- C# B/ b! T* |- d) A
  90.         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d        
    3 U8 W3 q2 n2 b) k7 Q( |* M4 m
  91. };
    2 H/ l5 ~& D/ I% j7 _
  92. : t" d. T, v! Z
  93. % M% y1 l" Z" l" p7 x
  94. ///
    4 _! Z) w6 G% W- x, h( A
  95. //        函数名:        rotation_word8 K0 Z- P6 d! D" i
  96. //        描述:                对一个“字”数据进行循环右移。
    # k& m2 h8 J* t! z- g  t- q, f
  97. //        输入参数:        pWord -- 要右移的4字节数据。% x9 U# v  x# i+ n: i8 v. D
  98. //        输出参数:        pWord -- 右移后的4字节数据。
    - w$ \6 O5 n* Y) a1 ]" D
  99. //        返回值:        无。/ p. f1 P9 ?6 c- v0 y+ d1 s# S
  100. ///
    1 p- |& X/ P, a7 X) u1 q
  101. static void rotation_word(unsigned char *pWord), s: N$ z: b& ?- U5 Y
  102. {) y" Q) ~) }3 v! x2 d3 E
  103.         unsigned char temp = pWord[0];
    8 L/ ^1 _3 K1 x- O
  104.         pWord[0]  = pWord[1];
    ; _( \& y, U* N7 m* d2 e
  105.         pWord[1]  = pWord[2];4 z: x7 O' P' w1 b$ [
  106.         pWord[2]  = pWord[3];. M  g6 `! {7 w' f6 S& @8 G
  107.         pWord[3]  = temp;
    0 ~- j  T; O6 D: O. S# @
  108. }# d" i' {1 p# X  ]
  109. & f3 ?0 g# b$ f5 @2 u% t
  110. ///& }9 }+ u0 T* k, @1 _
  111. //        函数名:        xor_bytes( u- K8 C. n; Q6 {: B
  112. //        描述:                批量异或两组数据。
    2 i/ E; K: C  ~' h: i5 R; o6 A
  113. //        输入参数:        pData1 -- 要异或的第一组数据。+ R) |; G$ {! J) `% K/ A  v" C
  114. //                                pData1 -- 要异或的第二组数据。  Y' h" y9 f1 k4 u/ T: j
  115. //                                nCount -- 要异或的数据长度。; e8 W$ i( E/ y$ ]  A6 J% Q
  116. //        输出参数:        pData1 -- 异或后的结果。* W3 B5 @" L, R, @" C% |! X, S
  117. //        返回值:        无。+ U! I0 _: u/ h( L' w
  118. ///& c9 B+ P( {9 F' K( p& n
  119. static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)
      I, I$ Z$ ?5 ~+ P) Z
  120. {9 y" z  l: B& p6 j/ U. U8 B1 Y; o
  121.         unsigned char i;
    : i8 `8 S" K. [- `
  122.         
    . n6 B% k6 q+ [6 n: j
  123.         for (i = 0; i < nCount; i++)
    $ `5 a6 K8 W1 s/ q: z! U# R& V
  124.         {2 j& g5 f/ B$ I4 M
  125.                 pData1<i> ^= pData2<i>;* M3 L' m5 `/ N9 F% M0 R( o4 k
  126.         }3 E+ u, w& j  N: Y1 [6 u* y* @! B: Y
  127. }$ v( _' ?  v% d6 B- F+ k) P

  128. 7 M4 y: p; Z5 Y, j. K
  129. ///# G6 k* l5 E, _% \$ D
  130. //        函数名:        AddRoundKey
    2 }, }1 O) B5 M) U$ p
  131. //        描述:                把 中间状态数据 加上(异或)子密钥,数据长度为16字节。; {9 d* o8 T) v$ i( b7 p
  132. //        输入参数:        pState          -- 状态数据。
    7 D0 z7 g+ G8 m$ |
  133. //                                pRoundKey -- 子密钥数据。, t. [/ g5 F# I" [! M( D
  134. //        输出参数:        pState          -- 加上子密钥后的状态数据。
    7 G* t6 d$ _5 c/ M3 }( ~3 T3 F
  135. //        返回值:        无。$ K9 _5 l- d2 F) ~  q
  136. ///3 X# w, q$ c7 K
  137. // static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)" z1 q/ W6 V5 P& ~) R. \7 L( N
  138. // {0 A7 n9 W9 Z- d; A4 e% {6 h
  139. //         xor_bytes(pState, pRoundKey, 4*Nb);+ i% J, V# \: Z
  140. // }. Y; C* J3 i% W! P' |
  141. 1 i  o. C$ ?1 @$ f, _9 K
  142. // AddRoundKey的宏形式,比函数形式可以节省4字节的data数据
    1 G, ^, a' X3 w- c* |
  143. #define AddRoundKey(pState, pRoundKey) \
    4 {% q! z6 I$ ^6 j" e. p% m9 I3 \
  144.         xor_bytes((pState), (pRoundKey), 4*Nb)
    ! z& Q! H& t) x# t8 @( L0 Z) ?, N

  145. # M- n- O: [& t( B7 }0 D

  146. - J* R# T7 [# T# }! c. t7 F
  147. ///
    ; O' J  U1 Y4 @0 @, p1 j% Y0 Y* o
  148. //        函数名:        sub_bytes
      `# u9 e3 w4 F! z) ]  {
  149. //        描述:                通过S盒子置换状态数据。. H) S, j& r3 U% B1 ~( s
  150. //        输入参数:        pState        -- 状态数据。
    2 Q  M2 b4 Q, c/ F; G' ]
  151. //                                nCount  -- 状态数据长度。2 W' I2 _0 w, `
  152. //                                bInvert        -- 是否使用反向S盒子(解密时使用)。; b2 d$ ^, g" `! g& Z
  153. //        输出参数:        pState        -- 置换后的状态数据。
    1 M8 ^" R# i6 Z% ^3 b% N. }* i
  154. //        返回值:        无。" |( R; y% G( X3 O0 s4 F. j4 r
  155. ///% ]+ G- w5 Z9 H6 Z/ A
  156. static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)
    ! t/ x7 ~% y2 M* C' n
  157. {) {6 `1 U0 s) [1 ]7 B+ l
  158.         unsigned char i;
      {; o# N! z; t  V1 a
  159.         const unsigned char code *pSBox = bInvert ? invSBox : sBox;
    ( c! i/ q  R1 _( u
  160.         
    + l5 l2 r" j, B! C" }. i+ @+ |
  161.         for (i = 0; i < nCount; i++)
    2 F, L: t+ {# w: S5 r
  162.         {1 o% p! u0 B8 @
  163.                 pState<i> = pSBox[pState<i>];
    ) L# A( ]4 p% u8 U
  164.         }/ j; t& d( e: W* W/ q& m
  165. }
    6 \, _) M  |# s0 M1 g8 x; U+ Z" q

  166. 6 {/ K; k! C/ E/ Q8 N; f
  167. ///4 d2 {/ s( E8 \8 N; v# Q$ U  I" A
  168. //        函数名:        shift_rows# X6 x6 J) a# g, h) d
  169. //        描述:                把状态数据移行。: ]2 k/ _; `* q& u
  170. //        输入参数:        pState        -- 状态数据。
    2 l5 y7 }( e. f& _& `/ C$ E! t
  171. //                                bInvert        -- 是否反向移行(解密时使用)。
      _, O1 T: C+ B8 t3 Y! H) t" ?
  172. //        输出参数:        pState        -- 移行后的状态数据。
    9 J2 O% z& Y6 O5 }8 @* P! ~) ?
  173. //        返回值:        无。
    ; S9 }7 o( i( p9 I- T$ y3 \* B
  174. ///
    ! K1 I9 h4 j: p- r0 Y% y4 N
  175. static void shift_rows(unsigned char *pState, BOOL bInvert)8 w* l  a, f" Y, ^+ [: Z
  176. {# U7 _: x2 Q9 q; _
  177.         // 注意:状态数据以列形式存放!
    " r2 c5 Z% \/ @5 u

  178. * E5 U% ~: I+ `4 d
  179.         unsigned char r;        // row,   行  g, Z- Z  V" A6 c0 ?1 ]
  180.         unsigned char c;        // column,列6 F0 K2 M( y+ U- o7 ~, G* u5 d+ E
  181.         unsigned char temp;
    1 H8 H7 s2 v! x8 z9 y- M# A& C7 t
  182.         unsigned char rowData[4];
    / i: U$ H: m$ T  e* z2 y2 N  Y
  183.         ; T' m: \1 P, T! {! o, O
  184.         for (r = 1; r < 4; r++)
    3 x4 H- R* c5 U; E
  185.         {
    + h  Z# O9 ^5 P" O) l1 \
  186.                 // 备份一行数据
    ; _* a1 ~8 _$ F* I7 J1 u
  187.                 for (c = 0; c < 4; c++)5 a2 O9 J9 g  W6 D
  188.                 {- m5 B3 n) H  n( A* y9 E5 ~
  189.                         rowData[c] = pState[r + 4*c];
    % [9 x) y7 e, G5 b
  190.                 }
    + {" L7 k6 Y8 x0 l- a5 u% ^
  191.                
    3 e) x; ]& M6 `
  192.                 temp = bInvert ? (4 - r) : r;  s7 v, M  l: V' p
  193.                 for (c = 0; c < 4; c++)! M7 ~( ]" C3 G  T
  194.                 {
    6 I$ H$ Q- j$ r( c( d4 Z+ d
  195.                         pState[r + 4*c] = rowData[(c + temp) % 4];
    8 R5 ~. p" S) h* y  r1 [
  196.                 }
    ; |  Z- M2 H! g
  197.         }1 v, l1 g; S. `' }  c$ q
  198. }
    ( G& v. w& S; ~. S+ n" I
  199. ( |8 l4 I9 g  t2 b- [; t
  200. ///
    * ^2 C7 ?4 j$ q1 P  w0 X4 S
  201. //        函数名:        gf_mult_by02( A6 u, d7 h; i+ c2 z
  202. //        描述:                在GF(28)域的 乘2 运算。4 U* d5 @/ E, ^4 w6 k  d' d/ _7 p' G
  203. //        输入参数:        num        -- 乘数。% l8 D6 ?* u8 Q4 I5 |
  204. //        输出参数:        无。. T' M- |" h8 k4 n4 ]" _& L
  205. //        返回值:        num乘以2的结果。
    1 R) d1 w; i1 E& _0 X
  206. ///
    ) Y: z8 A6 p5 Z1 n1 }. T
  207. static unsigned char gf_mult_by02(unsigned char num)( m$ U% q9 @2 _$ o
  208. {
    2 K9 a- n2 [( h& d1 ]
  209.         if ((num & 0x80) == 0): ]9 ?  N# q; k7 r: G& Y  i. @
  210.         {
    ( ~4 f/ {9 M1 t) v/ [
  211.                 num = num << 1;, {" [. S1 X  R$ u0 ]( V
  212.         }* l2 w. j  Q" V
  213.         else
    3 Y) G* J+ K. ^- J5 Y$ U2 I$ P7 g
  214.         {
      C9 D! `( E5 {  Q# j" R- C
  215.                 num = (num << 1) ^ BPOLY;
    5 D0 o% k- S: s- i7 d. I
  216.         }" b" R  m$ Z+ n
  217.         * j( S* P2 D" o  p
  218.         return num;  J# p( V3 P$ A: \
  219. }& K+ H* s9 `3 n
  220. 8 O4 k" Z: p+ ]% h- X
  221. ///
    , O3 J; v& q, }
  222. //        函数名:        mix_columns, j. e2 U( k4 ]7 j- U
  223. //        描述:                混合状态各列数据。
    # l" `  U6 R/ T8 P" _4 H: ]
  224. //        输入参数:        pState        -- 状态数据。
    ) o. r% I% ~4 f4 n+ E& l
  225. //                                bInvert        -- 是否反向混合(解密时使用)。: I8 r( \; L: o
  226. //        输出参数:        pState        -- 混合列后的状态数据。7 C% O# p3 j# g  M1 v
  227. //        返回值:        无。
    6 u/ Y7 O, J# F+ M; [5 Z
  228. ///, L9 @' B3 J! y' R# g
  229. static void mix_columns(unsigned char *pState, BOOL bInvert)
    5 e1 x8 S  ~3 F4 A; S3 P2 A
  230. {
    $ e* G4 l" K" K7 v. J8 p
  231.         unsigned char i;
    5 Y( Q7 D' i- u  o3 i) t" A! Q9 a
  232.         unsigned char temp;6 P' ]8 ]. b) a$ I
  233.         unsigned char a0Pa2_M4;        // 4(a0 + a2)2 m" t4 G; p6 E) q9 x
  234.         unsigned char a1Pa3_M4;        // 4(a1 + a3)0 n  b% k$ E5 a; d
  235.         unsigned char result[4];
    - g. v$ d% ~) k7 @0 x1 o

  236. ; b, d" Q# v( u! c! {# r7 t) ?/ Y
  237.         for (i = 0; i < 4; i++, pState += 4)- T- ?6 B3 t% F/ K2 l- @9 n% {& Q
  238.         {
    0 k: I( }+ H" h& Y( R. {4 `
  239.                 // b0 = 2a0 + 3a1 + a2 + a3
    * K6 I6 i$ j" x' _8 Y
  240.                 //    = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0! a( H8 L3 ?# R( x' ?
  241. 7 }8 ~# w4 d: K
  242.                 temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
    / E% Y$ a" e+ P9 |
  243.                 result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));9 s  l# s; i) ~  f) `) `
  244.                 result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
    4 ]% ?% H, d- B( B5 S7 {6 D: F2 d9 |
  245.                 result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));' K, z2 d, P& [6 S
  246.                 result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));
    & I; o9 V8 y9 G8 w* K

  247. & e! s& M3 `( l
  248.                 if (bInvert)8 G  F- @* v6 a. Y4 I
  249.                 {
    * _3 G- Y! H  K
  250.                 // b0' = 14a0 + 11a1 + 13a2 + 9a3
    * O7 I1 Z4 h# N
  251.                 //     = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0        (这部分为b0)1 K. R  l: z  b! u: m6 Y: I
  252.                 //       + 2(4(a0 + a2) + 4(a1 + a3))
    $ d' ^2 b! m$ M/ |. u
  253.                 //       +   4(a0 + a2)
    2 W+ ^, e5 \  D2 k
  254. ) Y/ [2 H9 Q3 }* B; i* z+ ?( Z
  255.                         a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));4 U/ O! g3 y$ {8 b, k2 R; s
  256.                         a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));5 y% W9 |1 R: l
  257.                         temp         = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));
    & k  c$ q1 H7 d. r
  258.                         result[0] ^= temp ^ a0Pa2_M4;4 R6 p, A- q& l' h
  259.                         result[1] ^= temp ^ a1Pa3_M4;3 S5 x5 U$ ]" F* a- a1 s! V- M$ ?
  260.                         result[2] ^= temp ^ a0Pa2_M4;
    7 A1 T: x+ V( I) k- k4 _# g
  261.                         result[3] ^= temp ^ a1Pa3_M4;
    & i0 E5 J' S1 K2 d- s
  262.                 }. K( [0 F( O/ ]

  263. 6 Q$ `" d+ b5 p2 i$ X2 F( k
  264.                 memcpy(pState, result, 4);
    8 Y& q: A# D# o; }9 s/ P4 p
  265.         }5 M' Q7 }9 M, a* Z; n. F
  266. }
    " B! T! i( D" k
  267. * v7 H! M0 l% z! x
  268. ///3 c; }/ C+ r/ {, j: F  x
  269. //        函数名:        block_encrypt
    . _& f4 g% N1 T$ w
  270. //        描述:                对单块数据加密。. |6 _/ {5 X$ U2 l
  271. //        输入参数:        pState -- 状态数据。+ f5 T2 M0 g; f# C9 q+ t- {7 U
  272. //        输出参数:        pState -- 加密后的状态数据。+ d& `4 P# f* }
  273. //        返回值:        无。
    " D8 }: O( F7 \& b# a( M4 R3 H# d+ [
  274. ///
    7 A, |& x, R0 b# W) z! n9 O, Q
  275. static void block_encrypt(unsigned char *pState)
    - ]- o7 ?/ K1 f' w
  276. {& R& G& L6 n" Y0 c
  277.         unsigned char i;
    3 K+ ^- u6 x4 ^' ^4 Q2 B
  278.         
    1 \: t6 ]; Q. B* m* G
  279.         AddRoundKey(pState, g_roundKeyTable);8 m# \4 x) J- m+ b
  280.         : j: W; f- F% D1 W5 d
  281.         for (i = 1; i <= Nr; i++)        // i = [1, Nr]
    4 k! u+ z! c# J( P# q. F
  282.         {
    1 A( J, z, X, M3 Q  f/ V  Q
  283.                 sub_bytes(pState, 4*Nb, 0);
    8 I/ ~6 ^' b5 Y( u5 ?( ?7 M
  284.                 shift_rows(pState, 0);, p# {  V, H7 F
  285. " f8 M5 T; `* S1 w
  286.                 if (i != Nr); k  \' E" B6 G
  287.                 {) m7 ^3 H  o. }
  288.                         mix_columns(pState, 0);/ e! L, v, q! L- F
  289.                 }+ k/ G( [' `. x! I: [& r5 l
  290.   H. m8 |2 f0 Z6 ^% x
  291.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);2 }. E% H) ]4 r5 Q+ j- S
  292.         }: N9 q! [& y* B% u$ _- L
  293.         5 D2 g  a* I1 V; g# u* u- K* l
  294. // 为了节省代码,合并到循化执行& q8 G, J8 J, P0 n/ V
  295. //         sub_bytes(pState, 4*Nb);
    5 c, X2 r8 r+ J" K1 }
  296. //        shift_rows(pState, 0);5 L# |; a: u3 {. D
  297. //         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    + B3 U4 V2 V& `+ N9 d% B8 t$ t
  298. }
    2 I! X" A5 I& ]) X' y" x. L

  299. 2 Y) B! X' Q) ~) ]
  300. ///
    ; G$ p. K; N9 K5 M8 _
  301. //        函数名:        block_decrypt
    # W; Z( K9 A6 |0 L/ }
  302. //        描述:                对单块数据解密。
    " C3 w, ?/ i" S
  303. //        输入参数:        pState -- 状态数据。9 r/ c' }- W; G- R. y
  304. //        输出参数:        pState -- 解密后的状态数据。
    * M0 N1 H6 o5 }( Z) S
  305. //        返回值:        无。
    ) }5 [" S. P7 R# @3 {- A
  306. ///: I3 S/ o' I7 c2 |8 C0 Z% R6 k
  307. static void block_decrypt(unsigned char *pState)- ?- _* u# C, s4 ]  M! h5 q
  308. {$ T) Z1 u: ]# J  o  S0 `/ J6 [6 Z
  309.         unsigned char i;. o: J8 j% q0 ^* C
  310.         : t  r: u: m, e9 v) G* u' l
  311.         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    ( r5 h8 P: x9 K, z* G
  312.         ; m5 ~. I' Z. n( }) J. M
  313.         for (i = Nr; i > 0; i--)        // i = [Nr, 1]+ G+ ]% c- y1 _1 u, ^# E
  314.         {
    2 @1 c, a6 M3 F5 j4 n$ X% H
  315.                 shift_rows(pState, 1);
    4 I2 W) P, V5 t0 @8 U2 c- `* [
  316.                 sub_bytes(pState, 4*Nb, 1);) H# ]2 t5 @* m, x
  317.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);8 n: o- ~0 X7 F) k0 y) J2 j

  318. ( |% Q  f5 D2 j$ [4 q! T' V% m3 v
  319.                 if (i != 1)  y5 R: g  e, m" ?: Z, t" ?! t2 V8 x0 G
  320.                 {% G0 X' W( O2 E  J
  321.                         mix_columns(pState, 1);6 I. ~, k, M+ z3 ?$ E, s* a. R0 ?, T. O" L
  322.                 }
    " _3 N, L" _2 T5 w
  323.         }2 U4 t0 [1 H" z9 ?
  324.         
      `$ g( Q9 Y$ q; g1 J
  325. // 为了节省代码,合并到循化执行
    4 g, K' W* C& C0 B; i0 _
  326. //  shift_rows(pState, 1);8 [. b( o4 H8 W7 `
  327. //  sub_bytes(pState, 4*Nb, 1);
    9 V& t8 s9 \1 s/ I, D  ^
  328. //  AddRoundKey(pState, g_roundKeyTable);, G+ T* Q6 ~9 B# \1 Q
  329. }/ Q2 @6 W: _- V. j4 l: @
  330. 1 N0 Z. \% D) |1 @* E, X8 {* l/ D, k
  331. /*****************************************************************************
    6 e- P8 w9 W9 \; K2 w4 J. X" s, M- Y
  332. *  Global Functions                     全局函数% V$ o) Q. p: K' x6 Z
  333. ******************************************************************************/
    , y6 y8 l5 j# v* Z" j0 g; z

  334. : {( M3 N# \. o, |3 N8 K
  335. ; o% i) N; a$ E. H4 N' k4 {; H
  336. ///
    7 [7 `, A1 j7 s8 H
  337. //        函数名:        aes_init0 b' q, j+ f+ p3 q7 Y& Q
  338. //        描述:                初始化,在此执行扩展密钥操作。
    # O$ q8 p0 \, }8 l
  339. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    : A" [+ S$ @6 i8 c
  340. //        输出参数:        无。
    4 ?* n& [3 n# U" _+ B. A! i
  341. //        返回值:        无。" E& K% I. x& {7 O
  342. ///
    9 F- x  S* f( s9 W/ U4 @+ ?
  343. void aes_init(const void *pKey)
    $ |& M( q4 |0 N& Z4 T5 i
  344. {
    $ g! D1 w) s" ?
  345.         // 扩展密钥  f' k: ?/ p, G
  346.         unsigned char i;
    $ F5 v1 r* J3 Q/ ?9 F# e6 O) r0 R
  347.         unsigned char *pRoundKey;
    . Z/ i: o4 L& r% T: s  Z( ], D( I3 \$ q
  348.         unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
    5 F: w# w& O' @9 M6 `

  349. ) J% m! x- T7 h* Z
  350.         memcpy(g_roundKeyTable, pKey, 4*Nk);
    $ [6 x! R+ _4 J1 Q1 U
  351. 9 z& T) q! Q/ M( O  B
  352.         pRoundKey = &g_roundKeyTable[4*Nk];
    & _; R( b, Z4 Y6 J  v
  353. # C. v4 Z3 \9 h$ g/ t; n- s
  354.         for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)% e- r% |' T1 V4 \: p" ]+ j" M) u
  355.         {
    9 V2 a: z% k0 j! s. j; i1 `
  356.                 memcpy(pRoundKey, pRoundKey - 4, 4);" M, g6 A) _" P% |$ _8 f: J& C

  357. " `' y' {" [- ~0 ~
  358.                 if (i % Nk == 0)( b2 O+ V' j' P
  359.                 {
    ) O: k% I9 s9 `9 B% t7 [4 p
  360.                         rotation_word(pRoundKey);0 t% ^- ]' C0 m, V/ C
  361.                         sub_bytes(pRoundKey, 4, 0);" j$ p5 t0 C! |/ `8 L7 z5 I8 ?1 j
  362.                         xor_bytes(pRoundKey, Rcon, 4);
    7 k- a0 V) W7 F4 F

  363. 3 b* z" p* x& [) H0 J! i, a" `" [
  364.                         Rcon[0] = gf_mult_by02(Rcon[0]);
    2 m3 y8 h) f4 {5 f3 p" z
  365.                 }
    * b% m1 ]5 y% W- t; R; C& M
  366.                 else if (Nk > 6 && i % Nk == Nb)
    1 E0 j- R8 P  p  |4 q: @/ c
  367.                 {
    4 y6 W8 \4 ^4 d! A( b% A9 W+ k6 f  ?
  368.                         sub_bytes(pRoundKey, 4, 0);; l2 |  _3 G" B3 {5 p3 y) |
  369.                 }4 H8 @' \9 f9 Z
  370. , b/ C5 @9 P: j- d5 z# o
  371.                 xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);
    ; F4 ^" Q+ N( k
  372.         }
    4 S! m. g  h1 Q8 k9 n5 g# {
  373. }
    7 V* s1 ~. T5 S! }2 M
  374. - X7 J* Q3 z3 t
  375. //
    ! h9 h, |1 F& S) _' b) j( [; X/ M
  376. //        函数名:        aes_encrypt6 u# e( M- ^( }2 v( i* w& |
  377. //        描述:                加密数据
    % X6 c3 a# U9 h" x
  378. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。( H9 v/ N3 C1 {" F8 A9 z) h( m
  379. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    4 r) `% K4 `4 S
  380. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    ( `! D) c; Y3 ^+ C9 E. H4 p. `
  381. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。
    ! H, Y& L  C! f2 f/ P& r
  382. //        返回值:        无。
    . s( c( R/ Z- [
  383. //+ j* r1 x+ M: e
  384. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText, - \1 P' t+ h6 H4 S
  385.                                  unsigned int nDataLen, const unsigned char *pIV): T% S# @- R& |- ^7 d: W! G
  386. {
    - \) E/ G2 Q7 d( i  D
  387.         unsigned int i;
    2 ^6 o& @: x+ g/ Q) \6 u8 F% s
  388. : s7 F; b" Z/ y% H4 f
  389.         if (pPlainText != pCipherText)
    , ^% x# |9 u5 k4 q; k$ J7 }
  390.         {9 k4 p/ q7 q7 G; r1 e9 ~- [
  391.                 memcpy(pCipherText, pPlainText, nDataLen);2 p# O. K9 w2 l0 B+ O
  392.         }% b% j. [# H8 w$ M0 F7 V0 c
  393. 5 x5 r7 e2 T& w  N/ J
  394.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)! u1 H# s* |2 m
  395.         {
    # M9 E# y: G4 b: a' v6 }
  396.                 #if AES_MODE == AES_MODE_CBC" q, V3 ]& ]4 m; ]1 e2 I! U) ~
  397.                         xor_bytes(pCipherText, pIV, 4*Nb);" s# O7 h- t( `1 J; k/ u
  398.                 #endif
    ( M  X3 \$ e8 h) W' m1 u

  399. & k) \/ o" I5 t# I9 q0 U5 `
  400.                 block_encrypt(pCipherText);
    6 W' [- m: p! }1 m$ U
  401.                 pIV = pCipherText;8 P* d' c* e, Z3 j5 U- j- M
  402.         }, h3 x' F. `( u- G3 b
  403. }
    / S$ l& k6 p2 c6 L# O4 d

  404. ; k. U& T0 F. V% o
  405. //
    * }( M4 ~  E) q( A8 D6 _8 V4 ^
  406. //        函数名:        aes_decrypt7 ^( [* p# E. m, n/ K4 s
  407. //        描述:                解密数据: L1 }$ o( `8 a3 t% a7 B
  408. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。2 c/ x8 C2 j! S+ z8 ~! X, ?  l
  409. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    ) P$ A0 f8 k6 d% n
  410. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    * X# N. A7 u6 |: ]! p7 I* F7 E
  411. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。7 ~% D/ D: ?; S/ P+ S, n4 e7 k% ]
  412. //        返回值:        无。
    + D+ X% m/ J* D
  413. //
    # O& M9 r$ i7 T- L& b  W- y
  414. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
    * a0 H1 k& t/ S$ Z- C# o
  415.                                  unsigned int nDataLen, const unsigned char *pIV)
    1 r& v; ^5 u7 G0 P! ^) d1 O
  416. {
    0 W; @; [. k$ c3 v; w
  417.         unsigned int i;
    + f5 O# \1 Y9 b0 i& s" }

  418. , x! P2 c2 E* f- F, e  `
  419.         if (pPlainText != pCipherText)
    7 K- z- A# z5 b' R' V* h" ?
  420.         {% ?! h# c+ s  ^
  421.                 memcpy(pPlainText, pCipherText, nDataLen);
    ; Q9 J; O. i( Q+ w0 l" U* n# V
  422.         }
    + F1 i5 a, |2 g. M8 t2 Q

  423. 9 u7 a: B9 ~# V* Q# N: P/ N
  424.         // 从最后一块数据开始解密,这样不用开辟空间来保存IV# s. n/ U1 d" w. D, J
  425.         pPlainText += nDataLen - 4*Nb;, X/ C7 a6 U0 J% K5 C% k3 N
  426.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb)
    / O& e) u  C9 A  Z* L  P0 L% O8 D
  427.         {' A( \! K/ o1 p/ r& S" |* t$ |
  428.                 block_decrypt(pPlainText);
    - J/ h9 q7 F/ Q9 m4 e  X/ S9 U

  429. 3 t) x3 K9 L( w0 h) A
  430.                 #if AES_MODE == AES_MODE_CBC8 M, w# {6 |' H+ h# [8 ^) e
  431.                         if (i == 1)
    $ i# A: t3 \4 \* c- Y0 T) F
  432.                         {// 最后一块数据. ^! k1 {7 M+ K
  433.                                 xor_bytes(pPlainText, pIV, 4*Nb);
    . i. E* f" t1 v2 w, w
  434.                         }
    9 b4 D7 Q  m2 Y" ~( Q
  435.                         else7 [/ Z5 X3 q, o( A$ ~
  436.                         {
      h- F! B1 [. G% z
  437.                                 xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);1 q7 R# k2 \) G1 B3 M4 Z
  438.                         }; ^9 P/ b: R8 M
  439.                 #endif# K' k3 G" }, T9 z$ N  l) p3 I' a1 d
  440.         }7 e6 G3 \' u6 _/ N
  441. }</i></i></i></i>
复制代码

5 d0 j7 Y! c: \三、使用
- X; ^: p. X" S4 @. g0 y使用注意点:: i& g" q4 y) n
1、AES_KEY_LENGTH取值只能是128,192 和 256
4 w2 r8 r1 D/ P& d: J; D+ y$ W+ r2、密钥和向量表长度为AES_KEY_LENGTH/8个字节
* p9 v( ^3 E' F: D9 M+ o3、加密、解密数据长度为AES_KEY_LENGTH/8的整数倍字节
# \: {+ k3 ]& U& s( [) M( o! w0 e' B* u* ~/ R2 r; o+ p. _% k
% n2 [1 s2 Z% u. T* Q4 Z, W8 H
  1. int main(void): A" J2 q) G, _% z; J9 T
  2. {
      o0 D' ~: ^) `# P. e) x( S! G
  3.         u8 buf[16],saveBuf[16],descryptBuf[16];" F( U) W6 O2 G* ]+ L4 {* k
  4.         u16 i;, s! W, v) A1 K  B* u5 `% {
  5.         unsigned char AES128key[16] = "123456789abcdefa";//秘钥6 d  ~. P/ D  r4 V) A8 g) Y3 C
  6.         unsigned char AES_IV[16]= "0102030405123456";//向量表, _3 a8 k9 n# \# g% K3 i
  7.         delay_init(168);                  //初始化延时函数9 N' {0 V. V$ [6 V
  8.         LED_Init();                        //初始化LED端口
    % M; i0 G' B0 a! K0 E: D9 E
  9. - n: b; U2 R1 Z" [" }9 d+ N& n
  10.         aes_init(AES128key);//AES初始化, p+ m/ P6 i  i* I( p
  11.         
    7 m1 |* @3 a8 V# A/ q0 p
  12.         for(i=0;i<sizeof(buf);i++)) X1 k) K- h8 ?8 d$ v( u1 ]1 K2 ^
  13.         {( r2 B5 _+ r, t5 @2 t: _8 t
  14.                 buf=i;4 V6 V8 }  n; p1 b
  15.         }
    : T# _% G( v5 s3 G  w6 x: b
  16.         while(1)" E# |9 p7 {% }9 C$ Y
  17.         {8 n# Y. d4 }( C
  18.                 aes_encrypt(buf,saveBuf,sizeof(buf), AES_IV);$ i* s  L' G+ I! `/ ^
  19.                
    % K9 x( s& T5 F9 N. t+ @
  20.                 9 Y' \2 p9 q) l: U2 E
  21.                 aes_decrypt(saveBuf,descryptBuf, sizeof(buf), AES_IV);
    ! _5 z& @+ Z) S. l
  22.                 7 B% i! @1 m- K8 L( V  w; b: h
  23.                 : d+ r) Y8 Y3 n5 B4 f
  24.                 GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0对应引脚GPIOF.9拉低,亮  等同LED0=0;/ t9 g  o! H1 J) Y
  25.                 GPIO_SetBits(GPIOF,GPIO_Pin_10);   //LED1对应引脚GPIOF.10拉高,灭 等同LED1=1;
    5 r7 s" }0 R1 V3 _  G1 Q
  26.                 delay_ms(500);                     //延时300ms$ e* d% q% Y4 Q" d; D! O" B
  27.                 GPIO_SetBits(GPIOF,GPIO_Pin_9);           //LED0对应引脚GPIOF.0拉高,灭  等同LED0=1;9 o  v$ K; S) h6 i* w3 p( X
  28.                 GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉低,亮 等同LED1=0;
    ! {* q6 G- N- c& E- G( o4 l
  29.                 delay_ms(500);                     //延时300ms
    ( f8 R0 |9 c, u4 m3 G5 h4 H
  30.         }
    * T- x! N8 N- u/ n7 H7 M
  31. }0 R. z  O+ w. n) X0 P

  32. 4 I: a# g5 z* p) D- o# K% ?- M  p: C
  33. ! ^& ?  [1 E5 f8 f- j0 [: \
复制代码

5 p/ y4 ^$ T9 g% k
收藏 评论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 手机版