《AES加密C语言实现代码.doc》由会员分享,可在线阅读,更多相关《AES加密C语言实现代码.doc(12页珍藏版)》请在三一办公上搜索。
1、#define BPOLY 0x1b /! Lower 8 bits of (x8+x4+x3+x+1), ie. (x4+x3+x+1).#define BLOCKSIZE 16 /! Block size in number of bytes.#define KEY_COUNT 3#if KEY_COUNT = 1 #define KEYBITS 128 /! Use AES128.#elif KEY_COUNT = 2 #define KEYBITS 192 /! Use AES196.#elif KEY_COUNT = 3 #define KEYBITS 256 /! Use AES2
2、56.#else #error Use 1, 2 or 3 keys!#endif#if KEYBITS = 128 #define ROUNDS 10 /! Number of rounds. #define KEYLENGTH 16 /! Key length in number of bytes.#elif KEYBITS = 192 #define ROUNDS 12 /! Number of rounds. #define KEYLENGTH 24 /! / Key length in number of bytes.#elif KEYBITS = 256 #define ROUND
3、S 14 /! Number of rounds. #define KEYLENGTH 32 /! Key length in number of bytes.#else #error Key must be 128, 192 or 256 bits!#endif#define EXPANDED_KEY_SIZE (BLOCKSIZE * (ROUNDS+1) /! 176, 208 or 240 bytes.unsigned char AES_Key_Table32 = 0xd0, 0x94, 0x3f, 0x8c, 0x29, 0x76, 0x15, 0xd8, 0x20, 0x40, 0
4、xe3, 0x27, 0x45, 0xd8, 0x48, 0xad, 0xea, 0x8b, 0x2a, 0x73, 0x16, 0xe9, 0xb0, 0x49, 0x45, 0xb3, 0x39, 0x28, 0x0a, 0xc3, 0x28, 0x3c,;unsigned char block1256; /! Workspace 1.unsigned char block2256; /! Worksapce 2.unsigned char tempbuf256;unsigned char *powTbl; /! Final location of exponentiation looku
5、p table.unsigned char *logTbl; /! Final location of logarithm lookup table.unsigned char *sBox; /! Final location of s-box.unsigned char *sBoxInv; /! Final location of inverse s-box.unsigned char *expandedKey; /! Final location of expanded key.void CalcPowLog(unsigned char *powTbl, unsigned char *lo
6、gTbl)unsigned char i = 0;unsigned char t = 1;do / Use 0x03 as root for exponentiation and logarithms.powTbli = t;logTblt = i;i+;/ Muliply t by 3 in GF(28).t = (t 1) (t & 0x80 ? BPOLY : 0);while( t != 1 ); / Cyclic properties ensure that i 0 ) temp = powTbl 255 - logTbli ; else temp = 0;/ Affine tran
7、sformation in GF(2).result = temp 0x63; / Start with adding a vector in GF(2).for( rot = 0; rot 4; rot+ )/ Rotate left.temp = (temp7);/ Add rotated byte in GF(2).result = temp;/ Put result in table.sBoxi = result; while( +i != 0 );void CalcSBoxInv( unsigned char * sBox, unsigned char * sBoxInv )unsi
8、gned char i = 0;unsigned char j = 0;/ Iterate through all elements in sBoxInv using i.do / Search through sBox using j.do / Check if current j is the inverse of current i.if( sBox j = i )/ If so, set sBoxInc and indicate search finished.sBoxInv i = j;j = 255; while( +j != 0 ); while( +i != 0 );void
9、CycleLeft( unsigned char * row )/ Cycle 4 bytes in an array left once.unsigned char temp = row0;row0 = row1;row1 = row2;row2 = row3;row3 = temp;void InvMixColumn( unsigned char * column )unsigned char r0, r1, r2, r3;r0 = column1 column2 column3;r1 = column0 column2 column3;r2 = column0 column1 colum
10、n3;r3 = column0 column1 column2;column0 = (column0 1) (column0 & 0x80 ? BPOLY : 0);column1 = (column1 1) (column1 & 0x80 ? BPOLY : 0);column2 = (column2 1) (column2 & 0x80 ? BPOLY : 0);column3 = (column3 1) (column3 & 0x80 ? BPOLY : 0);r0 = column0 column1;r1 = column1 column2;r2 = column2 column3;r
11、3 = column0 column3;column0 = (column0 1) (column0 & 0x80 ? BPOLY : 0);column1 = (column1 1) (column1 & 0x80 ? BPOLY : 0);column2 = (column2 1) (column2 & 0x80 ? BPOLY : 0);column3 = (column3 1) (column3 & 0x80 ? BPOLY : 0);r0 = column0 column2;r1 = column1 column3;r2 = column0 column2;r3 = column1
12、column3;column0 = (column0 1) (column0 & 0x80 ? BPOLY : 0);column1 = (column1 1) (column1 & 0x80 ? BPOLY : 0);column2 = (column2 1) (column2 & 0x80 ? BPOLY : 0);column3 = (column3 1) (column3 & 0x80 ? BPOLY : 0);column0 = column1 column2 column3;r0 = column0;r1 = column0;r2 = column0;r3 = column0;co
13、lumn0 = r0;column1 = r1;column2 = r2;column3 = r3;void SubBytes( unsigned char * bytes, unsigned char count )do *bytes = sBox *bytes ; / Substitute every byte in state.bytes+; while( -count );void InvSubBytesAndXOR( unsigned char * bytes, unsigned char * key, unsigned char count )do / *bytes = sBoxI
14、nv *bytes *key; / Inverse substitute every byte in state and add key.*bytes = block2 *bytes *key; / Use block2 directly. Increases speed.bytes+;key+; while( -count );void InvShiftRows( unsigned char * state )unsigned char temp;/ Note: State is arranged column by column./ Cycle second row right one t
15、ime.temp = state 1 + 3*4 ;state 1 + 3*4 = state 1 + 2*4 ;state 1 + 2*4 = state 1 + 1*4 ;state 1 + 1*4 = state 1 + 0*4 ;state 1 + 0*4 = temp;/ Cycle third row right two times.temp = state 2 + 0*4 ;state 2 + 0*4 = state 2 + 2*4 ;state 2 + 2*4 = temp;temp = state 2 + 1*4 ;state 2 + 1*4 = state 2 + 3*4
16、;state 2 + 3*4 = temp;/ Cycle fourth row right three times, ie. left once.temp = state 3 + 0*4 ;state 3 + 0*4 = state 3 + 1*4 ;state 3 + 1*4 = state 3 + 2*4 ;state 3 + 2*4 = state 3 + 3*4 ;state 3 + 3*4 = temp;void InvMixColumns( unsigned char * state )InvMixColumn( state + 0*4 );InvMixColumn( state
17、 + 1*4 );InvMixColumn( state + 2*4 );InvMixColumn( state + 3*4 );void XORBytes( unsigned char * bytes1, unsigned char * bytes2, unsigned char count )do *bytes1 = *bytes2; / Add in GF(2), ie. XOR.bytes1+;bytes2+; while( -count );void CopyBytes( unsigned char * to, unsigned char * from, unsigned char
18、count )do *to = *from;to+;from+; while( -count );void KeyExpansion( unsigned char * expandedKey )unsigned char temp4;unsigned char i;unsigned char Rcon4 = 0x01, 0x00, 0x00, 0x00 ; / Round constant.unsigned char * key = AES_Key_Table;/ Copy key to start of expanded key.i = KEYLENGTH;do *expandedKey =
19、 *key;expandedKey+;key+; while( -i );/ Prepare last 4 bytes of key in temp.expandedKey -= 4;temp0 = *(expandedKey+);temp1 = *(expandedKey+);temp2 = *(expandedKey+);temp3 = *(expandedKey+);/ Expand key.i = KEYLENGTH;while( i BLOCKSIZE*(ROUNDS+1) ) / Are we at the start of a multiple of the key size?i
20、f( (i % KEYLENGTH) = 0 )CycleLeft( temp ); / Cycle left once.SubBytes( temp, 4 ); / Substitute each byte.XORBytes( temp, Rcon, 4 ); / Add constant in GF(2).*Rcon = (*Rcon 24/ Are we right past a block size?else if( (i % KEYLENGTH) = BLOCKSIZE ) SubBytes( temp, 4 ); / Substitute each byte.#endif/ Add
21、 bytes in GF(2) one KEYLENGTH away.XORBytes( temp, expandedKey - KEYLENGTH, 4 );/ Copy result to current 4 bytes.*(expandedKey+) = temp 0 ;*(expandedKey+) = temp 1 ;*(expandedKey+) = temp 2 ;*(expandedKey+) = temp 3 ;i += 4; / Next 4 bytes.void InvCipher( unsigned char * block, unsigned char * expan
22、dedKey )unsigned char round = ROUNDS-1;expandedKey += BLOCKSIZE * ROUNDS;XORBytes( block, expandedKey, 16 );expandedKey -= BLOCKSIZE;do InvShiftRows( block );InvSubBytesAndXOR( block, expandedKey, 16 );expandedKey -= BLOCKSIZE;InvMixColumns( block ); while( -round );InvShiftRows( block );InvSubBytes
23、AndXOR( block, expandedKey, 16 );void aesDecInit(void)powTbl = block1;logTbl = block2;CalcPowLog( powTbl, logTbl );sBox = tempbuf;CalcSBox( sBox );expandedKey = block1;KeyExpansion( expandedKey );sBoxInv = block2; / Must be block2.CalcSBoxInv( sBox, sBoxInv );void aesDecrypt( unsigned char * buffer,
24、 unsigned char * chainBlock )unsigned char temp BLOCKSIZE ;CopyBytes( temp, buffer, BLOCKSIZE );InvCipher( buffer, expandedKey );XORBytes( buffer, chainBlock, BLOCKSIZE );CopyBytes( chainBlock, temp, BLOCKSIZE );unsigned char Multiply( unsigned char num, unsigned char factor )unsigned char mask = 1;
25、unsigned char result = 0;while( mask != 0 ) / Check bit of factor given by mask.if( mask & factor ) / Add current multiple of num in GF(2). result = num;/ Shift mask to indicate next bit.mask = 1;/ Double num.num = (num 1) (num & 0x80 ? BPOLY : 0);return result;unsigned char DotProduct( unsigned cha
26、r * vector1, unsigned char * vector2 )unsigned char result = 0;result = Multiply( *vector1+, *vector2+ );result = Multiply( *vector1+, *vector2+ );result = Multiply( *vector1+, *vector2+ );result = Multiply( *vector1 , *vector2 );return result;void MixColumn( unsigned char * column )unsigned char ro
27、w8 = 0x02, 0x03, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01; / Prepare first row of matrix twice, to eliminate need for cycling.unsigned char result4;/ Take dot products of each matrix row and the column vector.result0 = DotProduct( row+0, column );result1 = DotProduct( row+3, column );result2 = DotProduct(
28、 row+2, column );result3 = DotProduct( row+1, column );/ Copy temporary result to original column.column0 = result0;column1 = result1;column2 = result2;column3 = result3;void MixColumns( unsigned char * state )MixColumn( state + 0*4 );MixColumn( state + 1*4 );MixColumn( state + 2*4 );MixColumn( stat
29、e + 3*4 );void ShiftRows( unsigned char * state )unsigned char temp;/ Note: State is arranged column by column./ Cycle second row left one time.temp = state 1 + 0*4 ;state 1 + 0*4 = state 1 + 1*4 ;state 1 + 1*4 = state 1 + 2*4 ;state 1 + 2*4 = state 1 + 3*4 ;state 1 + 3*4 = temp;/ Cycle third row le
30、ft two times.temp = state 2 + 0*4 ;state 2 + 0*4 = state 2 + 2*4 ;state 2 + 2*4 = temp;temp = state 2 + 1*4 ;state 2 + 1*4 = state 2 + 3*4 ;state 2 + 3*4 = temp;/ Cycle fourth row left three times, ie. right once.temp = state 3 + 3*4 ;state 3 + 3*4 = state 3 + 2*4 ;state 3 + 2*4 = state 3 + 1*4 ;sta
31、te 3 + 1*4 = state 3 + 0*4 ;state 3 + 0*4 = temp;void Cipher( unsigned char * block, unsigned char * expandedKey )unsigned char round = ROUNDS-1;XORBytes( block, expandedKey, 16 );expandedKey += BLOCKSIZE;do SubBytes( block, 16 );ShiftRows( block );MixColumns( block );XORBytes( block, expandedKey, 1
32、6 );expandedKey += BLOCKSIZE; while( -round );SubBytes( block, 16 );ShiftRows( block );XORBytes( block, expandedKey, 16 );void aesEncInit(void)powTbl = block1;logTbl = tempbuf;CalcPowLog( powTbl, logTbl );sBox = block2;CalcSBox( sBox );expandedKey = block1;KeyExpansion( expandedKey );void aesEncrypt
33、( unsigned char * buffer, unsigned char * chainBlock )XORBytes( buffer, chainBlock, BLOCKSIZE );Cipher( buffer, expandedKey );CopyBytes( chainBlock, buffer, BLOCKSIZE );#include void AES_Test(void)unsigned char dat16=0123456789ABCDEF;unsigned char chainCipherBlock16; unsigned char i;for(i=0;i32;i+)
34、AES_Key_Tablei=i;/做运算之前先要设置好密钥,这里只是设置密钥的DEMO。memset(chainCipherBlock,0x00,sizeof(chainCipherBlock);aesEncInit();/在执行加密初始化之前可以为AES_Key_Table赋值有效的密码数据aesEncrypt(dat, chainCipherBlock);/AES加密,数组dat里面的新内容就是加密后的数据。/aesEncrypt(dat+16, chainCipherBlock);/AES源数据大于16字节时,把源数据的指针+16就好了memset(chainCipherBlock,0x00,sizeof(chainCipherBlock);/这里要重新初始化清空aesDecInit();/在执行解密初始化之前可以为AES_Key_Table赋值有效的密码数据aesDecrypt(dat, chainCipherBlock);/AES解密,密文数据存放在dat里面,经解密就能得到之前的明文。/aesDecrypt(dat+16, chainCipherBlock);/AES源数据大于16字节时,把源数据的指针+16就好了