📄 aes.c
字号:
#include "aes.h"
#include <string.h>
#include "tcpip.h"
#include "epa.h"
#include "variable.h"
#include "nsmib.h"
uint32 pack(uint8 *b);
void unpack(uint32 a,uint8 *b);
uint8 xtime(uint8 a);
uint8 bmul(uint8 x,uint8 y);
uint32 SubByte(uint32 a);
uint8 product(uint32 x,uint32 y);
uint32 InvMixCol(uint32 x);
uint8 ByteSub(uint8 x);
void gentables(void);
void gkey(uint8 nb, uint8 nk,uint8 *key);
void encrypt(uint8 *buff);
void decrypt(uint8 *buff);
#define ROTL(x) (((x)>>7)|((x)<<1))
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
static uint8 InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */
static uint8 fbsub[256];
static uint8 rbsub[256];
static uint8 ptab[256];
static uint8 ltab[256];
static uint32 ftable[256];
static uint32 rtable[256];
static uint32 rco[30];
static uint8 Nk;
static uint8 Nb;
static uint8 Nr;
static uint8 fi[24];
static uint8 ri[24];
static uint32 fkey[120];
static uint32 rkey[120];
// pack bytes into a 32-bit Word
uint32 pack(uint8 *b)
{
return ((uint32)b[3]<<24)|((uint32)b[2]<<16)|((uint32)b[1]<<8)|(uint32)b[0];
}
// unpack bytes from a word
void unpack(uint32 a,uint8 *b)
{
b[0]=(uint8)a;
b[1]=(uint8)(a>>8);
b[2]=(uint8)(a>>16);
b[3]=(uint8)(a>>24);
}
//aes乘法运算
uint8 xtime(uint8 a)
{
uint8 b;
if (a&0x80) b=0x1B;
else b=0;
a<<=1;
a^=b;
return a;
}
// x.y= AntiLog(Log(x) + Log(y))
uint8 bmul(uint8 x,uint8 y)
{
if (x && y) return ptab[(ltab[x]+ltab[y])%255];
else return 0;
}
uint32 SubByte(uint32 a)
{
uint8 b[4];
unpack(a,b);
b[0]=fbsub[b[0]];
b[1]=fbsub[b[1]];
b[2]=fbsub[b[2]];
b[3]=fbsub[b[3]];
return pack(b);
}
//dot product of two 4-byte arrays
uint8 product(uint32 x,uint32 y)
{
uint8 xb[4],yb[4];
unpack(x,xb);
unpack(y,yb);
return bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3]);
}
// matrix Multiplication
uint32 InvMixCol(uint32 x)
{
uint32 y;
uint32 m;
uint8 b[4];
m=pack(InCo);
b[3]=product(m,x);
m=ROTL24(m);
b[2]=product(m,x);
m=ROTL24(m);
b[1]=product(m,x);
m=ROTL24(m);
b[0]=product(m,x);
y=pack(b);
return y;
}
// multiplicative inverse
uint8 ByteSub(uint8 x)
{
uint8 y=ptab[255-ltab[x]];
x=y; x=ROTL(x);
y^=x; x=ROTL(x);
y^=x; x=ROTL(x);
y^=x; x=ROTL(x);
y^=x; y^=0x63;
return y;
}
// generate tables
void gentables(void)
{
uint32 i;
uint8 y,b[4];
/* use 3 as primitive root to generate power and log tables */
ltab[0]=0;
ptab[0]=1; ltab[1]=0;
ptab[1]=3; ltab[3]=1;
for (i=2;i<256;i++)
{
ptab[i]=ptab[i-1]^xtime(ptab[i-1]);
ltab[ptab[i]]=(uint8)i;
}
fbsub[0]=0x63;
rbsub[0x63]=0;
for (i=1;i<256;i++)
{
y=ByteSub((uint8)i);
fbsub[i]=y; rbsub[y]=(uint8)i;
}
for (i=0,y=1;i<30;i++)
{
rco[i]=y;
y=xtime(y);
}
/* calculate forward and reverse tables */
for (i=0;i<256;i++)
{
y=fbsub[i];
b[3]=y^xtime(y); b[2]=y;
b[1]=y; b[0]=xtime(y);
ftable[i]=pack(b);
y=rbsub[i];
b[3]=bmul(InCo[0],y); b[2]=bmul(InCo[1],y);
b[1]=bmul(InCo[2],y); b[0]=bmul(InCo[3],y);
rtable[i]=pack(b);
}
}
/****************************************************/
/* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*Nk bytes */
/* Key Scheduler. Create expanded encryption key */
/****************************************************/
void gkey(uint8 nb,uint8 nk,uint8 *key)
{
uint8 i,j,k,m,N;
uint8 C1,C2,C3;
uint32 CipherKey[8];
Nb=nb; Nk=nk;
/* Nr is number of rounds */
if (Nb>=Nk) Nr=6+Nb;
else Nr=6+Nk;
C1=1;
if (Nb<8) { C2=2; C3=3; }
else { C2=3; C3=4; }
/* pre-calculate forward and reverse increments */
for (m=j=0;j<nb;j++,m+=3)
{
fi[m]=(j+C1)%nb;
fi[m+1]=(j+C2)%nb;
fi[m+2]=(j+C3)%nb;
ri[m]=(nb+j-C1)%nb;
ri[m+1]=(nb+j-C2)%nb;
ri[m+2]=(nb+j-C3)%nb;
}
N=Nb*(Nr+1);
for (i=j=0;i<Nk;i++,j+=4)
{
CipherKey[i]=pack((uint8 *)&key[j]);
}
for (i=0;i<Nk;i++) fkey[i]=CipherKey[i];
for (j=Nk,k=0;j<N;j+=Nk,k++)
{
fkey[j]=fkey[j-Nk]^SubByte(ROTL24(fkey[j-1]))^rco[k];
if (Nk<=6)
{
for (i=1;i<Nk && (i+j)<N;i++)
fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
}
else
{
for (i=1;i<4 &&(i+j)<N;i++)
fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
if ((j+4)<N) fkey[j+4]=fkey[j+4-Nk]^SubByte(fkey[j+3]);
for (i=5;i<Nk && (i+j)<N;i++)
fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
}
}
/* now for the expanded decrypt key in reverse order */
for (j=0;j<Nb;j++) rkey[j+N-Nb]=fkey[j];
for (i=Nb;i<N-Nb;i+=Nb)
{
k=N-Nb-i;
for (j=0;j<Nb;j++) rkey[k+j]=InvMixCol(fkey[i+j]);
}
for (j=N-Nb;j<N;j++) rkey[j-N+Nb]=fkey[j];
}
/******************************************************************/
/** There is an obvious time/space trade-off possible here. */
/** Instead of just one ftable[], I could have 4, the other */
/** 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
/******************************************************************/
void encrypt(uint8 *buff)
{
int i,j,k,m;
uint32 a[8],b[8],*x,*y,*t;
for (i=j=0;i<Nb;i++,j+=4)
{
a[i]=pack((uint8 *)&buff[j]);
a[i]^=fkey[i];
}
k=Nb;
x=a; y=b;
/* State alternates between a and b */
for (i=1;i<Nr;i++)
{ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */
for (m=j=0;j<Nb;j++,m+=3)
{ /* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j]=fkey[k++]^ftable[(uint8)x[j]]^
ROTL8(ftable[(uint8)(x[fi[m]]>>8)])^
ROTL16(ftable[(uint8)(x[fi[m+1]]>>16)])^
ROTL24(ftable[x[fi[m+2]]>>24]);
}
t=x; x=y; y=t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m=j=0;j<Nb;j++,m+=3)
{
y[j]=fkey[k++]^(uint32)fbsub[(uint8)x[j]]^
ROTL8((uint32)fbsub[(uint8)(x[fi[m]]>>8)])^
ROTL16((uint32)fbsub[(uint8)(x[fi[m+1]]>>16)])^
ROTL24((uint32)fbsub[x[fi[m+2]]>>24]);
}
for (i=j=0;i<Nb;i++,j+=4)
{
unpack(y[i],(uint8 *)&buff[j]);
x[i]=y[i]=0; /* clean up stack */
}
return;
}
void decrypt(uint8 *buff)
{
int i,j,k,m;
uint32 a[8],b[8],*x,*y,*t;
for (i=j=0;i<Nb;i++,j+=4)
{
a[i]=pack((uint8 *)&buff[j]);
a[i]^=rkey[i];
}
k=Nb;
x=a; y=b;
/* State alternates between a and b */
for (i=1;i<Nr;i++)
{ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */
for (m=j=0;j<Nb;j++,m+=3)
{ /* This is the time-critical bit */
y[j]=rkey[k++]^rtable[(uint8)x[j]]^
ROTL8(rtable[(uint8)(x[ri[m]]>>8)])^
ROTL16(rtable[(uint8)(x[ri[m+1]]>>16)])^
ROTL24(rtable[x[ri[m+2]]>>24]);
}
t=x; x=y; y=t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m=j=0;j<Nb;j++,m+=3)
{
y[j]=rkey[k++]^(uint32)rbsub[(uint8)x[j]]^
ROTL8((uint32)rbsub[(uint8)(x[ri[m]]>>8)])^
ROTL16((uint32)rbsub[(uint8)(x[ri[m+1]]>>16)])^
ROTL24((uint32)rbsub[x[ri[m+2]]>>24]);
}
for (i=j=0;i<Nb;i++,j+=4)
{
unpack(y[i],(uint8 *)&buff[j]);
x[i]=y[i]=0; /* clean up stack */
}
return;
}
/***************************************************************************/
/* epa_encryption(): 对epa报文进行加密的函数; ****/
/* 参数: pData, epa报文体数据段; length, epa报文长度[可能会变]; ****/
/* timestamp, 时间戳,用于生成密钥用; ****/
/* 经过加密后,报文体为密文, length为可能改变,为16的倍数; ****/
/***************************************************************************/
void epa_encryption(uint8 *pData, uint16 length, Time timestamp)
{
uint8 i, j, k, nb, nk;
uint16 temp;
uint8 temp_data[16]; //temp_data, 16byte for encryption
uint8 en_data[128]; //after encryption data;
uint8 block[128]; //ori_data
uint8 key[16];
nb = 4; //4 轮
nk = 4;
j = 0;
k = 0;
temp = length;
gentables();
NSGetkey(key);
gkey(nb, nk, key);//生成密钥
for(i=0; i < temp; i++)
block[i] = pData[i];//用另外一个数组进行存储;
while(temp >= 16)//上面填充完毕,开始进行加密操作;
{
for(i=0;i<16;i++,j++)
temp_data[i] = block[j];
encrypt(temp_data);
for(i=0;i<16;i++,k++)
en_data[k] = temp_data[i];//store the result
temp = temp - 16;
}
temp = length;
for(i = 0; i < temp; i++)
pData[i] = en_data[i];
}
/***************************************************************************/
/* epa_decryption(): 对epa报文进行解密的函数; ****/
/* 参数: pData, epa报文体数据段; length, epa报文长度; ****/
/* timestamp, 时间戳,用于生成密钥用; ****/
/* 经过解密后,报文体为明文, length 不改变,为原来报文长度; ****/
/***************************************************************************/
void epa_decryption(uint8 *pData, uint16 length, Time timestamp)
{
uint8 i, j, k,nb, nk, templen;
uint8 temp_data[16]; //for decryption
uint8 dec_data[128]; //after decryption
uint8 key[16];
uint8 block[128];
j=0;
k=0;
nb = 4;
nk = 4;
templen=length;
gentables();
NSGetkey(key);
gkey(nb, nk, key);
//在此中地方最好检查一下改数组的长度;
for(i = 0; i < templen; i++)
block[i] = pData[i];
while(templen >= 16)
{
for(i = 0; i < 16; i++, j++)
temp_data[i]=block[j];
decrypt(temp_data);
for(i = 0; i < 16; i++, k++)
dec_data[k]=temp_data[i];//store the result
templen = templen - 16;
}
templen=length;
for(i=0;i<templen;i++)
pData[i] = dec_data[i];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -