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

📄 beeo_core.c

📁 基于beeo标准的数据加解密算法
💻 C
字号:
#include "beeo_Core.h"
#include "sortedList.h"
#include "beeo/beeo_Basic.h"

static BEEO_PROCESSOR bp = {0,};

static unsigned char beeo_PatternForMatrix[BEEO_DH_BYTES] =
{//用于生成矩阵的模数
	0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x5E,0x7E,
	0xC6,0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF
};

static unsigned char beeo_BaseForMatrix[BEEO_DH_BYTES] =
{//用于生成矩阵的底数
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x57,0x41,0x54,0x45,0x52,0x54,0x45,0x4b,
};

//用于生成位偏移量的模数
static uIn16 beeo_baseForOffset =3;
//用于生成位偏移量的底数
static uIn16 beeo_patternForOffset = 0xc567;

BEEO_INLINE void beeo_IncreaseRand(char* buf)
{
	int pos=bp.nRandPos;
	pos &= 0x07;	bp.dwRand[pos] += buf[pos];	pos+=3;
	pos &= 0x07;	bp.dwRand[pos] += buf[pos];	pos+=3;
	bp.nRandPos = pos;
}

BEEO_INLINE BEEO_CHANNEL* beeo_CreateChannel(SOCKET s, SOCKADDR *addr)
{
	SOCKADDR_IN* ad=(SOCKADDR_IN*)addr;
	BEEO_CHANNEL* channel=0;
	long pos;
	uIn32 ticks, tickNow;

	if(!bp.bInitialized)
	{
		beeo_init(0,0,0);
		return 0;
	}

	if(bp.bBusy) return 0;
	bp.bBusy = 1; //Lock

	//Check timeout
	pos=slGetItemCount(bp.sl)-1;
	tickNow=GetTickCount();
	while(pos>=0)
	{
		channel=(BEEO_CHANNEL*)slGetItem(bp.sl, pos);
		if(!channel) break;
		ticks = tickNow-channel->dwLastAccessTicks;
		if(ticks>15*60*1000)//15分钟
			slReleaseItembyPos(bp.sl, pos);
		pos--;
	}

	channel = (BEEO_CHANNEL*)sl_malloc(sizeof(BEEO_CHANNEL));
	if(0==channel)
	{
		bp.bBusy=0;	//Unlock
		return 0;
	}

	if(!slInsertItem(bp.sl, channel, (uIn32)s, ad->sin_addr.S_un.S_addr, ad->sin_port, 0))
	{
		bp.bBusy=0;	//Unlock
		sl_free(channel);
		return 0;
	}
	memset(channel, 0, sizeof(BEEO_CHANNEL));
	channel->sock = s;
	channel->dwLastAccessTicks=GetTickCount();
	memcpy(&(channel->addrPeer), addr, sizeof(SOCKADDR));

	bp.bBusy=0;	//Unlock
	return channel;
}

BEEO_INLINE BEEO_CHANNEL* beeo_FindChannel(SOCKET s, SOCKADDR *addr)
{
	SOCKADDR_IN* ad=(SOCKADDR_IN*)addr;
	BEEO_CHANNEL* channel=0;

	if(!bp.bInitialized)
	{
		beeo_init(0,0,0);
		return 0;
	}
	channel=(BEEO_CHANNEL*)slFindContent(bp.sl, (uIn32)s, ad->sin_addr.S_un.S_addr, ad->sin_port, 0);
	if(channel)
		channel->dwLastAccessTicks=GetTickCount();
	return channel;
}

BEEO_INLINE int beeo_DeleteChannel(SOCKET s, SOCKADDR *addr)
{
	SOCKADDR_IN* ad=(SOCKADDR_IN*)addr;

	if(!bp.bInitialized)
	{
		beeo_init(0,0,0);
		return 0;
	}
	slReleaseItem(bp.sl, (uIn32)s, ad->sin_addr.S_un.S_addr, ad->sin_port, 0);
	return 0;
}

/*
 关闭一个加密通道。
*/
int PASCAL beeo_close(SOCKET s, SOCKADDR *addr)
{
	if(!bp.bInitialized) return 0;
	beeo_DeleteChannel(s, addr);
	return 1;
}

/*
 初始化BEEO。
 如果bBufferPacket!=0,BEEO将暂存加密信道建立以前发送的报文,否则直接废弃。
 如果keyString!=0而且nKeyLength!=0,则使用公共密钥,否则不使用公共密钥。
 如果不调用这个函数进行初始化设置,BEEO将按照beeo_init(0,0,0)进行初始化。
*/
int PASCAL beeo_init(int bBufferPacket, char *keyString, int nKeyLength)
{
	if(nKeyLength>PEEO_MAX_KEY_BYTES)
		return 0;

	beeo_InitColIndex();
	if(!bp.sl)
		bp.sl=slAllocList();
	if(!bp.sl) return 0;

	if(!bp.dhID) bp.dhID=dh_Alloc(beeo_PatternForMatrix, BEEO_DH_BYTES);
	if(!bp.dhID) return 0;
	
	bp.dwFlag = bs_ntohl(BEEO_DH_FLAG);
	bp.dwVersion=bs_ntohl(BEEO_VERSION);

	bp.bBufferPacket = bBufferPacket;
	bp.nKeyLength=nKeyLength;
	if(bp.nKeyLength)
		memcpy(bp.key, keyString, bp.nKeyLength);
	bp.dwRand[0]=GetTickCount();
	bp.dwRand[1]=GetTickCount()+(uIn32)(&bp);
	bp.dwRand[2]=GetTickCount()+(uIn32)beeo_init;
	bp.dwRand[3]=GetTickCount()+(uIn32)bs_Sendto;
	bp.dwRand[4]=GetTickCount()+(uIn32)bp.sl;
	bp.dwRand[5]=GetTickCount()+(uIn32)bs_Recvfrom;
	bp.dwRand[6]=GetTickCount()+(uIn32)GetTickCount;
	bp.dwRand[7]=GetTickCount()*GetTickCount();
	
	bp.nNextSeq = GetTickCount();
	
	bp.bInitialized=1;

#if 0
	{
		char i[33], o[33], o_i[33],m[17];
		sprintf(i, "0123456789abcdefghijklmnopqrstuv");
		sprintf(m, "0123456789abcdef");
		i[32]=0;
		o[32]=0;
		o_i[32]=0;
		m[16]=0;
		beeo_EncodeCol(i,m,o,32);
		beeo_DecodeCol(o,m,o_i,32);
		beeo_EncodeRow(i,m,o,32);
		beeo_DecodeRow(o,m,o_i,32);
		beeo_EncodeXor(i,m,o,32);
		beeo_DecodeXor(o,m,o_i,32);
	}
#endif

	return 1;
}

/*
 强制进行DH交换。
 如果bNewKey=1,将强制产生一个新的密钥;
 如果bNewKey=0,则只有在加密信道还没有建立的情况下尝试建立一个新的密钥。
 返回>0表明成功发送了密钥加密报文或者已经建立了加密信道,否则表示错误
*/
int PASCAL beeo_force_setup(SOCKET s, int bNewKey, SOCKADDR *addr, bsType adlen )
{
	BEEO_CHANNEL* channel;
	int ret=1;

	channel = beeo_FindChannel(s, addr);
	if(!channel)
		channel=beeo_CreateChannel(s, addr);
	if(!channel) return 0;

	if(bNewKey)
	{
		channel->bEstablished = 0;
		channel->pkLocal.nLocalSeq = 0;
		channel->pkLocal.nPeerSeq = 0;
		channel->pkPeer.nLocalSeq = 0;
		channel->pkPeer.nPeerSeq = 0;
	}
	beeo_SendDHPackage(channel);
	return ret;
}

/*
 检查加密信道是否建立。
 返回0标识还没有建立,否则表示已经建立。
*/
int PASCAL beeo_established(SOCKET s, SOCKADDR *addr, bsType adlen )
{
	BEEO_CHANNEL* channel;
	channel = beeo_FindChannel(s, addr);
	if(!channel) return 0;
	if(!channel->bEstablished) return 0;
	return (int)channel;
}

int PASCAL beeo_BackupSendto(SOCKET s, char *buf, bsType len, bsType flag, SOCKADDR *addr, bsType adlen)
{
	return 0;
}

int PASCAL beeo_Encode(SOCKET s, char *buf, char* bufOut, bsType len, SOCKADDR *addr, bsType adlen, int ch)
{
	BEEO_CHANNEL* channel;

	beeo_IncreaseRand(buf);
	channel = (BEEO_CHANNEL*)ch;
	beeo_EncodeCol(buf, channel->mCol, bufOut, len);
	beeo_EncodeRow(bufOut, channel->mRow, bufOut, len);
	beeo_EncodeXor(bufOut, channel->mXor, bufOut, len);
	return len;
}

BEEO_INLINE int beeo_IsDHPackage(char* buf, bsType len)
{
	BEEO_DH_PACKAGE* pack;
	uChar* ptr;
	uChar	cSum1,cSum2,cSum3,cSum4;
	int i;

	if(len != sizeof(BEEO_DH_PACKAGE))
		return 0;
	pack = (BEEO_DH_PACKAGE*) buf;
	if((pack->dwFlag != bp.dwFlag)||
		(pack->dwVersion>bp.dwVersion))
	{
		return 0;
	}

	ptr=(uChar*)buf;
	cSum1=cSum2=cSum3=cSum4=0;
	for(i=0;i<len;i+=4)
	{
		cSum1 += ptr[0];
		cSum2 += ptr[1];
		cSum3 += ptr[2];
		cSum4 += ptr[3];
		ptr += 4;
	}

	cSum1 = cSum1|cSum2|cSum3|cSum4;
	return (!cSum1);
}

int PASCAL beeo_Decode(SOCKET s, char *buf, char* bufOut, bsType len, SOCKADDR *addr, bsType adlen )
{
	BEEO_CHANNEL* channel;

	channel = beeo_FindChannel(s, addr);
	beeo_IncreaseRand(buf);
	if(!channel)
	{
		channel=beeo_CreateChannel(s, addr);
		if(beeo_IsDHPackage(buf, len))
			memcpy(&(channel->pkPeer), buf, sizeof(BEEO_DH_PACKAGE));
		beeo_GenerateMatrix(channel);
		bufOut[0]=0;
		return RETURN_VALUE_WHEN_DATA_ABANDONED;
	}

	if(beeo_IsDHPackage(buf, len))
	{
		memcpy(&(channel->pkPeer), buf, sizeof(BEEO_DH_PACKAGE));
		beeo_GenerateMatrix(channel);
		bufOut[0]=0;
		return RETURN_VALUE_WHEN_DATA_ABANDONED;
	}
	
	if(channel->bEstablished)
	{
		beeo_DecodeXor(buf, channel->mXor, bufOut, len);
		beeo_DecodeRow(bufOut, channel->mRow, bufOut, len);
		beeo_DecodeCol(bufOut, channel->mCol, bufOut, len);
		return len;
	}
	else
	{
		beeo_GenerateMatrix(channel);
		bufOut[0]=0;
		return RETURN_VALUE_WHEN_DATA_ABANDONED;
	}
}

BEEO_INLINE int beeo_NeedSendDHPackage(BEEO_CHANNEL* channel)
{
	//如果有对方的SEQ,但对方的历史SEQ与新报文的SEQ不符合,说明对方发起了一次新的请求
	if(channel->pkLocal.nPeerSeq!=channel->pkPeer.nLocalSeq)
	{//要求重新计算本地的DH特征值
		if(!channel->bLocalRefreshed)
			channel->pkLocal.nLocalSeq=0;
		return 1;
	}
	//如果接收到了对方发送的DH报文,但对方报告的本地SEQ与实际本地SEQ不符合,
	//说明对方可能没有接收到最新的DH报文
	if(channel->pkLocal.nLocalSeq!=channel->pkPeer.nPeerSeq)
	{
		return 1;
	}
	//对方最新的DH报文中SEQ=0,表明本次协商发起之后就没有收到过对方的DH报文
	if(!channel->pkPeer.nPeerSeq)
	{
		return 1;
	}
	//本地最新发送的DH报文的SEQ=0,表明本次协商发起之后还没有发送过DH报文
	if(!channel->pkLocal.nLocalSeq)
		return 1;
	return 0;
}

static int beeo_MakeDHPackage(BEEO_CHANNEL* channel)
{
	int i;

	bp.nNextSeq++;
	if(!bp.nNextSeq)
		bp.nNextSeq++;
	memset(&(channel->pkLocal), 0, sizeof(BEEO_DH_PACKAGE));

	channel->pkLocal.nLocalSeq=bp.nNextSeq;
	channel->pkLocal.nPeerSeq=channel->pkPeer.nLocalSeq;
	channel->pkLocal.dwFlag=bp.dwFlag;
	channel->pkLocal.dwVersion=bp.dwVersion;
	memcpy(channel->dwRand, bp.dwRand, 8*sizeof(uIn32));
	for(i=0;i<4;i++)
	{
		channel->dwRand[i]&=0xfff;
		if(channel->dwRand[i]<0x400)
		{
			channel->dwRand[i] += GetTickCount();
			i--;
			continue;
		}
		channel->dwRand[i] = bs_ntohl(channel->dwRand[i]);
		dh_GetFeature(bp.dhID, beeo_BaseForMatrix, bs_ntohl(channel->dwRand[i]), channel->pkLocal.dh[i]);
	}
	for(i=4;i<8;i++)
	{
		channel->dwRand[i]&=0xff;
		if(channel->dwRand[i]<0x10)
		{
			channel->dwRand[i] += GetTickCount();
			i--;
			continue;
		}
		channel->dwRand[i] = bs_ntohl(channel->dwRand[i]);
		channel->pkLocal.dwOffset[i-4] = 
			bs_ntohl(dh_ShortPower(beeo_baseForOffset, (uIn16)bs_ntohl(channel->dwRand[i]),beeo_patternForOffset));
	}

	return 1;
}

int PASCAL beeo_SendDHPackage(BEEO_CHANNEL* channel)
{
	int ret;

	if(!channel->pkLocal.nLocalSeq)
	{//需要产生一组新的DH报文
		beeo_MakeDHPackage(channel);
		channel->bLocalRefreshed = 1;
	}

	channel->pkLocal.nPeerSeq=channel->pkPeer.nLocalSeq;

	{
		int i;
		uChar* ptr;
		uChar	cSum1,cSum2,cSum3,cSum4;
		cSum1=cSum2=cSum3=cSum4=0;
		ptr = (uChar*)&(channel->pkLocal);
		for(i=0;i<sizeof(BEEO_DH_PACKAGE);i+=4)
		{
			cSum1 += ptr[0];
			cSum2 += ptr[1];
			cSum3 += ptr[2];
			cSum4 += ptr[3];
			ptr += 4;
		}
		channel->pkLocal.cSum1 -= cSum1;
		channel->pkLocal.cSum2 -= cSum2;
		channel->pkLocal.cSum3 -= cSum3;
		channel->pkLocal.cSum4 -= cSum4;
	}

	ret = bs_Sendto(channel->sock,
		(char*)&(channel->pkLocal),
		sizeof(BEEO_DH_PACKAGE),
		0,
		(bsAddrType*)&(channel->addrPeer),
		sizeof(SOCKADDR_IN));
	return ret;
}

BEEO_INLINE void beeo_GenerateAMAtrax(uChar* digest, uIn32 offset, uChar* m)
{
	uIn32 bits;
	uIn16 d1,d2;
	int i;

	bits = offset&0x07;
	offset /= 8;
	offset += BEEO_DH_BYTES;
	
	d1 = digest[offset%BEEO_DH_BYTES];
	for(i=0;i<BEEO_DH_BYTES;i++)
	{
		d2 = digest[(offset+1)%BEEO_DH_BYTES];
		m[i]= (d1<<bits)+(d2>>(8-bits));
		d1 = d2;
	}
}

int PASCAL beeo_GenerateMatrix(BEEO_CHANNEL* channel)
{
	uIn16 offset;

	if(beeo_NeedSendDHPackage(channel))
	{
		channel->bEstablished=0;
		beeo_SendDHPackage(channel);
	}
	if(channel->pkLocal.nLocalSeq != channel->pkPeer.nPeerSeq)
		return 0;//还没有接收到对方的DH报文
	if(channel->bEstablished &&(channel->pkLocal.nPeerSeq == channel->pkPeer.nLocalSeq))
		return 1;//已经计算过了
	
	dh_GetFeature(bp.dhID, channel->pkPeer.dh[0], bs_ntohl(channel->dwRand[0]), bp.tmp);
	md5_HashBuff(bp.tmp, BEEO_DH_BYTES, bp.tmp);
	offset = dh_ShortPower((uIn16)bs_ntohl(channel->pkPeer.dwOffset[0]), (uIn16)bs_ntohl(channel->dwRand[4]), beeo_patternForOffset);
	beeo_GenerateAMAtrax(bp.tmp, offset, channel->mCol);

	dh_GetFeature(bp.dhID, channel->pkPeer.dh[1], bs_ntohl(channel->dwRand[1]), bp.tmp);
	md5_HashBuff(bp.tmp, BEEO_DH_BYTES, channel->mRow);
	offset = dh_ShortPower((uIn16)bs_ntohl(channel->pkPeer.dwOffset[1]), (uIn16)bs_ntohl(channel->dwRand[5]), beeo_patternForOffset);
	beeo_GenerateAMAtrax(bp.tmp, offset, channel->mCol);
	
	dh_GetFeature(bp.dhID, channel->pkPeer.dh[2], bs_ntohl(channel->dwRand[2]), bp.tmp);
	md5_HashBuff(bp.tmp, BEEO_DH_BYTES, channel->mXor);
	offset = dh_ShortPower((uIn16)bs_ntohl(channel->pkPeer.dwOffset[2]), (uIn16)bs_ntohl(channel->dwRand[6]), beeo_patternForOffset);
	beeo_GenerateAMAtrax(bp.tmp, offset, channel->mCol);
	
	channel->bEstablished = 1;
	channel->bLocalRefreshed = 0;
#if 0
	{
		char* ptr=bp.tmp;
		int len;

		len += sprintf(ptr+len, "O_a1 = 0x%08lx\r\n", channel->pkLocal)
	}
#endif
	return 1;
}

void PASCAL slCheckTimeout(void* sl)
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -