一、头文件) S2 N) ]; }6 x# Z1 y* @% d
& q4 a' {- Z. C0 m4 ^# W$ ?
- #ifndef _AES_H
4 H% c$ ]" L% T9 c - #define _AES_H
0 t2 { k: J! a, f$ ?
8 ~8 T6 S+ e+ S7 G7 Q- 0 ]0 l8 \% p2 b
- // 以bit为单位的密钥长度,只能为 128,192 和 256 三种
; x+ E: g! Y/ x( @ - #define AES_KEY_LENGTH 128! v$ E5 X- |- F, C" t' H9 K) \
- . F) [1 X) k* O8 [. d
- // 加解密模式
' }6 E- | r: v3 ~; ] - #define AES_MODE_ECB 0 // 电子密码本模式(一般模式)
) V/ [, ~ P' J! N: i) [ - #define AES_MODE_CBC 1 // 密码分组链接模式
9 y# q4 \' R+ ^; O0 d8 A - #define AES_MODE AES_MODE_CBC
! M5 w2 h3 `9 y' |
2 l4 T7 R( D# ]2 Z
- t& I& F9 }$ z+ q- ///
0 v5 W+ V9 k* @. J/ c$ ` - // 函数名: aes_init
* Y. `- Z7 s& P2 Y2 w - // 描述: 初始化,在此执行扩展密钥操作。/ c. \4 V3 B% g$ t8 G
- // 输入参数: pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
! A6 I+ ]: j2 i) P+ ^! F0 E - // 输出参数: 无。
2 |( f' D% {0 u - // 返回值: 无。 Q7 o" a" b% P) q5 z2 N
- ///- r, u! s; g7 t- y# n
- void aes_init(const void *pKey);
) q) c/ E0 B$ [9 L9 W' O3 \+ P - 6 G4 v+ v# j4 w) [5 a
- //
0 j* x/ T0 r" P9 [3 _ - // 函数名: aes_encrypt! [5 W* r) N: \3 Y
- // 描述: 加密数据
% h3 Z* z7 i' ~- x+ v* Y' m& q - // 输入参数: pPlainText -- 明文,即需加密的数据,其长度为nDataLen字节。; U" w8 H: P* d& u; H0 V+ o
- // nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。3 j' g$ l9 f+ d( {% o5 G) R
- // pIV -- 初始化向量,如果使用ECB模式,可设为NULL。" C8 h% E8 p+ N% J5 l
- // 输出参数: pCipherText -- 密文,即由明文加密后的数据,可以与pPlainText相同。! t# s- i- z$ d5 O( b
- // 返回值: 无。& f8 ?2 y k% A- V* K( J' v$ i
- //$ h/ h5 |: i3 y) T! x6 m2 }
- void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
* y% Y5 }0 T6 g8 L r7 c8 Q! I! H - unsigned int nDataLen, const unsigned char *pIV);
% B7 K; f9 U! v9 E& d' x ~ - & x c" ?% N! W. J. p( @1 H
- //
1 X! \. x! R( { - // 函数名: aes_decrypt2 \" V( W) {2 I% x
- // 描述: 解密数据
. K f: i4 L; U4 J% ?, L( S( T - // 输入参数: pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。3 U* b" V0 ]" n+ [/ K
- // nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。; y7 g1 S+ [5 S% y/ b# f
- // pIV -- 初始化向量,如果使用ECB模式,可设为NULL。
% U4 M& ?! P* p; n/ } - // 输出参数: pPlainText -- 明文,即由密文解密后的数据,可以与pCipherText相同。$ `. _+ Z! T H% \# s! i: o: Y
- // 返回值: 无。
; l' z( `" N: B g8 ]" q - //' v/ X% | {8 X" h/ b: `
- void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText, ( P1 x* D9 x, x; G2 i
- unsigned int nDataLen, const unsigned char *pIV);7 Z$ }4 ]0 f/ _* f1 {
- #endif /* _AES_H */
复制代码
2 ]5 \6 \) |- Z: Q" I! D) E二、源文件
, I2 `! q4 H! y9 R$ E* B, {. _
5 H7 Z) o/ J/ y) R; Y# E- #include "aes.h"
# F) U, _* l- @* B' G5 @ - #include "string.h"3 ^' D7 `/ V& G; Z7 D- Q
- 9 c, H1 u1 [4 V+ u( i. E! T, @
- / `' o* v: v8 W0 Y
- // 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
x5 b! I/ F6 J9 O) B+ Q) M - // 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空" A1 a# F* i, U0 B9 z
- #ifndef __C51__
* u% Q8 e3 X* K& P8 S - #define code! M) Z; ^" C" X t( U
- #define data
6 |7 X; S. I5 D e6 r - #define idata
7 i8 c0 M' v8 U0 [$ z$ d: d. U - #define xdata9 l1 Y. e9 v) p9 A
- #define pdata
+ |' }! R+ U4 H9 b7 x# R0 i - typedef unsigned char BOOL;& X/ X* w/ D: y* R' w6 m/ F
- #else" C3 F7 P$ E% J" V, X; \
- typedef bit BOOL;7 Y& {! g' y1 ^3 V# ~$ d
- #endif( x# D" A9 B4 l, {; D+ Y
- & F8 n4 l. B9 N( W. E& a/ J6 [
- #define Nk (AES_KEY_LENGTH / 32) // 以“字”(4字节)为单位的密钥长度
3 @: X/ o4 J, S, F/ h/ ]) Z1 x9 U/ z# j: v - #define Nb 4 // 以“字”(4字节)为单位的加解密数据块大小,固定为4
8 N. C6 M" U) ~; L8 K - * X! ~, a8 Q6 K; W1 x3 y8 L
- // Nr:加密的轮数
1 t: ~) Z/ C n" n- G/ [' N - #if AES_KEY_LENGTH == 128
6 |/ d' A; S6 ?3 r! z+ m - #define Nr 10
1 A( d0 ?- L! R+ e - #elif AES_KEY_LENGTH == 192
5 N3 q) ^) o+ o - #define Nr 12
6 a8 ^+ ~& d' D8 O( i+ W - #elif AES_KEY_LENGTH == 2568 T9 V, D1 p7 L- d7 G' A
- #define Nr 14/ d9 `/ B1 x5 p
- #else f a3 v4 J# y; y7 C& g; {% t
- #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
7 s/ t+ ? g5 ^9 [: S# D - #endif& ~8 d( q5 c5 p7 l5 H! c1 k
' \2 E4 [$ }. U/ Y- // GF(28) 多项式* V' w4 i0 F0 l' Q2 U1 M
- #define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).0 G6 |! O, A X. o
- 8 @# d: P& Z$ U- f
- /*****************************************************************************$ K) @# x) C i. @" @
- * Typedef Enum 枚举定义
6 O1 z* m E8 `2 w - *****************************************************************************/" P; x. U1 b/ h \! l4 P
- ; f- K, A# P& C) ^* R% d) M
- /*****************************************************************************1 t+ T! K2 \, V$ S2 @
- * Struct 数据结构定义7 T6 B! r9 x9 ~' Z8 q
- ******************************************************************************/' H- s# p" C* ^! T
z$ Q3 q! f r) Z- / o, W6 A) q. O2 a! U5 p
- /*****************************************************************************9 m C8 l9 z$ W4 C9 k6 u
- * Local variable 局部变量0 U& h( i' y) M0 O" g: Y
- *****************************************************************************/
; c/ U( R% V* g% \6 o ~ - ! D c7 o9 A p8 V! H* t
- // AES子密钥表,当密钥长度为128位时,占用176字节空间
$ i- S" E8 n1 a7 q - static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
5 d" D4 p8 A7 h5 Q E5 v! A. L0 i - $ J) X4 U) [- M* p3 r' p
- // 加密用的SBox2 S- z0 N* [2 n# F$ G, Q- `9 T
- static code const unsigned char sBox[256] =
% @; j, J, s0 [' n# V. H) P - {
, G, j" ]% j6 Y+ K/ D - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
$ l g# a- Z6 k7 `5 c4 d! n4 g - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
' Z8 f$ i8 D i/ ~ - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,5 b0 ^+ o& v1 V c" g' g
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
2 V% C4 y& ^5 _" k) O2 V - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,8 i; o% ]1 A) f$ b
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,1 \# J6 t7 W. a
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,, X, H$ s6 A+ T: i" Z
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,+ a% R" k6 X6 R/ m
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
' f% L9 t2 _4 P! i - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
4 U2 N f6 W: A) W - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,, D# ~9 l3 F8 a! ^9 ~% D$ R
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
1 S1 c/ f1 X2 K - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0**, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
8 ^1 C9 e& g7 f2 f/ i* k8 T - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,4 l: E; e( o4 r- G" j3 U
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
! i1 r; S, R Z" q. g6 a1 E& Y7 V! ^2 g - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 1 b6 q! x) [- r4 j. m
- };
, U! f+ g, x8 w D4 G, F - ' t2 }$ r8 Q0 X/ S0 g6 `$ Z
- // 解密用的SBox, a, d e" E6 g8 Z: @
- static code const unsigned char invSBox[256] =
+ P7 s' |7 k1 }# L9 O. a - {
) O- @, M8 m, i* O" W2 z# \' v - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
. c l7 `4 f# z3 u - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
4 P9 c$ P! [- e# ~, G - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
; u% ?, P/ f5 q( v6 Q ] - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,+ B d. K8 A6 e5 @4 |1 e
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
) b: ~( R8 g1 }8 [ - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- Y" u' C s: \" P6 g5 Q# E' V - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,+ w# J' N1 q V \) c9 R9 W
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,' m$ ^% n# u5 @$ g+ {: o: A/ e
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
' I; c% Y4 R- D) J - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,/ v! p; C( ?+ @3 d# f- H/ k
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,. L* t9 U% r3 C0 V2 v3 T
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
9 ?1 N1 a8 {+ A# l4 f! Z - 0x1f, 0**, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,; f4 r3 B+ ~5 @) s r5 p9 }
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
9 l* V" T% n& ^, \0 t2 O - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
; @' _. E+ K. ~: D$ X9 R - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d " Y; F4 @- P6 h
- };
2 H$ S; e, O, f# X1 |. f
) n1 L6 A1 k2 |3 |
) y7 P) b; R) B. Z+ z5 h( c- ///4 R/ G2 U0 C5 T/ t3 ~$ }
- // 函数名: rotation_word' D t& x' X/ B7 |$ s" w
- // 描述: 对一个“字”数据进行循环右移。
" C' u/ T8 L* m6 O - // 输入参数: pWord -- 要右移的4字节数据。
1 x( u7 O2 u; J) ]! k - // 输出参数: pWord -- 右移后的4字节数据。- |* y7 B+ s1 q6 N2 {
- // 返回值: 无。 [4 M+ x" P6 E U9 j/ U
- ///. m/ D- q7 ~1 Y5 O: P
- static void rotation_word(unsigned char *pWord)" V# ?7 F6 W% d4 e2 {3 }$ G
- {3 @- L& g, N' P/ q; v: \/ }
- unsigned char temp = pWord[0];
( @, S1 W- W" E& G5 L; v2 T$ ` - pWord[0] = pWord[1];; J' b3 }. \4 v
- pWord[1] = pWord[2];
1 X0 T/ }" F% b6 f; ^* M; d - pWord[2] = pWord[3]; F* @+ R k. p" ?
- pWord[3] = temp;
7 A' h" j# q# z B- f# W8 R - }
: W0 {; k6 k/ y) z8 E+ p. e
6 H2 C4 [% U" N! j, V- ///2 N/ ^* N( G. |
- // 函数名: xor_bytes$ J3 P) |3 z# _! D/ X `
- // 描述: 批量异或两组数据。
U; D {8 G5 G - // 输入参数: pData1 -- 要异或的第一组数据。7 N3 J) G" V$ K, Z
- // pData1 -- 要异或的第二组数据。
$ i) v% X0 Y% o$ w7 F; d; } - // nCount -- 要异或的数据长度。% K! I+ `/ Z. J# _
- // 输出参数: pData1 -- 异或后的结果。
# d% i5 I/ d7 Y# w% Y. L$ S1 D3 b - // 返回值: 无。- f, H4 d v$ l# J
- ///
# V$ w* ]) d/ @8 l/ C- D' i5 i - static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)6 R. h; ~" j8 ]/ L: w) ^* t2 M
- {
3 E$ O: R, U7 A! g - unsigned char i;8 u. h" ]: A1 \" r) n' n4 z: Y
-
x, k4 A4 O p; v, n J* m n - for (i = 0; i < nCount; i++)2 N2 {) K$ _0 [4 x( J2 F$ I
- {
6 D/ e: p9 F9 N/ t' r - pData1<i> ^= pData2<i>;! [, y1 ?! c. d4 K( U7 h: a8 A" n
- }8 p8 ?& Y9 s4 z! h! e
- }
: ^- o+ h6 N N0 N - & @& p; \( c E8 }8 F
- ///
2 C3 y4 i* T# z - // 函数名: AddRoundKey
/ U# f* p: l2 r0 d - // 描述: 把 中间状态数据 加上(异或)子密钥,数据长度为16字节。* B4 C1 W+ ~( d; \8 `5 T2 G+ _
- // 输入参数: pState -- 状态数据。
! C5 O+ Y" ]% R! M' C: i - // pRoundKey -- 子密钥数据。
) r1 p* q) w) L# ]- L8 w& r) l$ k - // 输出参数: pState -- 加上子密钥后的状态数据。
' o, Q1 i5 X7 K - // 返回值: 无。
. H4 W6 t8 g8 d, Q U - ///3 U/ ?. `* H" T' U6 ]3 G" z
- // static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)
; J+ p" @' u% ^6 m - // {: g/ c) O/ c, c' ^" s
- // xor_bytes(pState, pRoundKey, 4*Nb); F# X- c: D" G
- // } J+ F& o, H4 v, t V3 M/ |
, x3 R' h4 y; U7 [- // AddRoundKey的宏形式,比函数形式可以节省4字节的data数据 C4 i2 z0 x7 f: q' c
- #define AddRoundKey(pState, pRoundKey) \
) n; M( H! \- T/ u8 I6 Z" [ - xor_bytes((pState), (pRoundKey), 4*Nb)
" w7 ^& P# ^3 p9 R5 u% b' |) U
" s! E# ]- @5 w' T- z" y7 i- / b6 @; G6 t7 c( }$ ^' \' s
- /// |1 D p- F% a, ^
- // 函数名: sub_bytes+ N# p0 D/ V9 C ~ N
- // 描述: 通过S盒子置换状态数据。! ` s- t5 I9 G0 P; l7 ~$ S
- // 输入参数: pState -- 状态数据。 C, z; z- V+ a" W8 P b
- // nCount -- 状态数据长度。
& O7 o$ h, @ y: H+ u+ l - // bInvert -- 是否使用反向S盒子(解密时使用)。% [- V ]& n7 k0 @( v
- // 输出参数: pState -- 置换后的状态数据。
& A$ o- j) X* W; G3 e - // 返回值: 无。
8 S( f2 _! Y5 n9 Z/ t6 { - ///
" z/ C j8 S! _. I - static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)/ c9 w. {/ H% |) Y# w0 m# H
- {
% ]$ n* \7 r8 w6 }3 M# i& w1 G - unsigned char i;
" _ p: w$ W* ? - const unsigned char code *pSBox = bInvert ? invSBox : sBox;* {! h5 C1 H) z$ l
- ; N& ^ b- h( y9 d, Y. B! f% @2 h
- for (i = 0; i < nCount; i++)# o5 Y1 b% F# F$ n$ U/ N
- {* T8 \. Z2 A9 g4 v- u: Z& X
- pState<i> = pSBox[pState<i>];
6 `; R6 q, n- d2 E - }! m# k/ A! `) G: k
- }: O0 s9 Q4 m. C K- d
- - r9 V1 ?3 C2 e0 F1 |
- ///) u# L! P+ }/ `, e4 T
- // 函数名: shift_rows! a8 o3 ?4 [7 S/ ?- W
- // 描述: 把状态数据移行。
: u+ r; }* Y* G8 o r - // 输入参数: pState -- 状态数据。
- h/ c/ d! R) @7 U2 I, D$ o - // bInvert -- 是否反向移行(解密时使用)。
k$ d' ~: v9 r1 R& @+ g - // 输出参数: pState -- 移行后的状态数据。
3 P2 \! O7 u8 V x$ r - // 返回值: 无。2 @8 b, g4 A$ I: ?! S
- ///$ [7 v1 j4 l0 s' H; K& [% _
- static void shift_rows(unsigned char *pState, BOOL bInvert)
! `7 V8 h" B7 \+ D1 A6 w6 L" @ - {
# Y& N' x" W. s- X- k8 @2 g" @ - // 注意:状态数据以列形式存放!9 F7 G& \( Z1 j) E7 `' C2 `
( c, U2 r3 |0 ^* y# ]- unsigned char r; // row, 行: r* O; Z: ~: K' V: h* s: R9 ~
- unsigned char c; // column,列
8 z4 S# v+ n$ K9 h - unsigned char temp;
' @/ t5 u5 Z1 n - unsigned char rowData[4];0 `" j& k$ u% D5 G) e5 E
- 8 [( Y0 ]. f4 \. i' c0 M
- for (r = 1; r < 4; r++)4 {, O( d% l) k
- {9 ], _% |" l/ ^8 ~
- // 备份一行数据
" F& ]' |8 b8 m2 h - for (c = 0; c < 4; c++)' R+ I" N Q" X, ~; i- v
- {
7 y+ M9 z& R( a& y; v - rowData[c] = pState[r + 4*c];
3 G; C( m! C7 I; E - }
; C2 ]; h, ~* C; `; k1 o - . A- j, R% \5 |3 ?0 \
- temp = bInvert ? (4 - r) : r;
5 C6 q$ f+ e) x( T) j5 j( F+ D - for (c = 0; c < 4; c++)
& _! }8 d. U3 z h2 U* r0 Y" h - {+ q* ]5 f% F5 W
- pState[r + 4*c] = rowData[(c + temp) % 4];
( }) n; e/ C6 ]4 x! {% y - }
) |2 p' f' Y* a& E2 n - }! I9 ~4 F3 \9 w( p' p/ |
- }
; p* P" d# b' ?# X E3 T# e
+ [. f0 {9 V0 y( [1 z. e- ///
* _8 W$ B* R3 y5 k: M - // 函数名: gf_mult_by021 @$ |, I$ N# f4 m
- // 描述: 在GF(28)域的 乘2 运算。$ V4 B8 b' \5 |
- // 输入参数: num -- 乘数。; e& g! ?5 x0 b! v o
- // 输出参数: 无。+ d* R2 E/ `9 g
- // 返回值: num乘以2的结果。
5 v; P& I# V* u( x1 O - ///
* o$ b7 R% W, d) [2 a - static unsigned char gf_mult_by02(unsigned char num)
) l) E' K: D0 X - {
% `2 |% u2 Z5 f6 r0 ^/ V - if ((num & 0x80) == 0)' d; C' l( t8 h4 j
- {
" O8 `# } ^3 \, R8 A# ^; e$ ? - num = num << 1;4 W" ?" z1 o2 b
- }' k, d' | i$ J- x G$ y) A, K
- else
) A0 N% |# R) x+ D8 V' [ - {0 i. p: w2 c- h
- num = (num << 1) ^ BPOLY;. [; Y3 b J2 V$ x7 d
- }. }$ U4 {! L! ?" Q9 J3 n6 q! _8 q
- 7 G3 s0 x% b7 U! L( f
- return num;* u4 O. Q" {8 O( Z$ ?, e
- }
3 _5 ^* q1 D1 B0 ?/ J# K5 Z - $ N2 X+ s6 k! e# q* K6 W7 y$ y
- ///! M6 j1 G( q0 _6 G/ v1 _
- // 函数名: mix_columns
$ u! k+ H t' x$ U8 V: P - // 描述: 混合状态各列数据。
$ z P' q8 }" s+ ] - // 输入参数: pState -- 状态数据。
8 x' ]; P1 h" v' i/ c/ j" C - // bInvert -- 是否反向混合(解密时使用)。
0 ~9 k; H. z8 W2 M- f+ [2 |2 W - // 输出参数: pState -- 混合列后的状态数据。, i2 [( U! {2 Z/ G) F' z
- // 返回值: 无。: U6 R. u. G$ `, D
- ///- D. i- [' r3 C6 f) x! x5 W# O
- static void mix_columns(unsigned char *pState, BOOL bInvert)
! o1 C3 @8 E1 T+ ] - {' T; a9 y9 G; J6 b' u" v
- unsigned char i;) P6 \" i% y' I" A+ r
- unsigned char temp;
) l* r8 }, W4 t - unsigned char a0Pa2_M4; // 4(a0 + a2)
. n: d5 L0 c# H - unsigned char a1Pa3_M4; // 4(a1 + a3)% P9 T* _# U3 a' C. A# l, O
- unsigned char result[4];
* } `; x8 ^9 Q# Z- H2 P- p - ( ` j9 Y! `, h3 N# r/ V
- for (i = 0; i < 4; i++, pState += 4)
4 I3 V% A+ b2 h! V - {0 J% R( t4 c' v2 m
- // b0 = 2a0 + 3a1 + a2 + a3
1 }; K5 B8 e6 |4 H - // = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0! B6 m4 w) J# ~5 s
- : R: V3 r5 p4 L f+ E: `
- temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
/ g) S- R; {" p0 J7 {' i - result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));+ M l( j# G( P
- result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
0 @& C0 ?7 X& d3 k; A( ] - result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));
7 U' v F' J. s) w1 k5 g+ A: V - result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));: W' q+ ?, d" g- ~: |0 p
) O& k7 U; m2 o0 P) P# h- if (bInvert)2 L3 `6 ^" @6 c* |2 q0 `) G, Q
- {
# e8 N7 Y/ `5 t* D: R4 r# ^# C - // b0' = 14a0 + 11a1 + 13a2 + 9a3 + ]; ]2 k7 e4 c. B5 {! y
- // = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0 (这部分为b0)
* A$ D V7 c1 r" V - // + 2(4(a0 + a2) + 4(a1 + a3))4 i! ?$ @8 u! j/ F
- // + 4(a0 + a2)
* n+ ]! |6 b$ V' o7 r
& {0 u9 X8 i8 _# @- a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));; `) `' P6 G: ~+ c' B
- a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));
% L9 ^. e2 o# J" i - temp = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));) ?2 R1 \: M: }3 ^5 }
- result[0] ^= temp ^ a0Pa2_M4;1 K6 i- Y! L: n' D0 F& M8 c
- result[1] ^= temp ^ a1Pa3_M4;
( u* r; c9 {" f+ _ - result[2] ^= temp ^ a0Pa2_M4;
# p* |5 G6 @8 d& B) \ - result[3] ^= temp ^ a1Pa3_M4;
; K4 e3 V+ O X; O' T) p v7 G0 { - }4 h0 M! e( V/ [
- + j- j0 S, o- v' ^. J
- memcpy(pState, result, 4);& b4 k, X' o/ @* M* Q7 Y
- }
& [5 n0 P8 h' {7 s% C7 K+ Y - }( J. i* F+ U) B. g8 g2 x% ?3 [1 h
- % k X+ \- D: `
- ///
" c+ v6 P) @9 {9 S - // 函数名: block_encrypt
1 x+ {/ T) D/ f* e0 _ - // 描述: 对单块数据加密。
; \. O2 g1 }& m+ l- K4 k( _ - // 输入参数: pState -- 状态数据。
9 V3 f" ~' @5 ~ - // 输出参数: pState -- 加密后的状态数据。3 q5 v5 y2 T, ]/ ?" @2 Q% s# n
- // 返回值: 无。
; E' k- Y$ Q$ z: t$ r' } - ///" W" e& S8 ^8 ?! H% x+ w6 U Q
- static void block_encrypt(unsigned char *pState)
1 s# [1 _! g) L6 r9 U - {/ e, k6 q' S9 a: e9 \# c
- unsigned char i;
' S" D) v. U. [3 a$ ^ - + k& d& C ~0 ~ D
- AddRoundKey(pState, g_roundKeyTable);
2 B9 @& V( l$ T4 y- V7 u - 5 ]% p) |4 J: a# w4 p7 _; ~
- for (i = 1; i <= Nr; i++) // i = [1, Nr]0 M1 d( b$ e1 u( a- o B
- {0 p1 c! R+ `1 K% v
- sub_bytes(pState, 4*Nb, 0);8 G3 a5 G7 @8 V$ ~0 t
- shift_rows(pState, 0); F$ [% W2 @1 z- ]3 m* b" g0 e, p
' D& s+ u9 D7 u* h1 u1 w. b% B- if (i != Nr)) O' b! X0 d6 k/ ] K" R. z
- {
! ]- c2 x) O Y - mix_columns(pState, 0);/ p1 K3 l. h0 L, k( E5 [7 B! j2 m/ ?
- }
1 m& `2 C6 Q: P6 D( }5 | - * y" g: z" V. _5 u& W
- AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);/ Y, }' e6 n% ^) b
- }4 _, {' b% l* s
- / ~: W& x+ n- E1 [; G( T! J
- // 为了节省代码,合并到循化执行# e. B2 d" N4 }
- // sub_bytes(pState, 4*Nb);) h/ i' ~0 c1 @' H% e. u
- // shift_rows(pState, 0);
5 h6 ]1 l4 J/ p; | - // AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
% s4 W H- t/ l1 K! F - }
( R& c6 C6 @& J$ ^ - 2 r+ C3 o( X% Z
- ///
, f. R/ z6 p% \ - // 函数名: block_decrypt/ q1 y8 G0 f2 H7 r$ c( r
- // 描述: 对单块数据解密。
- r' y3 R2 d& E1 ~) ~- | - // 输入参数: pState -- 状态数据。
- a8 G& q( D& d+ l( O - // 输出参数: pState -- 解密后的状态数据。4 D7 y1 ?7 V y
- // 返回值: 无。* q( Y! f8 b: A6 I% }$ c Z
- ///1 l6 F1 X! ?8 P& Z3 D
- static void block_decrypt(unsigned char *pState)& e4 G) n' D- X# `( n# m( J# C
- {
0 F# ~+ p, o4 [9 @$ d - unsigned char i;0 L, d6 p# F1 B1 N4 R1 e: {
- 7 T" q$ N6 Y2 A4 E
- AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
: ?8 _2 N+ ~: Z - - M/ |( x1 S6 l' V% D
- for (i = Nr; i > 0; i--) // i = [Nr, 1]* a. U! r6 f* Q" e5 r* {- r( G
- {4 y( g$ F, I: ]6 |/ \+ c- z8 C
- shift_rows(pState, 1);: W! ^* `6 J; ?! ?" _( [4 Q6 a
- sub_bytes(pState, 4*Nb, 1);
" {# a1 J' s/ q0 g2 w - AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);
7 ^ ]5 B* d$ ^% r& Q) z! V" U+ N - , r- C$ J6 p* b7 U
- if (i != 1)# n$ f9 w O. N/ ?( f4 v
- {9 c) m4 S0 Q' K+ K
- mix_columns(pState, 1);
% F) V, U1 O) b g' w5 Z+ a6 K+ J - }
4 w8 ]- i1 L7 t! Z/ R7 B- u2 o/ y- ` - }
2 F3 E) I0 V$ Y. | -
: |9 v% ^' z1 C! [8 z$ I. g! Q2 J - // 为了节省代码,合并到循化执行' R# r4 p6 ^' R" Y. [
- // shift_rows(pState, 1);
. f: c/ R8 m. m! j% q - // sub_bytes(pState, 4*Nb, 1);
& Z& ]7 A7 h2 f3 s- M, e6 x7 @ - // AddRoundKey(pState, g_roundKeyTable);, ^0 H# E) B. ~+ h9 g c: b1 {
- }; T! u/ |9 J; }1 o6 p
4 f7 i+ y/ L1 y T- /*****************************************************************************
/ P, o: }9 Q% L( x; n - * Global Functions 全局函数6 h0 w# o4 ?8 [- `" V8 a" c4 u- _
- ******************************************************************************/2 o' h+ @2 z/ O3 }! t
1 L! I6 ~& B% B/ }- s
' {1 ^/ J! {& d. Y- ///2 d: |, p7 M, Z& {8 X
- // 函数名: aes_init! }, \5 U6 A$ ? i+ u1 x
- // 描述: 初始化,在此执行扩展密钥操作。
4 e9 C/ w1 l) z2 ?" K& o0 T - // 输入参数: pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
+ V% S6 s/ w5 d$ b9 n d1 v4 }; b - // 输出参数: 无。
8 X9 }7 F; h5 U. V5 ]; N - // 返回值: 无。
4 N6 B+ n$ u x4 Y: G; \ - ///
8 M4 c- p2 A! p4 Y2 } - void aes_init(const void *pKey)
. l. p! p* ^- u- o3 Z - {! Z% f& t4 w! S4 B
- // 扩展密钥( ~& ]3 F! ~" }
- unsigned char i;2 ]9 y/ S' m; l" c
- unsigned char *pRoundKey;- b. @% X2 f& w! }. L1 @
- unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
, L1 s+ Q& F+ e: h6 G2 H5 T - ' ?% \; x! _) S, g
- memcpy(g_roundKeyTable, pKey, 4*Nk);2 S4 K+ D# d9 e# G* D% S
; W- n6 V8 G$ _' p" @& H8 L- pRoundKey = &g_roundKeyTable[4*Nk];7 }" ?+ J8 b# y$ f6 H
- " s s7 B# p. w: k4 f% z% Q3 U
- for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)
9 B' `: b* r# b# F1 j - {
( J# L3 g" y+ P' l7 w0 \ - memcpy(pRoundKey, pRoundKey - 4, 4);0 m* I5 w4 r: c3 J( i9 r7 |
, c8 A8 V- z$ d; s( K/ R8 a4 \- if (i % Nk == 0)5 q4 `& Y2 ^; l
- {
. ?& x! u7 D- f- u& b - rotation_word(pRoundKey);
; d8 \) C/ `* E. b0 H) q8 A - sub_bytes(pRoundKey, 4, 0);
- I% b6 A; u# B6 @' _0 Z, ] - xor_bytes(pRoundKey, Rcon, 4);
% {& W+ a5 A) w1 v - " e X6 e5 L. ^" {5 n
- Rcon[0] = gf_mult_by02(Rcon[0]); v4 d2 X! z2 x
- }
! d6 |# ^. D5 w- D3 ?* H - else if (Nk > 6 && i % Nk == Nb)4 G6 x# E! ?1 _' d
- {6 c8 N8 B3 J7 n, h& B" F' T
- sub_bytes(pRoundKey, 4, 0);" G8 U: w0 {- S+ F
- }* d$ s: V$ R2 x8 Z
- e0 C9 q, }- E
- xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);
7 d) g" C: {% O- R" i# y" d - }
3 O* R/ I1 f P& b0 V6 z+ @0 H - }" T" a) x# V$ N
; ^$ I- B$ u3 b {7 [$ L2 s- //. O$ e; R' W/ W( f/ k8 A! `# H
- // 函数名: aes_encrypt4 c: g! n4 `5 i6 f' |3 ~
- // 描述: 加密数据+ o! C# R. z9 ^0 T$ q; b1 i7 p
- // 输入参数: pPlainText -- 明文,即需加密的数据,其长度为nDataLen字节。7 M: g8 o1 {- ]) Z
- // nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。+ U* x# j! V, K
- // pIV -- 初始化向量,如果使用ECB模式,可设为NULL。/ ]! v$ A$ ]1 P9 R# y O
- // 输出参数: pCipherText -- 密文,即由明文加密后的数据,可以与pPlainText相同。
6 h4 X/ V7 I0 S1 J - // 返回值: 无。
) k4 ?1 l% P/ M( f. Y4 @3 ` - //' B2 R6 {. s, z1 [1 g! I# P
- void aes_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
% I; G p- ?. j' |4 ~2 v - unsigned int nDataLen, const unsigned char *pIV)! n& d( N4 y# \& a
- {
8 I! r8 I% `4 ]2 `& D" t; @* x - unsigned int i;, k8 q5 F# X/ h; S$ |
7 p. m1 ]) I9 i" v, v2 S- y- if (pPlainText != pCipherText)( [- f* H2 m9 ]+ j) i& `
- {' ?4 U% g, v) {3 |
- memcpy(pCipherText, pPlainText, nDataLen);) o) G# F0 S. {$ a# d) y
- }
2 ^* i! U4 g. q& g
& W2 y2 M( c) x: t/ c- for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
P) h0 g5 v/ W: h m& R - {$ X- s$ @- E" O+ z; r' D
- #if AES_MODE == AES_MODE_CBC4 y8 h M6 E' A o) e$ |6 y
- xor_bytes(pCipherText, pIV, 4*Nb);/ }2 ~% q! w6 f, F
- #endif" h3 e( _1 X0 \0 R
- ; z% s; | X& _% T% D, t# R+ {
- block_encrypt(pCipherText);8 M+ {9 l# ^# L* D! C2 m
- pIV = pCipherText;
# `: u' F8 o0 V" a7 R; Z - }
2 M, S) K J$ j7 @ - }3 s% w* v2 H9 D0 s- @
% l$ ~: D: |) D- R5 p% P- //
' d+ h% }/ S6 K, o0 h( m! V: H - // 函数名: aes_decrypt+ L. K8 \) Z6 i9 X, {/ W9 g
- // 描述: 解密数据* K& N0 P+ f6 V/ n1 J4 d6 s+ \+ H
- // 输入参数: pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。7 e* @' ~# d: X: a* [* B
- // nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。2 |7 m8 X+ y/ N8 B8 J: l
- // pIV -- 初始化向量,如果使用ECB模式,可设为NULL。/ w2 s; T8 d1 X
- // 输出参数: pPlainText -- 明文,即由密文解密后的数据,可以与pCipherText相同。
8 Q: o- g# T" H) V1 [ W - // 返回值: 无。) w8 H7 B( u1 r4 H4 S
- //
( f- m: F) D3 S& s9 I - void aes_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
$ U- Q3 ~6 J2 C6 h - unsigned int nDataLen, const unsigned char *pIV)
4 T% i" \) h, o. W, H - {; T& ]- D- H$ _
- unsigned int i;
! h1 n% p( Z% R2 M- c
" R1 z+ ]3 O$ H- if (pPlainText != pCipherText)( l: `" B9 G# k! l
- {* G2 K0 W$ m: K! D
- memcpy(pPlainText, pCipherText, nDataLen);; _" X" u- q. L, H' N
- }* |- r! o4 ^: S! G4 L* W
- 0 p' `3 l% q: b
- // 从最后一块数据开始解密,这样不用开辟空间来保存IV
8 n) W* [6 G, H8 S' L - pPlainText += nDataLen - 4*Nb;
; E- A& x% h$ y! A: x - for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb). ?- \3 E$ }& f8 x
- {5 s T: m; e8 `
- block_decrypt(pPlainText);5 @2 u6 r% B/ X6 I9 U3 h
: q$ C, P- W. d4 I* P- #if AES_MODE == AES_MODE_CBC3 \1 f/ w; c5 K
- if (i == 1)1 u! p9 X' F2 e2 h2 L
- {// 最后一块数据$ l" I$ e r( {$ \: c4 x- u% l0 P' g
- xor_bytes(pPlainText, pIV, 4*Nb);" J8 _. X) n4 J! b) I5 T5 b# ?
- }
8 n/ P1 \; D- y5 v% m7 n - else/ O* @9 p2 a# _5 Y2 Q9 x0 G
- {
" k) o% O" y8 S9 Q# j1 c8 F U - xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);3 F# B6 T% t: g% b
- }; U% o5 U- \6 \* G! X8 x
- #endif
0 N# [( N4 i; Y q1 ^$ l - }: k4 Y- ^+ g }; ~" M, l" Z
- }</i></i></i></i>
复制代码 ' J4 G6 F1 a$ B- h p$ M
三、使用8 B: b+ N1 u) M8 \) x- E
使用注意点:
( W2 k2 m. A, L+ y1、AES_KEY_LENGTH取值只能是128,192 和 256
% X$ e" @* Z1 b7 e. b, x. C2、密钥和向量表长度为AES_KEY_LENGTH/8个字节
1 g7 X( g8 X% {& u6 }! ~3 |3、加密、解密数据长度为AES_KEY_LENGTH/8的整数倍字节6 j9 o* p. t7 R7 K: C, b
7 D$ q6 N0 n. r- R8 u" N; W
1 H: L+ \" Q7 s, v$ \6 l3 M: _
- int main(void)# n5 m- ]: j. e/ R9 P
- {
/ T% Y+ _ D+ r. ^ - u8 buf[16],saveBuf[16],descryptBuf[16];6 ~9 D( g- L* r- o! C
- u16 i;6 t! W' R* E. \) V; ?
- unsigned char AES128key[16] = "123456789abcdefa";//秘钥) p. K; c! j' u$ b1 y
- unsigned char AES_IV[16]= "0102030405123456";//向量表
. g/ _" ]3 f. D0 V ^0 B% n - delay_init(168); //初始化延时函数; j9 h/ j# s* b, R N8 `$ m
- LED_Init(); //初始化LED端口9 K1 r# ?5 k7 k1 u
- ?: m+ K4 @: S4 G0 \
- aes_init(AES128key);//AES初始化
& k. [! P5 \4 s2 q4 Y -
! ]: l: V% \8 |: n - for(i=0;i<sizeof(buf);i++)
1 `% L4 ?: k( r; c5 P* a! Z( _ - {3 m: Q0 U9 z1 S4 d, i: Z6 [, F- l
- buf=i;
: ]- W! ]' V: G& [' ? M - }
$ P- O5 _; W' z& F4 o3 r5 o9 L6 l - while(1)
& b9 H0 S' ~* P' W - {- E/ e3 P4 }0 H$ }. ^# b- A
- aes_encrypt(buf,saveBuf,sizeof(buf), AES_IV);0 {* S. z, ~( ^+ Z# I
- 8 O5 {. E& z& ]0 j% q a1 E0 p+ E
- & Y* [* k/ T/ k9 g! l- z: P; e
- aes_decrypt(saveBuf,descryptBuf, sizeof(buf), AES_IV);
Y- T6 U7 D& W' r6 h+ i9 a' x - - A! `" ~9 [; \! z
- # C3 n' S# A$ B
- GPIO_ResetBits(GPIOF,GPIO_Pin_9); //LED0对应引脚GPIOF.9拉低,亮 等同LED0=0;" R: ^" E7 ~) ~4 U7 }
- GPIO_SetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉高,灭 等同LED1=1;
: e' f% e1 w ? - delay_ms(500); //延时300ms, @ _$ `* F' }
- GPIO_SetBits(GPIOF,GPIO_Pin_9); //LED0对应引脚GPIOF.0拉高,灭 等同LED0=1;% U; b7 v( X+ P2 [
- GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1对应引脚GPIOF.10拉低,亮 等同LED1=0;
+ D6 F( i6 I/ Q$ c3 {0 ~ - delay_ms(500); //延时300ms" X% u* J: }: s% G
- }
6 n6 W" w1 \- z- K2 _ - } j: Z1 y' {: _" o* p. X+ r
5 \* ]; Y' ^& D& `& S$ _4 Y
: X; X7 y8 R( h6 R
复制代码
$ @' e. X# }! @ |
AES加密这么复杂?