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

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

[复制链接]
STMCU小助手 发布时间:2022-4-22 22:00
一、头文件
# l9 T4 @  ?0 P/ J
- s9 ^' R5 x! A5 a
  1. #ifndef _AES_H% K+ v; _( E: I" O, f& r
  2. #define _AES_H7 O4 [  `' a+ _. J! P9 p

  3. 0 T2 ~( V- j% @9 e8 A0 p. v: F1 R& B
  4. + p# s& g& C0 O- E
  5. // 以bit为单位的密钥长度,只能为 128,192 和 256 三种
    * k; ]+ m1 Z( G% K. r  A$ M4 f
  6. #define AES_KEY_LENGTH        1288 G+ K( L% O; @: }
  7. . V% _2 E0 N% v0 O3 b( Q9 o6 i
  8. // 加解密模式
    ! V8 y) d% ~0 Y: E+ C' g/ t
  9. #define AES_MODE_ECB        0                                // 电子密码本模式(一般模式)  W* S% o4 r" f4 F" p' S& J" ?6 j
  10. #define AES_MODE_CBC        1                                // 密码分组链接模式+ H" w  V: |# b
  11. #define AES_MODE                AES_MODE_CBC
    # p% K/ X- u! U, K, x

  12. 5 _1 F) Z" o+ v* n) Z

  13. ! F5 W/ ?5 V# h1 p4 D
  14. ///
      ~- u' h) b6 \0 v5 |# `0 @2 r
  15. //        函数名:        aes_init
    : v% j. @* Q' e9 ~
  16. //        描述:                初始化,在此执行扩展密钥操作。) o) q& ^0 Y, o* }' s5 D
  17. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。- o9 d; v' L( t1 S% L; S- p
  18. //        输出参数:        无。" i7 d/ u$ g# c9 S7 j) f
  19. //        返回值:        无。
    ( n+ D% O  n) U0 C! H$ @0 I
  20. ///8 N3 ?5 K5 J5 j/ M
  21. void aes_init(const void *pKey);& ?3 |7 W; @* a
  22. 1 [, ?9 A: D9 J* T- C5 v$ J; x9 X
  23. //
    : i8 V* ]! e5 q8 ]8 M1 H  Y
  24. //        函数名:        aes_encrypt) N% D9 |- t. o( A' r" h& j0 x% L1 b
  25. //        描述:                加密数据5 g' n% c4 a- L6 @2 K, j  B% v) B
  26. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。
    8 Y# c/ r9 Y8 K" j
  27. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。8 t+ O8 ~& }. ?  q' k5 t, e
  28. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    " `- @0 a/ H/ o
  29. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。( ^# I6 J+ r2 Y
  30. //        返回值:        无。2 T8 S8 k+ k8 f- `# V
  31. //
    8 q1 ]% ^( i% i8 S
  32. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,   m. x. {. T8 J( O9 x1 t5 g& ]
  33.                                  unsigned int nDataLen, const unsigned char *pIV);
    8 X& x" R5 h- O* t5 W( v
  34. - h* T0 S5 i  d  s4 `" d" W1 I+ c1 O' K
  35. //2 L3 |  Z2 {: S( k
  36. //        函数名:        aes_decrypt
    ; `5 B3 j$ T* P" z0 ?3 w6 g
  37. //        描述:                解密数据
    0 t' e! M" l" m/ S
  38. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。% W) l! J7 y! A8 @2 U
  39. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    - l/ e2 V: d: f; R0 ]7 p
  40. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。
    9 x- F/ B* K, v# m# Q/ }
  41. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。
    * `& u9 |7 C- T4 Y0 r
  42. //        返回值:        无。, F# o6 T2 K' w4 Q+ r/ D- E
  43. //
    " \* G; d5 g4 `: I0 t% }8 l5 T
  44. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
    $ N+ ^) Q, y3 u5 Q2 r
  45.                                  unsigned int nDataLen, const unsigned char *pIV);) C0 K4 m& k7 x
  46. #endif  /* _AES_H */
复制代码

) l# @0 |$ B' Z- f  O二、源文件7 j  q& j# f- v  I- P
' ~$ s4 T+ K1 Q* W" l  s& J* u
  1. #include "aes.h"6 V9 C2 ]5 z: \7 S- A' ~
  2. #include "string.h"3 c' Q4 w1 u0 ]- E+ d/ d" I0 J5 Q( R
  3. # K  ~8 ^) C3 I
  4. - m3 A7 B* Q9 {) Z% n1 d
  5. // 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
    % S' z% ]5 ]$ D5 m
  6. // 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空: }/ C1 `' K# a+ L( }/ o
  7. #ifndef __C51__
    - {) N- j/ x  |* z
  8.         #define code; r3 I# f4 L& y- i, h# F1 j6 L) Q
  9.         #define data. M& _, L9 i  w5 ]/ ?
  10.         #define idata) ]# D: |$ U. K3 x( F; M
  11.         #define xdata
    7 [3 u/ j# z$ B0 ~" P
  12.         #define pdata
    8 A" z) B9 X( W5 Q
  13.         typedef unsigned char BOOL;" y- |; e8 v  W) R8 J
  14. #else
    ! x& c+ H  c% _+ x
  15.         typedef bit BOOL;
    " t; o$ {* B! J
  16. #endif6 p5 F3 l* q" g
  17. 4 @* }! ]& r$ h% {9 j
  18. #define Nk        (AES_KEY_LENGTH / 32)                // 以“字”(4字节)为单位的密钥长度
    & f1 ~+ ]- @% z# z- @& Y% S" r
  19. #define Nb        4                                                        // 以“字”(4字节)为单位的加解密数据块大小,固定为4
    " \- U, d& g  P! l) v4 q0 }7 T
  20. ( L7 G% ~9 t8 U2 U
  21. // Nr:加密的轮数
    : h; z: R: s! Z! _/ O6 J( K" @# \
  22. #if   AES_KEY_LENGTH == 128* a+ S+ ?0 G% M3 J
  23.         #define Nr        105 U- }  F* u0 L- w" k+ M2 @( n
  24. #elif AES_KEY_LENGTH == 192  S- B% }* r$ L1 U* W4 d; [
  25.         #define Nr        12. T3 ?) G* H6 E/ e
  26. #elif AES_KEY_LENGTH == 256# j6 q: q6 m0 y4 I. M# {
  27.         #define Nr        14. i9 U7 ~$ t  r) C% f" F, C- L  ^
  28. #else
    5 v( N8 U/ B* s- |/ z
  29.         #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
    9 G- F2 ?  `8 C0 t/ A# d; r0 c
  30. #endif
    ! [8 O  g& Q9 x8 O
  31. . A* h3 O) s# `5 l6 _* s
  32. // GF(28) 多项式
    , [' c2 m; U" \7 g6 J1 k
  33. #define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).- T9 J0 J( A4 J; s

  34. ; |: r9 d& U* E9 X! ^4 F
  35. /*****************************************************************************
    9 P. N$ ~2 V7 ~2 b
  36. *  Typedef  Enum                        枚举定义3 X: E! `7 Q% I( y1 }8 q( r
  37. *****************************************************************************/
    / o6 b- E+ c# O# q& }: B& j

  38. 0 A) Y7 z! G% h6 L1 s& N
  39. /*****************************************************************************
    3 C8 N" ^# a- T% V; q& ^( [
  40. *  Struct                               数据结构定义
    / Q5 d# y2 b% ?& y' b
  41. ******************************************************************************/
      P" n3 C4 ~  }. h
  42. , e. j0 U8 c7 V
  43. ) o" E% t- M9 `/ @% J
  44. /*****************************************************************************- ^- L( y( c9 j3 g
  45. *  Local variable                       局部变量
    ; r) M0 A$ D5 k1 }. D- K, D
  46. *****************************************************************************/
    1 l6 h* E  n" ?, C

  47. ) H6 h: Z2 S2 U5 B
  48. // AES子密钥表,当密钥长度为128位时,占用176字节空间
    " o" C/ ?' {( b6 a2 M& R
  49. static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
    ; ~/ \' E9 [$ m7 G) ~
  50. 5 e. z. v+ }; J3 o6 H
  51. // 加密用的SBox4 Q  S& C( z0 b; Q$ Y9 z" w( B$ Z
  52. static code const unsigned char sBox[256] = , O& l6 M7 N: Q0 I3 M& o
  53. {/ n* S5 b1 |' q  d( q- B+ y
  54.         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    3 k& E8 V( b) n& |, N
  55.         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    ) Z2 Y* L' M4 z! w4 ~
  56.         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,  j- P. J# f# b: {6 ~* p
  57.         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,7 R* N6 j$ s  a
  58.         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0 M1 r2 a0 U; e+ M0 X7 J
  59.         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    ( ]& B* W! @& m' Z2 e( y
  60.         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    " h3 J; e0 d5 R/ r, r( O5 `
  61.         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    + W- Q6 ~* b: {! v' X
  62.         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,& D5 l1 N  G; W
  63.         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
      f& V6 _: g3 H1 K0 m' r# s
  64.         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,' s# q' c) R1 `
  65.         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    ! S6 n- x. b+ a; u  z# p3 V
  66.         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0**, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    ! V1 t/ n' h8 k# L# |
  67.         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    * Q0 }/ N4 ~" |) w3 T8 o
  68.         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    ' j" Z5 A3 W% o- v
  69.         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + N. q1 L, I$ D; E5 c6 [
  70. };0 W8 f, j1 H& S& s3 {2 S; \1 X
  71.   w+ L; i, E2 n" C
  72. // 解密用的SBox8 p: U$ ?( h9 Z4 ?& r! K: d* r9 P
  73. static code const unsigned char invSBox[256] = - ]. d0 \4 H- L
  74. {) W1 R3 t' l# v# T
  75.         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
    3 H6 K9 {! J6 R) K7 P/ a- V# _
  76.         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
    : B5 y" j6 b& a; l  c3 z  ~
  77.         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
    / q) T2 H  v3 ~( H& H8 p; w" a, q& g
  78.         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
    ( [0 [4 }; F5 J7 N1 h0 E% M# d
  79.         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
    " _5 |; U- j3 x" [8 C0 o6 R& k
  80.         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84," F- j3 z. q; X9 d! U
  81.         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
    5 I) Y; n9 Q! u* B
  82.         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
    # M- {9 Q1 z6 H7 k8 F( d* p( a
  83.         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
    , S# u6 G' X% j& a# d4 @
  84.         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
      R& E8 |; J. S0 y7 u& D3 ]- i
  85.         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,, Q: U" F- }* L! q$ n; W
  86.         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
    , D# S) d) m- s5 S7 h& e
  87.         0x1f, 0**, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,7 o" `* L2 y; n% ]( h0 O4 J
  88.         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,& ]6 F, O  p* D1 z- I
  89.         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,1 H" `3 @* G8 d5 N6 T3 O
  90.         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d        - i3 p. r+ b' T% O6 e
  91. };2 ?7 `6 b2 C9 E3 b
  92. 5 Z/ X7 V8 L1 T% ~1 h
  93. ' A; C: v, Q( W9 E
  94. ///
    4 N3 t' z1 q3 J" i  L0 |: x
  95. //        函数名:        rotation_word
    $ ?3 L* T" S  `7 M
  96. //        描述:                对一个“字”数据进行循环右移。) f. t4 d7 ~& Z8 t- i2 ?0 w6 M
  97. //        输入参数:        pWord -- 要右移的4字节数据。
    " w3 a* j0 t9 @
  98. //        输出参数:        pWord -- 右移后的4字节数据。3 I$ k" e6 I. j, P2 v
  99. //        返回值:        无。& @( Z4 t1 C0 m0 `# s: ?% A" A
  100. ///: o+ S( |& V- q5 ^# S* p8 f6 `
  101. static void rotation_word(unsigned char *pWord)* z; q8 v  H; Z
  102. {
    9 ~/ F- P7 H0 m- z; y+ c% X
  103.         unsigned char temp = pWord[0];
    9 X) [% @7 d' J+ ^
  104.         pWord[0]  = pWord[1];
    $ Q  N5 E& D& q
  105.         pWord[1]  = pWord[2];
    0 M6 T+ R" X7 Q& D9 l# z. l
  106.         pWord[2]  = pWord[3];
    4 E9 Z9 B8 ?' k+ S8 q
  107.         pWord[3]  = temp;" s; t+ n+ h4 i
  108. }  T7 U  C$ P4 @4 z2 H$ L* d

  109. + E5 j+ P# W! x: R  \
  110. ///
    7 J% U& c* b! ?# T) _/ J& B" k* j
  111. //        函数名:        xor_bytes' z- n3 k* h9 V4 \
  112. //        描述:                批量异或两组数据。
    - B' Z/ E0 _% D5 o
  113. //        输入参数:        pData1 -- 要异或的第一组数据。
    + w% {& T5 I% J* l
  114. //                                pData1 -- 要异或的第二组数据。
    . {! D0 q( C. I0 j
  115. //                                nCount -- 要异或的数据长度。& Q" r* Z+ l7 T  f
  116. //        输出参数:        pData1 -- 异或后的结果。
    ( k- j- i* T8 x0 G
  117. //        返回值:        无。
    1 J* ^/ O9 t, Z* d* S
  118. ///
    ' d. ?1 F) T/ a7 i
  119. static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)
    # P4 ^' r8 t' i% X! n) _# p; N0 u
  120. {7 T8 Z- y3 O- O& b/ q+ R
  121.         unsigned char i;
    : x5 n- d$ u  ^6 |8 B
  122.         
    5 j) r' F  `! s( _, M
  123.         for (i = 0; i < nCount; i++)2 [) j* n* \  Q0 C3 C3 O* ]8 F' P
  124.         {- L1 M! h0 L% B1 G! i9 p
  125.                 pData1<i> ^= pData2<i>;0 C/ U% X# B: N& k
  126.         }" x5 B3 h- Z* F
  127. }
    8 t8 ~- F" S$ |0 `8 e6 b
  128. ) Q* P' i& @! m; F9 Z% m7 e4 D! a
  129. ///
    - Z0 o- j* T; ^+ R) }
  130. //        函数名:        AddRoundKey: f7 b6 o& M* C9 I8 O2 z
  131. //        描述:                把 中间状态数据 加上(异或)子密钥,数据长度为16字节。0 P" [0 g) `; J8 p6 T( P0 Y! l
  132. //        输入参数:        pState          -- 状态数据。
    " o# f( S+ W/ x1 E# ~) j' |- g
  133. //                                pRoundKey -- 子密钥数据。
    % @* e1 z, A8 q% V+ u/ ?
  134. //        输出参数:        pState          -- 加上子密钥后的状态数据。# P( I3 Y/ W) N+ N7 f- Y. e0 _
  135. //        返回值:        无。1 c, B. t; |9 _5 c+ ~5 i
  136. ///+ M. u/ R( y, W+ x% l
  137. // static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)
    9 p# O8 ~( L, g: n* T9 h
  138. // {
    5 m6 a8 O8 |. a: R
  139. //         xor_bytes(pState, pRoundKey, 4*Nb);9 O- A# [7 P8 @4 r+ x; E
  140. // }3 n6 i% X! I9 b9 o9 |5 G

  141. . `4 E9 t9 e! ?! c. q  j
  142. // AddRoundKey的宏形式,比函数形式可以节省4字节的data数据
    . L) J* R; L2 A: l3 a8 v
  143. #define AddRoundKey(pState, pRoundKey) \9 j0 z9 a, E& h, b! C! U
  144.         xor_bytes((pState), (pRoundKey), 4*Nb)4 c" Z3 {' ?* T0 v& X; r# t$ A" `
  145. $ |# J5 y; v7 r1 [- q) Z% F2 ~$ G- Z
  146. * ^+ s# S3 F, [9 T% D- {
  147. ///& q9 v. @, R2 R% }
  148. //        函数名:        sub_bytes/ R3 N9 `" h9 h% B6 A3 R
  149. //        描述:                通过S盒子置换状态数据。  C$ l7 {$ U& g4 w
  150. //        输入参数:        pState        -- 状态数据。
    " n$ ~4 e# E4 t& `3 V9 w5 `
  151. //                                nCount  -- 状态数据长度。4 I, a# _7 O: A. m4 ?
  152. //                                bInvert        -- 是否使用反向S盒子(解密时使用)。0 s  N% Q' l6 {8 s
  153. //        输出参数:        pState        -- 置换后的状态数据。
    ' d% q, }( Q9 k& y7 ~, A5 D/ l8 X
  154. //        返回值:        无。
    ' D$ H( Z  c0 E2 I' Q
  155. ///" O6 b3 {+ z; q- R4 n/ q( o" K4 M" d
  156. static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)
    & k0 H9 w: H- g& `) k. p1 {
  157. {
    ; N) Z0 j" m  |" ~, l: L
  158.         unsigned char i;! {+ x! L* ]- k  [
  159.         const unsigned char code *pSBox = bInvert ? invSBox : sBox;6 ~9 ~" n+ c# `+ q; V! H6 d
  160.         / Q0 e# e5 e9 E3 s' E5 j7 n% e8 F
  161.         for (i = 0; i < nCount; i++)
    0 f2 e  ?5 f2 X; z
  162.         {8 X8 u: ?' W/ v, [: R$ Z
  163.                 pState<i> = pSBox[pState<i>];
    1 o# x& M1 S& G1 Y" U
  164.         }. Y! i: O0 I) \5 ~
  165. }
    6 k0 `, w" E3 ^+ {4 R( j  N

  166. + ~! D; R( [) g& ^$ {
  167. ///! Z6 w4 h, Z; I, v# b* f
  168. //        函数名:        shift_rows- E1 b5 F1 _" w6 T
  169. //        描述:                把状态数据移行。
    0 C5 ]8 |6 l- r9 F+ V1 l, n
  170. //        输入参数:        pState        -- 状态数据。
    ) X  }$ ]  w: e7 D/ R  K
  171. //                                bInvert        -- 是否反向移行(解密时使用)。
    ( l" Z. k( W0 A) s6 N: J
  172. //        输出参数:        pState        -- 移行后的状态数据。* a% r* _, {4 ^7 Z6 A
  173. //        返回值:        无。
      Q# q3 f$ D0 `9 Z7 Y
  174. ///
    * z5 D' s% m0 Z/ M( f3 u
  175. static void shift_rows(unsigned char *pState, BOOL bInvert)
    # p( R: \7 l" ~
  176. {
    " U; N: L& c5 y$ ]
  177.         // 注意:状态数据以列形式存放!* N; J' d$ X, C3 j5 l% t3 l1 s

  178. * q2 E: [% @9 q* w; Y5 D7 d
  179.         unsigned char r;        // row,   行# K0 d) I& D5 [- _# e+ \5 n; H' d
  180.         unsigned char c;        // column,列5 v3 M- W1 }1 ?) s- X. w2 g
  181.         unsigned char temp;
    4 ~3 I% x% C6 `& L' d  D
  182.         unsigned char rowData[4];
    , [+ A& b( w" A- U
  183.         ) w1 Z8 `! ?. A' k, ^& R) `
  184.         for (r = 1; r < 4; r++)8 l4 y/ _+ {6 Q* r4 @: b% @
  185.         {
    $ q9 h3 G3 l6 o( u2 K( `% U
  186.                 // 备份一行数据
    0 a* g0 r9 M( t2 `: S8 ^
  187.                 for (c = 0; c < 4; c++)
    1 [( N7 h3 d6 d  `9 f5 s$ S+ C
  188.                 {# _" d! c5 _* i- s- R- s7 p) @
  189.                         rowData[c] = pState[r + 4*c];
    3 T2 @: c, u  h3 m
  190.                 }6 m2 H% |0 `: k$ f- ^. D1 @
  191.                 1 W0 _0 N" o9 U5 @8 p
  192.                 temp = bInvert ? (4 - r) : r;
    3 X: w, ~6 T5 T
  193.                 for (c = 0; c < 4; c++)) |2 N# I5 P4 g  r. n
  194.                 {
    ) U, c9 w3 B6 ]' U  M. H
  195.                         pState[r + 4*c] = rowData[(c + temp) % 4];) J2 i4 ]$ Z; h2 ~2 ?
  196.                 }
    ! E7 ]$ G/ ]$ v# `9 E  C1 k# \
  197.         }8 O: G7 `, D) U5 `
  198. }6 w. R' M1 ?1 ?  g0 d0 \: }6 X
  199. % G4 A0 l: X, s; y9 K! A8 ^) ]1 L
  200. ///& h* A$ o9 X$ i7 B! j
  201. //        函数名:        gf_mult_by02: ]' r- d% Q! `$ @  r
  202. //        描述:                在GF(28)域的 乘2 运算。' N! q! i6 p1 P# q8 ^
  203. //        输入参数:        num        -- 乘数。( r9 b4 A! s( [6 c4 H2 D
  204. //        输出参数:        无。  W+ D+ t5 [, q2 x& R
  205. //        返回值:        num乘以2的结果。
    % `* \4 d& X% X  w, F" \
  206. ///: u: _* P  g8 y8 \3 ]  H% P! [. e
  207. static unsigned char gf_mult_by02(unsigned char num)
    6 t- h- M8 U( I4 b( N' u
  208. {# r0 c/ v& u1 R# h1 R, X8 z
  209.         if ((num & 0x80) == 0)
    9 o, y: u6 D- ~% \' S5 c
  210.         {
    5 x* I6 _% H! z* }
  211.                 num = num << 1;% G7 y- G( z9 C
  212.         }
    - H. f, }  J% w. j- T
  213.         else
    ( K) _- z% u) b  ~/ u! }
  214.         {
    9 X' m$ u8 M2 S8 B* d5 S
  215.                 num = (num << 1) ^ BPOLY;
    ) z# z* F0 f* |
  216.         }
    * q  M+ R# {: s
  217.         
    4 v& L7 f6 W3 {- c1 J- m) O4 O9 V9 N
  218.         return num;
    ) Y1 D, A* p3 u
  219. }5 s1 n% S; h' h( t
  220. ; ~; H/ O! Y5 B! Y4 F$ t6 \# c+ ]& V
  221. ///5 Z. b1 u. w5 z6 U3 I6 y- R8 T8 q
  222. //        函数名:        mix_columns! j6 k( p" D/ G8 T7 d0 b
  223. //        描述:                混合状态各列数据。* A* k9 i- a, N/ A6 t$ }1 V$ L
  224. //        输入参数:        pState        -- 状态数据。
    " o: `2 @/ z: Y$ P+ {: f9 p
  225. //                                bInvert        -- 是否反向混合(解密时使用)。
    2 P" G: [2 y/ v+ E/ t) T$ L
  226. //        输出参数:        pState        -- 混合列后的状态数据。
    ; y! D. i+ G+ B1 Y3 c& w5 G
  227. //        返回值:        无。
    , M8 [7 p. l3 H3 c. z0 Q
  228. ///
    ' |( D$ t" ^: q. u$ a7 f6 F
  229. static void mix_columns(unsigned char *pState, BOOL bInvert)
    $ P: r" B2 I  T! k
  230. {
    3 K' a3 c2 Z6 z* d6 k
  231.         unsigned char i;$ ~  I9 p; i; b
  232.         unsigned char temp;% |! [% ~) R5 v5 {/ v: {
  233.         unsigned char a0Pa2_M4;        // 4(a0 + a2)
    ! d1 a* G$ A6 ?( v8 Q" Z% T5 C
  234.         unsigned char a1Pa3_M4;        // 4(a1 + a3)
    ( o7 k' a. J: Z2 t: u9 ~# N2 |
  235.         unsigned char result[4];5 c6 O3 @) R) g( j% \

  236. 5 @4 \& p9 E& v" t
  237.         for (i = 0; i < 4; i++, pState += 4)# Y' j! w; S2 n7 J$ l' k: t! s! u
  238.         {7 {3 _) ~- q. q% Z; n' X
  239.                 // b0 = 2a0 + 3a1 + a2 + a3 + d/ n. K3 K% |5 ~- N
  240.                 //    = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0. v7 X3 w" m5 F0 \: I

  241. ! Q* x$ [+ H! L' b5 |& t
  242.                 temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
    ! M5 Z6 u2 E$ U
  243.                 result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));
    6 Z% m( ?. \9 K: S2 r" |: D! d
  244.                 result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
    4 O# U; t* m  }* O& P+ g! C
  245.                 result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));
    8 G7 v% }3 Z8 v9 e' U% Q- b$ |
  246.                 result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));' U6 [% s6 n. _" m% |5 @: a2 `& E

  247. 2 l  k- O* o. v( X9 h4 t* t5 A) M
  248.                 if (bInvert)) s8 W5 p% x  j0 M0 R
  249.                 {
    9 l. w7 B: e! |' X
  250.                 // b0' = 14a0 + 11a1 + 13a2 + 9a3 0 W3 l6 a' b% d1 K7 P' e
  251.                 //     = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0        (这部分为b0)2 l# @- `; u7 b/ b$ O
  252.                 //       + 2(4(a0 + a2) + 4(a1 + a3))
    ( d$ }/ v$ G2 c
  253.                 //       +   4(a0 + a2)
    - x9 j9 i5 @) M# B! u7 P/ S
  254. ( d# b" {' p2 ]/ o7 E3 G
  255.                         a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));3 b3 X1 o4 E) P+ s
  256.                         a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));9 L$ U" u: Z+ ?; y" R% D
  257.                         temp         = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));
    . Y% j) L; G0 u5 M% a; h+ ]
  258.                         result[0] ^= temp ^ a0Pa2_M4;/ b/ Y$ |# o' ]% E) {
  259.                         result[1] ^= temp ^ a1Pa3_M4;7 K. l5 X1 `0 m2 F$ I: x5 G9 q
  260.                         result[2] ^= temp ^ a0Pa2_M4;
    4 h9 `8 j, G$ c
  261.                         result[3] ^= temp ^ a1Pa3_M4;; L- u9 M! t( _
  262.                 }
    , M% o: S8 T2 Q+ \9 y. v7 c
  263. 6 G! p4 g8 |5 R3 C, t
  264.                 memcpy(pState, result, 4);/ P0 a- ^. e4 z) X
  265.         }
    4 u* M, T. S4 M* ]3 h0 [3 U
  266. }5 }- `+ o# ^+ N! e7 K( f9 W3 ^" F

  267.   i; |. n0 ?$ [4 u! Y6 u
  268. ///7 y, r5 j# c$ U% b! }
  269. //        函数名:        block_encrypt* a6 W* }6 ]; v2 C* Y$ h$ E
  270. //        描述:                对单块数据加密。4 \" X$ K1 m/ v3 C( v+ `
  271. //        输入参数:        pState -- 状态数据。0 @% _' ]3 q$ S2 V4 r& g5 D, x
  272. //        输出参数:        pState -- 加密后的状态数据。& I9 |; [) F4 y' B  M3 {0 u3 K
  273. //        返回值:        无。
    8 L0 y4 J/ ?) C2 K
  274. ///
    & m% W+ E8 X/ g* u9 l0 m7 ~8 B
  275. static void block_encrypt(unsigned char *pState)# t; d8 W/ X4 N. X( _6 S
  276. {" U: o" W: M2 X" \' Q" ~# O/ I% y
  277.         unsigned char i;  q. W- ?! r2 I3 _3 |. [- z2 n: W+ c
  278.         9 U- y8 Y! f( K% d( f
  279.         AddRoundKey(pState, g_roundKeyTable);) H" U! J8 I% W2 \: [- v$ L
  280.         
    6 u( ?! Y4 v+ [: H
  281.         for (i = 1; i <= Nr; i++)        // i = [1, Nr]2 ^! ?+ o' Y: _7 c
  282.         {, u5 {6 {% }. C- ?7 G9 X
  283.                 sub_bytes(pState, 4*Nb, 0);
    * X1 j3 ^" o$ J# ?- r+ ?, r+ c
  284.                 shift_rows(pState, 0);
    4 E$ U7 P. D6 A+ Y" J
  285. " x6 y7 ~* g8 M3 M
  286.                 if (i != Nr)
    , W! U9 f/ I, j- _* _! W
  287.                 {' E$ t  ~/ H+ o6 y% t
  288.                         mix_columns(pState, 0);
    * f/ d- x3 q6 e3 v* @: h
  289.                 }
    & N. v& \" u- p) ]2 M1 ^2 O

  290. 7 I' A" g' ~: C$ Q' \  a& [
  291.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);0 ]* |! P9 O0 {4 m
  292.         }2 X+ ]+ b+ c4 F& }, G( g' o
  293.         
    * h: u$ `9 N6 B4 N1 ~6 \7 H2 h
  294. // 为了节省代码,合并到循化执行
    0 q9 r/ j& ?) F$ l/ l% P- r  F( ]' Y
  295. //         sub_bytes(pState, 4*Nb);
    # R1 G; U3 F! Y2 K3 e
  296. //        shift_rows(pState, 0);, P" b. x/ H- l8 V! I7 d; t& l' _" J
  297. //         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
    ) [+ o( O7 G; X; `
  298. }
    + J  @# D7 N8 i. g
  299. % p) C* |4 _  A. y# v" f; S8 g3 }
  300. ///
    7 z/ _  t0 V  D, w
  301. //        函数名:        block_decrypt+ m8 E* I; l8 c
  302. //        描述:                对单块数据解密。
    - c" G# q- T# t) I2 j  v" ^
  303. //        输入参数:        pState -- 状态数据。6 Z: ?" U& k+ i( [5 S' A3 O* U
  304. //        输出参数:        pState -- 解密后的状态数据。
    6 O- g+ c- b, ]. P4 u* _/ N
  305. //        返回值:        无。
    ! k0 C' I* Y, [6 X% B
  306. ///
    ; o7 O1 |: h- F' X. _! Q
  307. static void block_decrypt(unsigned char *pState)) J1 H2 s6 o% {6 V4 \5 v
  308. {
    . w/ N( |8 K! r; O' ]
  309.         unsigned char i;6 N4 m+ H/ m- k0 c% _% `7 \
  310.         
    + h6 V) Z: B( @1 p, L4 A6 {6 r
  311.         AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);# b' W- b$ ^( f* t6 H$ ~5 w* g, x2 k
  312.         8 Q+ t* ^: b, m3 F2 u+ W8 J3 ^
  313.         for (i = Nr; i > 0; i--)        // i = [Nr, 1]# E  J9 W7 l- N
  314.         {
    / o  C  Q; x  U4 U8 W( U! @
  315.                 shift_rows(pState, 1);
    ! K" p& L  s+ r+ s  a7 C! }
  316.                 sub_bytes(pState, 4*Nb, 1);
      S' F4 H6 N. \
  317.                 AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);
    ; n3 z( v$ F* J& l
  318. 6 q3 d; i' I  m" \$ N. |7 G
  319.                 if (i != 1)
    4 S* }' G0 O8 L% u& b3 K/ o
  320.                 {
    5 I; k/ h+ h5 H( a, M( m: Y
  321.                         mix_columns(pState, 1);, r5 R1 S- D3 F3 m- I1 M
  322.                 }
    % C! o) @" j/ e
  323.         }
    1 g  p# Y% g7 @! d* l) ?
  324.         2 J, W1 T2 ~% E2 o0 _6 R# ~
  325. // 为了节省代码,合并到循化执行
    * @$ e& g0 _1 u! X4 O& t: n& _
  326. //  shift_rows(pState, 1);. m/ E  F. i9 v, _9 _
  327. //  sub_bytes(pState, 4*Nb, 1);
    $ P% f' Z) x' h& f
  328. //  AddRoundKey(pState, g_roundKeyTable);7 H. t+ c0 ^: H7 k
  329. }
    & A% e- r3 M+ e; d+ G) |
  330. 0 d1 s  d: P8 G$ j
  331. /*****************************************************************************
    3 c- o, W+ r; g4 D
  332. *  Global Functions                     全局函数
    + z$ b* L5 S5 A8 h! D" \, i
  333. ******************************************************************************/! k6 r1 n; U$ h
  334. 5 Y. M4 k) ^  }! e) U$ p5 Y

  335. 1 ]- j) b  c% j9 d( R4 P1 q* R6 }
  336. ///, _/ v  a: q7 |6 d6 |& b; l# _
  337. //        函数名:        aes_init9 g. N; R; G% ~& x* N( T
  338. //        描述:                初始化,在此执行扩展密钥操作。
    0 V5 ~/ a) S  _# Y1 A
  339. //        输入参数:        pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
    $ D: u5 I  k+ A- Z; W0 W' k
  340. //        输出参数:        无。
    ( ?" b9 r. `6 R6 J' a
  341. //        返回值:        无。
    7 ]6 I, k8 K* L& m: E9 I
  342. ///; \1 \" N. |: M0 r
  343. void aes_init(const void *pKey); B& n- ~( _6 v& m4 v' Z
  344. {
    * {- o9 F1 d' o- e# v
  345.         // 扩展密钥9 h  X" P2 t" z8 w' G" v
  346.         unsigned char i;
    - H9 v& r1 z- v; u, G: g
  347.         unsigned char *pRoundKey;/ d3 |9 d0 ]& |8 [- s' ?
  348.         unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
    5 w3 C7 s2 y% y0 |' Y* d
  349. % K3 ?. A# b% A. a3 R
  350.         memcpy(g_roundKeyTable, pKey, 4*Nk);
    ' l+ w5 o9 Z  b: c& a* S; ]4 T

  351. ! H& W7 a4 t; J" q$ ^$ `
  352.         pRoundKey = &g_roundKeyTable[4*Nk];% Z7 A5 E9 P- K/ x# w
  353. . b4 r+ R- G! ]1 A
  354.         for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)( e$ i  {% U% t
  355.         {0 r2 a# A" q0 z% u4 ^
  356.                 memcpy(pRoundKey, pRoundKey - 4, 4);5 b) L4 ~+ A! d7 h5 ?
  357. ( {1 i% X+ ~& d' i, p+ J2 _
  358.                 if (i % Nk == 0), v' p8 y* k: z% \2 F5 E
  359.                 {' O3 Y$ h/ ]# s7 G4 p
  360.                         rotation_word(pRoundKey);' k3 M( ~" W) i2 @  `# C3 a* A) J
  361.                         sub_bytes(pRoundKey, 4, 0);2 O  Y- ~$ ]1 O/ {. P: j
  362.                         xor_bytes(pRoundKey, Rcon, 4);
    % g. s  a6 S$ c
  363. 2 l/ Y! U# m) p; q
  364.                         Rcon[0] = gf_mult_by02(Rcon[0]);
    $ A+ y- n2 N, B0 C. n2 d- @' y- l
  365.                 }
    & q+ o( n% a  _
  366.                 else if (Nk > 6 && i % Nk == Nb)
    $ l% d5 W; }$ [; M6 ~) T
  367.                 {& q0 r8 s* n# U5 o) y; a
  368.                         sub_bytes(pRoundKey, 4, 0);
    5 Q7 R# J4 `3 h$ l/ g
  369.                 }
    : A) ^) l; }/ B, P/ ?- B6 V- M
  370. / [. T7 O$ j, k' E( H- M
  371.                 xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);; C% }4 Q/ A2 j8 P1 k% z: m
  372.         }2 z  O$ E7 d* l, P# H; c. \* U
  373. }( t9 R+ F8 `4 k5 e' x
  374. # w( n0 I6 `# q5 M- \0 ]) j7 z
  375. //% s- c0 m1 B  f: N
  376. //        函数名:        aes_encrypt
    / Z/ c) h$ j6 {0 V) ?! h
  377. //        描述:                加密数据% [" P  G$ N: Z8 r( g/ r) V
  378. //        输入参数:        pPlainText        -- 明文,即需加密的数据,其长度为nDataLen字节。
    7 [  A- `, @% p9 x
  379. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
    , n* z0 H  ?4 C2 |  R" B
  380. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。0 ^3 K8 g( h" x$ O
  381. //        输出参数:        pCipherText        -- 密文,即由明文加密后的数据,可以与pPlainText相同。: t5 `$ i" X9 S. N$ |6 ~/ x* b
  382. //        返回值:        无。
    9 h  i, A# S4 B% d; B
  383. //% z( V4 d* U1 l1 j3 z8 G4 k: c
  384. void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
    3 d8 H4 ]7 x2 n- c
  385.                                  unsigned int nDataLen, const unsigned char *pIV)
    3 ~7 G' u$ S/ ?
  386. {: D' a6 Q" w  N. ^* Z; Z! }4 q' F, w1 ?
  387.         unsigned int i;
    * p" p' s/ I' q/ K; M- Q% W: Q" {+ \, R

  388. + a! V6 q9 m5 Q) C0 k* Q1 w( q
  389.         if (pPlainText != pCipherText)
    / q/ n$ X- H* p5 |2 G8 ]0 V
  390.         {
    3 f/ I' r8 z5 [; C' w: J; D' Z
  391.                 memcpy(pCipherText, pPlainText, nDataLen);% Z2 w# c1 Z; a% S# G' i
  392.         }
    : s0 K4 B/ l  ?4 N7 `3 s; x
  393. 1 e9 Z5 M/ X% a$ F; g
  394.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
    ( Q+ Q& j% x9 Z8 g2 \7 X! u7 t
  395.         {
    ; n. M* h! T5 w# y4 c; j/ x4 a
  396.                 #if AES_MODE == AES_MODE_CBC: C* v2 i/ u5 F- L- J& S
  397.                         xor_bytes(pCipherText, pIV, 4*Nb);
    3 y0 D- f6 C& o- Q! t
  398.                 #endif# u% k% G% A+ ~' P% ]
  399. + N6 R( J  i' _& v" N( n
  400.                 block_encrypt(pCipherText);
      ~  {+ S4 `6 G& u! [0 l! d
  401.                 pIV = pCipherText;  |0 I: v0 p  D" @, F- L% t
  402.         }2 R2 _8 d, k' L8 {6 F% N$ R
  403. }
    4 C# O  Y, s; {  k; r6 X/ C

  404. ; B( J( T. i: S
  405. //
    ) R7 v7 x* w  l0 R4 Z
  406. //        函数名:        aes_decrypt' R3 N3 p5 {/ V6 L- q7 b  W
  407. //        描述:                解密数据
    " [- o7 F' |1 ~. d- i
  408. //        输入参数:        pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。: O$ V9 }2 ^5 f, j( T
  409. //                                nDataLen        -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。0 W1 h9 J5 x, x( R( b2 x, M
  410. //                                pIV                        -- 初始化向量,如果使用ECB模式,可设为NULL。2 G" u, y$ X5 G! {* v" c
  411. //        输出参数:        pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。: [9 v- Z0 E" C5 N- \
  412. //        返回值:        无。
    # G3 y  Q7 y' W4 Q: X; q* H
  413. //& x% T2 P# x1 C+ {
  414. void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
    ) G/ I7 m, g# R3 |2 s9 E* k
  415.                                  unsigned int nDataLen, const unsigned char *pIV)# o$ W/ R6 ?7 w4 q
  416. {
    : A) O( g7 R: v; _( ~
  417.         unsigned int i;  z7 J' R+ l1 O( ^9 f$ R

  418. / f) t* X# k- g: U  z
  419.         if (pPlainText != pCipherText)( y& W! ?1 T  V. ]
  420.         {* J/ c( K6 d# r2 _6 t- p3 V* M
  421.                 memcpy(pPlainText, pCipherText, nDataLen);, N/ L+ A9 O3 T1 X& a2 v
  422.         }# ]0 l' ]' G3 c7 O& A! P
  423. 5 p/ E5 T* S& B# H# P
  424.         // 从最后一块数据开始解密,这样不用开辟空间来保存IV! g+ N+ x3 {$ s7 }8 H8 D
  425.         pPlainText += nDataLen - 4*Nb;
    2 F+ r8 j. z3 j2 O
  426.         for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb)
    3 A1 D* X. S/ F, U/ u1 X! O% D2 j
  427.         {, W/ ^8 c) B: }- n
  428.                 block_decrypt(pPlainText);
    4 J7 w8 d" M/ I+ V# v
  429. & [9 v" x, e' S: b& x+ M
  430.                 #if AES_MODE == AES_MODE_CBC
    . \% K. z, K: P: Z% [
  431.                         if (i == 1)2 q% t" z3 q; B& v: e4 v
  432.                         {// 最后一块数据3 K9 D) B; J/ s# z
  433.                                 xor_bytes(pPlainText, pIV, 4*Nb);1 ?$ c# ^0 E+ U$ W
  434.                         }
    3 u* q. A5 c' D3 n
  435.                         else# D" s6 i! S7 Q$ O7 K1 ~# w
  436.                         {
    # k9 L0 C% f8 F8 H- y" J
  437.                                 xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);
    : p- [1 u3 R9 T9 X! j
  438.                         }/ B. F! ], `! \9 L8 \: a1 O9 D
  439.                 #endif
    ) t; h; y6 ]5 _, s% U
  440.         }% M6 Q; y; y" t  R; `2 ~1 q
  441. }</i></i></i></i>
复制代码
0 R3 e* H! a4 K3 a9 F1 |7 V3 t
三、使用7 V/ P% L- i  h; M. @9 l7 o
使用注意点:, q4 F' O9 g( f3 D  l" A
1、AES_KEY_LENGTH取值只能是128,192 和 256# N( W! A% ?( o, R0 B' q9 }
2、密钥和向量表长度为AES_KEY_LENGTH/8个字节- o  C* S& Y/ e$ k) T6 P
3、加密、解密数据长度为AES_KEY_LENGTH/8的整数倍字节
, f. T- {9 [4 P. n+ \5 ]9 n) {; U
3 a2 g+ H6 N) n1 |8 k0 q
  1. int main(void)% M( x7 X6 d8 T. g8 j. \
  2. {
    - t0 W+ C* U) e9 t4 @* I
  3.         u8 buf[16],saveBuf[16],descryptBuf[16];
    / T3 i8 M. {) u( T- G# v( z
  4.         u16 i;; J+ u" N, o4 f- d
  5.         unsigned char AES128key[16] = "123456789abcdefa";//秘钥' J, B+ s9 T' P% T- ^% |; D
  6.         unsigned char AES_IV[16]= "0102030405123456";//向量表
    ) Q. q9 u- g' {9 }, T
  7.         delay_init(168);                  //初始化延时函数9 i6 o3 E" _. w$ I8 @
  8.         LED_Init();                        //初始化LED端口, I/ N/ F* i4 S' A; g1 Z3 g  _8 I

  9. : a5 m% K" w5 w& X; H- Y2 [
  10.         aes_init(AES128key);//AES初始化
    . D. U/ ]4 u, _( w( J# M
  11.         
    / M6 q7 D/ ^1 o( g
  12.         for(i=0;i<sizeof(buf);i++)
    1 u" L% _" n5 l) \6 \; p
  13.         {
    3 W  j" i: t- e1 g, B: z
  14.                 buf=i;
    3 z! h: r2 s; |( E& S+ ^5 Z* j3 a
  15.         }
    $ u) i! K7 e0 ]3 N+ S0 z8 V' j% {3 U3 T
  16.         while(1)
    ) n5 W; l& V7 R* o  u, v1 K
  17.         {
    $ G$ ~' E* w& p& |
  18.                 aes_encrypt(buf,saveBuf,sizeof(buf), AES_IV);9 ^- d0 s* w: s  s
  19.                
    ; D' f% X" Y: h; n* d
  20.                
    4 K% s# j% s3 c2 Q7 P) c# e
  21.                 aes_decrypt(saveBuf,descryptBuf, sizeof(buf), AES_IV);6 d7 O' X$ X" Z- y) X& l
  22.                
    ; U, i0 Y' P+ @2 T: U6 w$ A
  23.                
    ! M( L* @3 B# }
  24.                 GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0对应引脚GPIOF.9拉低,亮  等同LED0=0;4 @6 G3 x7 x* O  M7 q: ]
  25.                 GPIO_SetBits(GPIOF,GPIO_Pin_10);   //LED1对应引脚GPIOF.10拉高,灭 等同LED1=1;
    $ ^" ]: J+ [8 `2 M, ]1 }( a
  26.                 delay_ms(500);                     //延时300ms7 \& V, y5 a3 B9 R- a! f) |$ s
  27.                 GPIO_SetBits(GPIOF,GPIO_Pin_9);           //LED0对应引脚GPIOF.0拉高,灭  等同LED0=1;* @5 |. l& E7 v! e1 v1 z! E: W1 t( m
  28.                 GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉低,亮 等同LED1=0;' w8 G) C2 n, o5 w2 I. f
  29.                 delay_ms(500);                     //延时300ms
    5 F# _$ t9 E9 {) x& P/ G% [
  30.         }
    * @6 l1 l( ~6 y( m, Y
  31. }1 J: l  I: n* L( O7 N" o0 K
  32. 4 v# Y5 X# [8 v- A3 D! s
  33. & G; J$ ~! b. _/ a. l( t
复制代码
4 Z2 G4 e; Y; r# @$ \( r! [
收藏 评论1 发布时间:2022-4-22 22:00

举报

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

AES加密这么复杂?

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版