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