/*
 * @Description: 工具模块-TEA加密子模块
 * @Author: yangsw
 * @Date: 2021-05-24 16:13:42
 * @LastEditTime: 2021-09-17 15:42:48
 * @LastEditors: yangsw
 * @Reference: 
 */
#include "util_tea.h"
#include "../com/svc/svc_com.h"
#include "../log/svc/svc_log.h"

#define  delta 0x9e3779b9ul	

/**
 * @brief: 4字节数据转化为 gw_u32
 * @return {gw_u32}
 * @note: 
 * @see: 
 * @param {gw_u8*} p
 */
gw_u32 Byte2Long(const gw_u8* p)	//
{
	gw_u32 ll = 0;
	for(gw_s32 i=0; i<4; i++)
	{
		ll<<= 8;
		ll += p[i];
	}
	return ll;
}

/**
 * @brief: gw_u32转化为4字节数据
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u8*} p
 * @param {gw_u32} ll
 */
void Long2Byte(gw_u8* p,gw_u32 ll)	//
{
	for(gw_s32 i=0; i<4; i++)
	{
		p[3 - i] = (gw_u8) (ll & 0xff);
		ll>>= 8;
	}
}
#define a key[0]
#define b key[1]
#define c key[2]
#define d key[3]

#define y lData[0]
#define z lData[1]

/**
 * @brief: 加密
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u32*} lData
 * @param {gw_u32*} key
 */
void encrypt(gw_u32* lData, gw_u32* key) 
{																			

	gw_u32	sum=0;																
						
	for (gw_u8 i=0; i < 32; i++) {																	
		sum += delta;																	
		y += ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);																	
		z += ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);																
	}
}																			

/**
 * @brief: 解密
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u32*} lData
 * @param {gw_u32*} key
 */
void decrypt(gw_u32* lData, gw_u32* key) 
{		

	gw_u32 sum=0xC6EF3720ul; 
															
	for(gw_u8 i=0; i<32; i++) {																	
		z -= ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);																	
		y -= ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);																	
		sum -= delta;	
		//Svc_Log_Print("i:%u,z:%ld,y:%ld,sum:%ld\r\n",i,z,y,sum);															
	}
																			
}																				
#undef a
#undef b
#undef c
#undef d
#undef y
#undef z


/**
 * @brief: 加密数据
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u8*} buff 等待加密的数据指针
 * @param {gw_u16} nLen 需要加密的数据字节数，必须为8的整数倍，且小于1024
 * @param {gw_u8*} key 加密密钥
 */
void Util_Tea_Encrypt(gw_u8* buff, gw_u16 nLen, const gw_u8* key)
{
	gw_u32 *lsData;
	lsData=(gw_u32*)Svc_Com_Get_Buf();
	if(nLen % 8 != 0 || nLen > 1024)
		return;
	gw_u32 lsKey[4];

	for(gw_s32 i= 0; i<4; i++)
	{
		lsKey[i] = Byte2Long(key + i * 4);
	}
	
	for(gw_s32 i= 0; i < nLen/4; i++)
	{
		lsData[i] = Byte2Long(buff + i * 4);
	}

	gw_u32 lNor = 0;		
	for(gw_u16 i=0; i<nLen / 8; i ++)
	{
		lsData[2*i] ^= lNor;		//交织运算
		lsData[2*i + 1] ^= lNor;	//交织运算

		lNor ^= lsData[2 *i];
		lNor ^= lsData[2 *i + 1];

		encrypt(lsData + i * 2,lsKey);

	}

	for(gw_s32 i= 0; i < nLen/4; i++)
	{
		Long2Byte(buff + i * 4,lsData[i]);
	}
}
// /*解密数据
// 入参 gw_u8* buff <INOUT>等待解密的数据指针
// 	 gw_u16 nLen <IN>需要加密的数据字节数，必须为8的整数倍，且小于1024
// 	 const gw_u8* key <IN>加密密钥
// */
// void Util_Tea_Decrypt(gw_u8* buff, gw_u16 nLen, const gw_u8* key)
// {
// 	gw_u32 *lsData;
// 	lsData=(gw_u32*)Svc_Com_Get_Buf();
// 	if(nLen % 8 != 0 || nLen > 1024)
// 		return;
// 	gw_u32 lsKey[4];
// 	for(gw_s32 i= 0; i<4; i++)
// 	{
// 		lsKey[i] = Byte2Long(key + i * 4);
// 	}
// 	for(gw_s32 i= 0; i < nLen/4; i++)
// 	{
// 		lsData[i] = Byte2Long(buff + i * 4);
// 	}

// 	gw_u32 lNor = 0;
// 	for(gw_u16 i=0; i<nLen / 8; i ++)
// 	{
// 		decrypt(lsData + i*2 ,lsKey);

// 		lsData[2*i] ^= lNor;
// 		lsData[2*i + 1] ^= lNor;

// 		lNor ^= lsData[2 *i];		//交织运算
// 		lNor ^= lsData[2 *i + 1];	//交织运算
// 	}
// 	for(gw_s32 i= 0; i < nLen/4; i++)
// 	{
// 		Long2Byte(buff + i * 4,lsData[i]);
// 	}
// }


/**
 * @brief: 解密数据
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u8*} buff 等待解密的数据指针
 * @param {gw_u16} nLen 需要解密的数据字节数，必须为8的整数倍，且小于1024
 * @param {gw_u8*} key 解密密钥
 */
void Util_Tea_Decrypt(gw_u8* buff, gw_u16 nLen, const gw_u8* key)
{
	gw_u32 lsData[2];
	if(nLen % 8 != 0 || nLen > 1024)
		return;
	gw_u32 lsKey[4];
	for(gw_s32 i= 0; i<4; i++)
	{
		lsKey[i] = Byte2Long(key + i * 4);
	}
	gw_u32 lNor = 0;
	for(gw_s32 i= 0; i < nLen/4; i=i+2)
	{
		lsData[0] = Byte2Long(buff + i * 4);
		lsData[1] = Byte2Long(buff + (i+1) * 4);
		decrypt(lsData,lsKey);
		lsData[0] ^= lNor;
		lsData[1] ^= lNor;
		lNor ^= lsData[0];		//交织运算
		lNor ^= lsData[1];	//交织运算
		Long2Byte(buff + i * 4,lsData[0]);
		Long2Byte(buff + (i+1) * 4,lsData[1]);
	}
}
