📄 beeo_core.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 + -