⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aes.c

📁 包括EPA协议栈
💻 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 + -