📄 aes.c
字号:
/*
Cryptosystem for 128 bits plaintext block.
*/
#include "StdAfx.h"
#include "stdio.h"
typedef unsigned char u1byte;
typedef unsigned long u4byte;
#define LARGE_TABLE 0
u1byte pow_tab[256];
u1byte log_tab[256];
u1byte sbx_tab[256];
u1byte isb_tab[256];
u4byte rco_tab[10];
u4byte ft_tab[4][256];
u4byte it_tab[4][256];
#ifdef LARGE_TABLE
u4byte fl_tab[4][256];
u4byte il_tab[4][256];
#endif
u4byte tab_gen=0;
u4byte k_len;
u4byte e_key[60];
u4byte d_key[60];
#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a]+log_tab[b])%255]:0)
#define byte(x,n) ((u1byte)((x)>>(8*n)))
#define f_rn(bo,bi,n,k) \
bo[n]=ft_tab[0][byte(bi[n],0)]^ \
ft_tab[1][byte(bi[(n+1)&3], 1)]^ \
ft_tab[2][byte(bi[(n+2)&3], 2)]^ \
ft_tab[3][byte(bi[(n+3)&3], 3)]^ *(k+n)
#define i_rn(bo,bi,n,k) \
bo[n]=it_tab[0][byte(bi[n],0)]^ \
it_tab[1][byte(bi[(n+3)&3], 1)]^ \
it_tab[2][byte(bi[(n+2)&3], 2)]^ \
it_tab[3][byte(bi[(n+1)&3], 3)]^ *(k+n)
#define rotr(x,n) (((x)>>((int)(n))) | ((x)<<(32-(int)(n))))
#define rotl(x,n) (((x)<<((int)(n))) | ((x)>>(32-(int)(n))))
#ifdef LARGE_TABLES
#define ls_box(x) \
(fl_tab[0][byte(x,0)]^fl_tab[1][byte(x,1)]^ \
fl_tab[2][byte(x,2)]^fl_tab[3][byte(x,3)])
#define f_rl(bo,bi,n,k) \
bo[n]=fl_tab[0][byte(bi[n],0)]^ \
fl_tab[1][byte(bi[(n+1)&3], 1)]^ \
fl_tab[2][byte(bi[(n+2)&3], 2)]^ \
fl_tab[3][byte(bi[(n+3)&3], 3)]^ *(k+n)
#define i_rn(bo,bi,n,k) \
bo[n]=il_tab[0][byte(bi[n],0)]^ \
il_tab[1][byte(bi[(n+3)&3], 1)]^ \
il_tab[2][byte(bi[(n+2)&3], 2)]^ \
il_tab[3][byte(bi[(n+1)&3], 3)]^ *(k+n)
#else
#define ls_box(x) \
((u4byte)sbx_tab[byte(x,0)]<<0)^((u4byte)sbx_tab[byte(x,1)]<<8)^ \
((u4byte)sbx_tab[byte(x,2)]<<16)^((u4byte)sbx_tab[byte(x,3)]<<24)
#define f_rl(bo,bi,n,k) \
bo[n]=(u4byte)sbx_tab[byte(bi[n],0)] ^ \
rotl(((u4byte)sbx_tab[byte(bi[(n+1)&3],1)]),8) ^ \
rotl(((u4byte)sbx_tab[byte(bi[(n+2)&3],2)]),16) ^ \
rotl(((u4byte)sbx_tab[byte(bi[(n+3)&3],3)]),24) ^*(k+n)
#define i_rl(bo,bi,n,k) \
bo[n]=(u4byte)isb_tab[byte(bi[n],0)] ^ \
rotl(((u4byte)isb_tab[byte(bi[(n+3)&3],1)]),8) ^ \
rotl(((u4byte)isb_tab[byte(bi[(n+2)&3],2)]),16) ^ \
rotl(((u4byte)isb_tab[byte(bi[(n+1)&3],3)]),24) ^*(k+n)
#endif
void gen_tabs(void)
{
u4byte i, t;
u1byte p, q;
for(i=0, p=1; i<256; ++i)
{
pow_tab[i]=(u1byte)p;
log_tab[p]=(u1byte)i;
p=p^(p<<1)^(p & 0x80 ? 0x1b :0);
}
log_tab[1]=0; p=1;
for(i=0; i<10; ++i)
{
rco_tab[i]=p;
p=(p<<1)^(p & 0x80 ? 0x1b :0);
}
for(i=0; i<256; ++i)
{
p=(i? pow_tab[255-log_tab[i]]: 0);
q=p;
q=(q>>7) | (q<<1);
p^=q;
q=(q>>7) | (q<<1);
p^=q;
q=(q>>7) | (q<<1);
p^=q;
q=(q>>7) | (q<<1);
p^=q^0x63;
sbx_tab[i]=(u1byte)p;
isb_tab[p]=(u1byte)i;
}
for(i=0; i<256; ++i)
{
p=sbx_tab[i];
#ifdef LARGE_TABLES
t=p;
f1_tab[0][i]=t;
f1_tab[1][i]=rot1(t, 8);
f1_tab[2][i]=rot1(t, 16);
f1_tab[3][i]=rot1(t, 24);
#endif
t=((u4byte)ff_mult(2,p))|((u4byte)p<<8)|
((u4byte)p<<16)|((u4byte)ff_mult(3,p)<<24);
ft_tab[0][i]=t;
ft_tab[1][i]=rotl(t,8);
ft_tab[2][i]=rotl(t,16);
ft_tab[3][i]=rotl(t,24);
p=isb_tab[i];
#ifdef LARGE_TABLES
t=p; il_tab[0][i]=t; il_tab[1][i]=rotl(t,8);
il_tab[2][i]=rotl(t,16);il_tab[3][i]=rotl(t,24);
#endif
t=((u4byte)ff_mult(14,p))|((u4byte)ff_mult(9,p)<<8)|
((u4byte)ff_mult(13,p)<<16)|((u4byte)ff_mult(11,p)<<24);
it_tab[0][i]=t;
it_tab[1][i]=rotl(t,8);
it_tab[2][i]=rotl(t,16);
it_tab[3][i]=rotl(t,24);
}
tab_gen=1;
}
#define star_x(x) (((x)& 0x7f7f7f7f)<<1)^((((x) & 0x80808080)>>7)*0x1b)
#define imix_col(y,x) \
u=star_x(x); v=star_x(u); w=star_x(v);\
t=w^(x); (y)=u^v^w; (y)^=rotr(u^t,8)^rotr(v^t,16)^rotr(t,24)
#define loop6(i) \
{ t=ls_box(rotl(t,8))^rotr(rco_tab[i], 8);\
t^=e_key[6*i]; e_key[6*i+6]=t; \
t^=e_key[6*i+1]; e_key[6*i+7]=t; \
t^=e_key[6*i+2]; e_key[6*i+8]=t; \
t^=e_key[6*i+3]; e_key[6*i+9]=t; \
t^=e_key[6*i+4]; e_key[6*i+10]=t; \
t^=e_key[6*i+5]; e_key[6*i+11]=t; \
}
#define loop8(i) \
{ t=ls_box(rotl(t,8))^rotr(rco_tab[i], 8);\
t^=e_key[8*i]; e_key[8*i+8]=t; \
t^=e_key[8*i+1]; e_key[8*i+9]=t; \
t^=e_key[8*i+2]; e_key[8*i+10]=t; \
t^=e_key[8*i+3]; e_key[8*i+11]=t; \
t^=e_key[8*i+4]^ls_box(t); e_key[8*i+12]=t; \
t^=e_key[8*i+5]; e_key[8*i+13]=t; \
t^=e_key[8*i+6]; e_key[8*i+14]=t; \
t^=e_key[8*i+7]; e_key[8*i+15]=t; \
}
void set_key(const u4byte in_key[], const u4byte key_len)
{
u4byte i, t, u, v, w;
if(!tab_gen)
gen_tabs();
k_len=(key_len+31)/32;
e_key[0]=in_key[0];
e_key[1]=in_key[1];
e_key[2]=in_key[2];
e_key[3]=in_key[3];
switch(k_len)
{
//add round key
case 4: t=e_key[3];
for(i=0; i<10; ++i)
{
t=ls_box(rotr(t,8))^rco_tab[i];
t^=e_key[4*i];
e_key[4*i+4]=t;
t^=e_key[4*i+1];
e_key[4*i+5]=t;
t^=e_key[4*i+2];
e_key[4*i+6]=t;
t^=e_key[4*i+3];
e_key[4*i+7]=t;
};
break;
case 6:
e_key[4]=in_key[4];
t=e_key[5]=in_key[5];
for(i=0; i<8; ++i)
loop6(i);
break;
case 8:
e_key[4]=in_key[4];
e_key[5]=in_key[5];
e_key[6]=in_key[6];
t=e_key[7]=in_key[7];
for(i=0; i<7; ++i)
loop8(i);
break;
}
d_key[0]=e_key[0];
d_key[1]=e_key[1];
d_key[2]=e_key[2];
d_key[3]=e_key[3];
for(i=4; i<4*k_len+24; ++i)
{
imix_col(d_key[i], e_key[i]);
}
}
#define f_nround(bo, bi, k) \
f_rn(bo, bi, 0, k); f_rn(bo, bi, 1, k); \
f_rn(bo, bi, 2, k); f_rn(bo, bi, 3, k); k+=4
#define f_lround(bo, bi, k) \
f_rl(bo, bi, 0, k); f_rl(bo, bi, 1, k); f_rl(bo, bi, 2, k); f_rl(bo, bi, 3, k)
void encrypt(const u4byte in_blk[4], u4byte out_blk[4])
{
u4byte b0[4], b1[4], *kp;
b0[0]=in_blk[0]^e_key[0];
b0[1]=in_blk[1]^e_key[1];
b0[2]=in_blk[2]^e_key[2];
b0[3]=in_blk[3]^e_key[3];
kp=e_key+4;
if(k_len>6)
{
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
}
if(k_len>4)
{
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
}
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
f_nround(b1, b0, kp);
f_nround(b0, b1, kp);
f_nround(b1, b0, kp);
f_lround(b0, b1, kp);
out_blk[0]=b0[0];
out_blk[1]=b0[1];
out_blk[2]=b0[2];
out_blk[3]=b0[3];
}
#define i_nround(bo, bi, k) \
i_rn(bo, bi, 0, k); i_rn(bo, bi, 1, k); \
i_rn(bo, bi, 2, k); i_rn(bo, bi, 3, k); k-=4
#define i_lround(bo, bi, k) \
i_rl(bo, bi, 0, k); i_rl(bo, bi, 1, k); i_rl(bo, bi, 2, k); i_rl(bo, bi, 3, k)
void decrypt(const u4byte in_blk[4], u4byte out_blk[4])
{
u4byte b0[4], b1[4], *kp;
b0[0]=in_blk[0]^e_key[4*k_len+24];
b0[1]=in_blk[1]^e_key[4*k_len+25];
b0[2]=in_blk[2]^e_key[4*k_len+26];
b0[3]=in_blk[3]^e_key[4*k_len+27];
kp=d_key+4*(k_len+5);
if(k_len>6)
{
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
}
if(k_len>4)
{
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
}
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
i_nround(b1, b0, kp);
i_nround(b0, b1, kp);
i_nround(b1, b0, kp);
i_lround(b0, b1, kp);
out_blk[0]=b0[0];
out_blk[1]=b0[1];
out_blk[2]=b0[2];
out_blk[3]=b0[3];
}
//===============================================================================
typedef enum
{
AES_ENCRYPT_128BIT = 128,
AES_ENCRYPT_192BIT = 192,
AES_ENCRYPT_256BIT = 256
} AES_ENC_bit;
#define AES_ENCRYPT_BLOCK 16
/*
*-----------------------------------------------------------------------------------------------------
* int readFromFile(char* path,char** data)
* purpose: This function read a file's content to a len size data by fp.
* Params:
* Input: this file's path , data.
* Output: None.
* Returns: the length of this file.
* Notes: None.
* ----------------------------------------------------------------------------------------------------
*/
char *readFromFile(char* path, int *len)
{
FILE* fp=NULL;
char* data=NULL;
size_t size=0;
if (path == NULL)
return NULL;
if ((fp=fopen(path,"a+")) == NULL)
return NULL;
if (fseek(fp, 0L, SEEK_END) != 0)
goto close_file;
if ((size=ftell(fp)) == -1)
goto close_file;
data = (char*)malloc(size);
if (data == NULL)
goto close_file;
*len = size;
rewind(fp);
if (fread(data,1,size,fp) != size)
goto close_file;
fclose(fp);
return data;
close_file:
fclose(fp);
return NULL;
}
/*
*-----------------------------------------------------------------------------------------------------
* int writeToFile(FILE* fp, char *data, size_t len)
* purpose: This function write a len size data to file pointed by fp.
* Params:
* Input: file's path , data, data length.
* Output: None.
* Returns: Write result.
* Notes: None.
* ----------------------------------------------------------------------------------------------------
*/
int writeToFile(char* path, char* data, size_t len)
{
FILE *fp = NULL;
if (data == NULL)
return 0;
if ((fp=fopen(path,"w+")) == NULL)
return 0;
if (fwrite(data, 1, len, fp) != len)
{
fflush(fp);
return 0;
}
fflush(fp);
return 1;
}
/*
*-----------------------------------------------------------------------------------------------------
* int aes_encrypt(char* file_path, char* cipher_path, char* in_key, int key_len)
* purpose: This function encode the plain file to the cipher file.
* Params:
* Input: plain file'spath, cipher file's path, the secret key , the length of key
* Output: the cipher file.
* Returns: None.
* Notes: None.
* ----------------------------------------------------------------------------------------------------
*/
int aes_encrypt(char* file_path, char* cipher_path, char* key, int key_len)
{
int block_len=0, file_len=0, rest_len = 0;
char *buffer = NULL;
char *exbuffer = NULL;
char *pos;
u4byte in_block[4], out_block[4];
set_key((u4byte*)key, key_len);
if ((buffer = readFromFile(file_path, &file_len)) == NULL)
return 0;
if ((exbuffer = (char *)malloc(file_len + AES_ENCRYPT_BLOCK)) == NULL)
{
free(buffer);
return 0;
}
else
{
memcpy(exbuffer, buffer, file_len);
free(buffer);
}
rest_len = file_len + AES_ENCRYPT_BLOCK;
pos = exbuffer;
while (rest_len)
{
if (rest_len > AES_ENCRYPT_BLOCK)
block_len = AES_ENCRYPT_BLOCK;
else
block_len = rest_len;
memcpy((char*)in_block, pos, block_len);
encrypt(in_block, out_block);
memcpy(pos, (char*)out_block, block_len);
pos += block_len;
rest_len -= block_len;
}
if (writeToFile(cipher_path, exbuffer, file_len + AES_ENCRYPT_BLOCK))
{
free(exbuffer);
return 1;
}
else
{
free(exbuffer);
return 0;
}
}
/*
*-----------------------------------------------------------------------------------------------------
* int aes_decrypt(char* cipher_path, char* file_path, char* in_key, int key_len)
* purpose: This function decode the cipher file to the plain file.
* Params:
* Input: plain file'spath, cipher file's path, the secret key , the length of key
* Output: the plain file.
* Returns: None.
* Notes: None.
* ----------------------------------------------------------------------------------------------------
*/
int aes_decrypt(char* cipher_path, char* file_path, char* key, int key_len)
{
int block_len=0, file_len=0, rest_len = 0;
char *buffer = NULL;
char *pos;
u4byte in_block[4], out_block[4];
set_key((u4byte*)key, key_len);
if ((buffer = readFromFile(cipher_path, &file_len)) == NULL)
return 0;
rest_len = file_len;
pos = buffer;
while (rest_len)
{
if (rest_len > AES_ENCRYPT_BLOCK)
block_len = AES_ENCRYPT_BLOCK;
else
block_len = rest_len;
memcpy((char*)in_block, pos, block_len);
decrypt(in_block, out_block);
memcpy(pos, (char*)out_block, block_len);
pos += block_len;
rest_len -= block_len;
}
if (writeToFile(file_path, buffer, file_len - AES_ENCRYPT_BLOCK))
{
free(buffer);
return 1;
}
else
{
free(buffer);
return 0;
}
}
#if 0
int aes_demo(void)
{
char file_path[64]={0};
char cipher_path[64]={0};
char key[80]={0};
strcpy(key,"2sgwret3457erasd");
strcpy(file_path,"mail.txt");
strcpy(cipher_path,"mail.aes");
aes_encrypt(file_path, cipher_path, key, AES_ENCRYPT_128BIT);
strcpy(file_path,"mail2.txt");
aes_decrypt(cipher_path, file_path, key, AES_ENCRYPT_128BIT);
return 1;
}
int main()
{
return aes_demo();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -