AES 암호 화 알고리즘(c 언어)

인터넷 에서 얻 은 코드 의 실현 만 보 여 줍 니 다.제 가 수정 을 해서 당신 의 코드 에 편리 하 게 사용 할 수 있 습 니 다.
AES 는 DES 알고리즘 보다 강도 가 더 강하 다.AES 는 128 비트 의 암호 화 키 를 사용 하면 충분 하 며 더 긴 키 를 사용 할 필요 가 없습니다.키 가 너무 길 어서 CPU 자원 을 낭비 합 니 다.
#ifndef _AES_H
#define _AES_H

/*************** Header files *********************************************/
#include <stdlib.h>
#include <string.h>
#include <memory.h>
//#include "cryptcom.h"


#define AES_ModeType  AI_ECB
#define AES_PadType   AI_PKCS_PADDING

/*************** Assertions ***********************************************/
////////	Define the Endianness	////////
#undef BIG_ENDIAN
#undef LITTLE_ENDIAN

#define USER_LITTLE_ENDIAN

#if defined(USER_BIG_ENDIAN)
	#define BIG_ENDIAN
#elif defined(USER_LITTLE_ENDIAN)
	#define LITTLE_ENDIAN
#else
	#if 0
		#define BIG_ENDIAN		//	Big-Endian machine with pointer casting
	#elif defined(_MSC_VER)
		#define LITTLE_ENDIAN	//	Little-Endian machine with pointer casting
	#else
		#error
	#endif
#endif

/*************** Macros ***************************************************/
////////	rotate by using shift operations	////////
#if defined(_MSC_VER)
	#define ROTL_DWORD(x, n) _lrotl((x), (n))
	#define ROTR_DWORD(x, n) _lrotr((x), (n))
#else
	#define ROTL_DWORD(x, n) ( (DWORD)((x) << (n)) | (DWORD)((x) >> (32-(n))) )
	#define ROTR_DWORD(x, n) ( (DWORD)((x) >> (n)) | (DWORD)((x) << (32-(n))) )
#endif

////////	reverse the byte order of DWORD(DWORD:4-bytes integer) and WORD.
#define ENDIAN_REVERSE_DWORD(dwS)	( (ROTL_DWORD((dwS),  8) & 0x00ff00ff) | (ROTL_DWORD((dwS), 24) & 0xff00ff00) )

////////	move DWORD type to BYTE type and BYTE type to DWORD type
#if defined(BIG_ENDIAN)		////	Big-Endian machine
	#define BIG_B2D(B, D)		D = *(DWORD *)(B)
	#define BIG_D2B(D, B)		*(DWORD *)(B) = (DWORD)(D)
	#define LITTLE_B2D(B, D)	D = ENDIAN_REVERSE_DWORD(*(DWORD *)(B))
	#define LITTLE_D2B(D, B)	*(DWORD *)(B) = ENDIAN_REVERSE_DWORD(D)
#elif defined(LITTLE_ENDIAN)	////	Little-Endian machine
	#define BIG_B2D(B, D)		D = ENDIAN_REVERSE_DWORD(*(DWORD *)(B))
	#define BIG_D2B(D, B)		*(DWORD *)(B) = ENDIAN_REVERSE_DWORD(D)
	#define LITTLE_B2D(B, D)	D = *(DWORD *)(B)
	#define LITTLE_D2B(D, B)	*(DWORD *)(B) = (DWORD)(D)
#else
	#error ERROR : Invalid DataChangeType
#endif

/*************** Definitions / Macros *************************************/
////	       4          .
#define AI_ECB					1
#define AI_CBC					2
#define AI_OFB					3
#define AI_CFB					4
////	         padding      .
#define AI_NO_PADDING			1	//	Padding   (    16       )
#define AI_PKCS_PADDING			2	//	padding          padding

////	AES         
#define AES_BLOCK_LEN			16		//	in BYTEs
#define AES_USER_KEY_LEN		32		//	(16,24,32) in BYTEs
#define AES_NO_ROUNDS			10
#define AES_NO_ROUNDKEY			68		//	in DWORDs

/*************** New Data Types *******************************************/
////////	Determine data types depand on the processor and compiler.
#define BOOL	int					//	1-bit data type
#define BYTE	unsigned char		//	unsigned 1-byte data type
#define WORD	unsigned short int	//	unsigned 2-bytes data type
#define DWORD	unsigned int		//	unsigned 4-bytes data type
#define RET_VAL		DWORD			//	return values

////	AES..
typedef struct{
	DWORD		ModeID;						//	ECB or CBC
	DWORD		PadType;					//	      Padding type
	BYTE		IV[AES_BLOCK_LEN];			//	Initial Vector
	BYTE		ChainVar[AES_BLOCK_LEN];	//	Chaining Variable
	BYTE		Buffer[AES_BLOCK_LEN];		//	Buffer for unfilled block
	DWORD		BufLen; 					//	Buffer          
	DWORD		RoundKey[AES_NO_ROUNDKEY];	//	       DWORD  
} AES_ALG_INFO;
/*************** Constant (Error Code) ************************************/
////	Error Code -     ,           .
#define CTR_SUCCESS					0
#define CTR_FATAL_ERROR				0x1001
#define CTR_INVALID_USERKEYLEN		0x1002	//	             .
#define CTR_PAD_CHECK_ERROR			0x1003	//	
#define CTR_DATA_LEN_ERROR			0x1004	//	            .
#define CTR_CIPHER_LEN_ERROR		0x1005	//	               .

#ifdef __cplusplus
extern "C" {
#endif

/*************** Prototypes ***********************************************/
////	       AES_ALG_INFO  mode, padding      IV         .
void	AES_SetAlgInfo(
		DWORD			ModeID,
		DWORD			PadType,
		BYTE			*IV,
		AES_ALG_INFO	*AlgInfo);

////	    AES_USER_KEY_LEN                  
RET_VAL AES_EncKeySchedule(
		BYTE			*UserKey,		//	            .
		DWORD			UserKeyLen,
		AES_ALG_INFO	*AlgInfo);		//	     Round Key     .
RET_VAL AES_DecKeySchedule(
		BYTE			*UserKey,		//	            .
		DWORD			UserKeyLen,
		AES_ALG_INFO	*AlgInfo);		//	     Round Key     .

////	Init/Update/Final        .
RET_VAL	AES_EncInit(
		AES_ALG_INFO	*AlgInfo);
RET_VAL	AES_EncUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE			*PlainTxt,		//	       .
		DWORD			PlainTxtLen,
		BYTE			*CipherTxt, 	//	        .
		DWORD			*CipherTxtLen);
RET_VAL	AES_EncFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE			*CipherTxt, 	//	        .
		DWORD			*CipherTxtLen);

////	Init/Update/Final        .
RET_VAL	AES_DecInit(
		AES_ALG_INFO	*AlgInfo);
RET_VAL	AES_DecUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE			*CipherTxt,		//	        .
		DWORD			CipherTxtLen,
		BYTE			*PlainTxt,		//	        .
		DWORD			*PlainTxtLen);
RET_VAL	AES_DecFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE			*PlainTxt,		//	        .
		DWORD			*PlainTxtLen);

/*************** END OF FILE **********************************************/
#ifdef __cplusplus
}
#endif

#endif	//	_AES_H

AECNEC.C
<pre name="code" class="cpp">/*************** Header files *********************************************/
#include "aes.h"

/*************** Assertions ***********************************************/

/*************** Definitions / Macros  ************************************/
#define BlockCopy(pbDst, pbSrc) {					/
	((DWORD *)(pbDst))[0] = ((DWORD *)(pbSrc))[0];	/
	((DWORD *)(pbDst))[1] = ((DWORD *)(pbSrc))[1];	/
	((DWORD *)(pbDst))[2] = ((DWORD *)(pbSrc))[2];	/
	((DWORD *)(pbDst))[3] = ((DWORD *)(pbSrc))[3];	/
}
#define BlockXor(pbDst, phSrc1, phSrc2) {			/
	((DWORD *)(pbDst))[0] = ((DWORD *)(phSrc1))[0]	/
						  ^ ((DWORD *)(phSrc2))[0];	/
	((DWORD *)(pbDst))[1] = ((DWORD *)(phSrc1))[1]	/
						  ^ ((DWORD *)(phSrc2))[1];	/
	((DWORD *)(pbDst))[2] = ((DWORD *)(phSrc1))[2]	/
						  ^ ((DWORD *)(phSrc2))[2];	/
	((DWORD *)(pbDst))[3] = ((DWORD *)(phSrc1))[3]	/
						  ^ ((DWORD *)(phSrc2))[3];	/
}

/*************** New Data Types *******************************************/

/*************** Global Variables *****************************************/

/*************** Prototypes ***********************************************/
void	AES_Encrypt(
		void		*CipherKey,		//	 /    Round Key
		BYTE		*Data);			//	                 pointer
void	AES_Decrypt(
		void		*CipherKey,		//	 /    Round Key
		BYTE		*Data);			//	                 pointer

/*************** Constants ************************************************/

/*************** Constants ************************************************/

/*************** Macros ***************************************************/

/*************** Global Variables *****************************************/

/*************** Function *************************************************
*
*/
void	AES_SetAlgInfo(
		DWORD			ModeID,
		DWORD			PadType,
		BYTE			*IV,
		AES_ALG_INFO	*AlgInfo)
{
	AlgInfo->ModeID = ModeID;
	AlgInfo->PadType = PadType;

	if( IV!=NULL )
		memcpy(AlgInfo->IV, IV, AES_BLOCK_LEN);
	else
		memset(AlgInfo->IV, 0, AES_BLOCK_LEN);
}
/*************** Function *************************************************
*
*/
static RET_VAL PaddSet(
			BYTE	*pbOutBuffer,
			DWORD	dRmdLen,
			DWORD	dBlockLen,
			DWORD	dPaddingType)
{
	DWORD dPadLen;

	switch( dPaddingType ) 
	{
		case AI_NO_PADDING :
			if( dRmdLen==0 )	return 0;
			else				return CTR_DATA_LEN_ERROR;

		case AI_PKCS_PADDING :
			dPadLen = dBlockLen - dRmdLen;
			memset(pbOutBuffer+dRmdLen, (char)dPadLen, (int)dPadLen);
			return dPadLen;

		default :
			return CTR_FATAL_ERROR;
	}
}
/*************** Function *************************************************
*
*/
static RET_VAL PaddCheck(
			BYTE	*pbOutBuffer,
			DWORD	dBlockLen,
			DWORD	dPaddingType)
{
	DWORD i, dPadLen;

	switch( dPaddingType ) {
		case AI_NO_PADDING :
			return 0;			//	padding       0    .

		case AI_PKCS_PADDING :
			dPadLen = pbOutBuffer[dBlockLen-1];
			if( ((int)dPadLen<=0) || (dPadLen>(int)dBlockLen) )
				return CTR_PAD_CHECK_ERROR;
			for( i=1; i<=dPadLen; i++)
				if( pbOutBuffer[dBlockLen-i] != dPadLen )
					return CTR_PAD_CHECK_ERROR;
			return dPadLen;

		default :
			return CTR_FATAL_ERROR;
	}
}
/**************************************************************************
*
*/
RET_VAL	AES_EncInit(
		AES_ALG_INFO	*AlgInfo)
{
	AlgInfo->BufLen = 0;
	if( AlgInfo->ModeID!=AI_ECB )
		memcpy(AlgInfo->ChainVar, AlgInfo->IV, AES_BLOCK_LEN);
	return CTR_SUCCESS;
}

/**************************************************************************
*
*/
static RET_VAL ECB_EncUpdate(
		AES_ALG_INFO	*AlgInfo,		//	
		BYTE		*PlainTxt,		//	         pointer
		DWORD		PlainTxtLen,	//	              
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;

	//
	*CipherTxtLen = BufLen + PlainTxtLen;

	//	No one block
	if( *CipherTxtLen<BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)PlainTxtLen);
		AlgInfo->BufLen += PlainTxtLen;
		*CipherTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that PlainTxt and CipherTxt are the same buffer
	if( PlainTxt==CipherTxt )
		return CTR_FATAL_ERROR;

	//	first block
	memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)(BlockLen - BufLen));
	PlainTxt += BlockLen - BufLen;
	PlainTxtLen -= BlockLen - BufLen;

	//	core part
	BlockCopy(CipherTxt, AlgInfo->Buffer);
	AES_Encrypt(ScheduledKey, CipherTxt);
	CipherTxt += BlockLen;
	while( PlainTxtLen>=BlockLen ) 
	{
		BlockCopy(CipherTxt, PlainTxt);
		AES_Encrypt(ScheduledKey, CipherTxt);
		PlainTxt += BlockLen;
		CipherTxt += BlockLen;
		PlainTxtLen -= BlockLen;
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, PlainTxt, (int)PlainTxtLen);
	AlgInfo->BufLen = PlainTxtLen;
	*CipherTxtLen -= PlainTxtLen;

	//	control the case that PlainTxt and CipherTxt are the same buffer
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL CBC_EncUpdate(
		AES_ALG_INFO	*AlgInfo,		//	
		BYTE		*PlainTxt,		//	         pointer
		DWORD		PlainTxtLen,	//	              
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;

	//
	*CipherTxtLen = BufLen + PlainTxtLen;

	//	No one block
	if( *CipherTxtLen<BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)PlainTxtLen);
		AlgInfo->BufLen += PlainTxtLen;
		*CipherTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that PlainTxt and CipherTxt are the same buffer
	if( PlainTxt==CipherTxt )
		return CTR_FATAL_ERROR;

	//	first block
	memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)(BlockLen - BufLen));
	PlainTxt += BlockLen - BufLen;
	PlainTxtLen -= BlockLen - BufLen;

	//	core part
	BlockXor(CipherTxt, AlgInfo->ChainVar, AlgInfo->Buffer);
	AES_Encrypt(ScheduledKey, CipherTxt);
	CipherTxt += BlockLen;
	while( PlainTxtLen>=BlockLen ) 
	{
		BlockXor(CipherTxt, CipherTxt-BlockLen, PlainTxt);
		AES_Encrypt(ScheduledKey, CipherTxt);
		PlainTxt += BlockLen;
		CipherTxt += BlockLen;
		PlainTxtLen -= BlockLen;
	}
	BlockCopy(AlgInfo->ChainVar, CipherTxt-BlockLen);

	//	save remained data
	memcpy(AlgInfo->Buffer, PlainTxt, (int)PlainTxtLen);
	AlgInfo->BufLen = PlainTxtLen;
	*CipherTxtLen -= PlainTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL OFB_EncUpdate(
		AES_ALG_INFO	*AlgInfo,		//	
		BYTE		*PlainTxt,		//	         pointer
		DWORD		PlainTxtLen,	//	              
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN;
	DWORD		BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*CipherTxtLen = BufLen + PlainTxtLen;

	//	No one block
	if( *CipherTxtLen<BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)PlainTxtLen);
		AlgInfo->BufLen += PlainTxtLen;
		*CipherTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that PlainTxt and CipherTxt are the same buffer
	if( PlainTxt==CipherTxt )
		return CTR_FATAL_ERROR;

	//	first block
	memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)(BlockLen - BufLen));
	PlainTxt += BlockLen - BufLen;
	PlainTxtLen -= BlockLen - BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	BlockXor(CipherTxt, AlgInfo->ChainVar, AlgInfo->Buffer);
	CipherTxt += BlockLen;
	while( PlainTxtLen>=BlockLen ) 
	{
		AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
		BlockXor(CipherTxt, AlgInfo->ChainVar, PlainTxt);
		PlainTxt += BlockLen;
		CipherTxt += BlockLen;
		PlainTxtLen -= BlockLen;
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, PlainTxt, (int)PlainTxtLen);
	AlgInfo->BufLen = (AlgInfo->BufLen&0xF0000000) + PlainTxtLen;
	*CipherTxtLen -= PlainTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL CFB_EncUpdate(
		AES_ALG_INFO	*AlgInfo,		//	
		BYTE		*PlainTxt,		//	         pointer
		DWORD		PlainTxtLen,	//	              
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN;
	DWORD		BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*CipherTxtLen = BufLen + PlainTxtLen;

	//	No one block
	if( *CipherTxtLen<BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)PlainTxtLen);
		AlgInfo->BufLen += PlainTxtLen;
		*CipherTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that PlainTxt and CipherTxt are the same buffer
	if( PlainTxt==CipherTxt )
		return CTR_FATAL_ERROR;

	//	first block
	memcpy(AlgInfo->Buffer+BufLen, PlainTxt, (int)(BlockLen - BufLen));
	PlainTxt += BlockLen - BufLen;
	PlainTxtLen -= BlockLen - BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	BlockXor(AlgInfo->ChainVar, AlgInfo->ChainVar, AlgInfo->Buffer);
	BlockCopy(CipherTxt, AlgInfo->ChainVar);
	CipherTxt += BlockLen;
	while( PlainTxtLen>=BlockLen ) 
	{
		AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
		BlockXor(AlgInfo->ChainVar, AlgInfo->ChainVar, PlainTxt);
		BlockCopy(CipherTxt, AlgInfo->ChainVar);
		PlainTxt += BlockLen;
		CipherTxt += BlockLen;
		PlainTxtLen -= BlockLen;
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, PlainTxt, (int)PlainTxtLen);
	AlgInfo->BufLen = (AlgInfo->BufLen&0xF0000000) + PlainTxtLen;
	*CipherTxtLen -= PlainTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
RET_VAL	AES_EncUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*PlainTxt,		//	         pointer
		DWORD		PlainTxtLen,	//	              
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	switch( AlgInfo->ModeID ) 
	{
		case AI_ECB :	return ECB_EncUpdate(AlgInfo, PlainTxt, PlainTxtLen, CipherTxt, CipherTxtLen);
		case AI_CBC :	return CBC_EncUpdate(AlgInfo, PlainTxt, PlainTxtLen, CipherTxt, CipherTxtLen);
		case AI_OFB :	return OFB_EncUpdate(AlgInfo, PlainTxt, PlainTxtLen, CipherTxt, CipherTxtLen);
		case AI_CFB :	return CFB_EncUpdate(AlgInfo, PlainTxt, PlainTxtLen, CipherTxt, CipherTxtLen);
		default :		return CTR_FATAL_ERROR;
	}
}
/**************************************************************************
*
*/
static RET_VAL ECB_EncFinal(
		AES_ALG_INFO	*AlgInfo,		//	
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;
	DWORD		PaddByte;

	//	Padding
	PaddByte = PaddSet(AlgInfo->Buffer, BufLen, BlockLen, AlgInfo->PadType);
	if( PaddByte>BlockLen )		return PaddByte;

	if( PaddByte==0 ) 
	{
		*CipherTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	core part
	BlockCopy(CipherTxt, AlgInfo->Buffer);
	AES_Encrypt(ScheduledKey, CipherTxt);

	//
	*CipherTxtLen = BlockLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL CBC_EncFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;
	DWORD		PaddByte;

	//	Padding
	PaddByte = PaddSet(AlgInfo->Buffer, BufLen, BlockLen, AlgInfo->PadType);
	if( PaddByte>BlockLen )		return PaddByte;

	if( PaddByte==0 ) 
	{
		*CipherTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	core part
	BlockXor(CipherTxt, AlgInfo->Buffer, AlgInfo->ChainVar);
	AES_Encrypt(ScheduledKey, CipherTxt);
	BlockCopy(AlgInfo->ChainVar, CipherTxt);

	//
	*CipherTxtLen = BlockLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL OFB_EncFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN;
	DWORD		BufLen=AlgInfo->BufLen;
	DWORD		i;

	//	Check Output Memory Size
	*CipherTxtLen = BlockLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	for( i=0; i<BufLen; i++)
		CipherTxt[i] = (BYTE) (AlgInfo->Buffer[i] ^ AlgInfo->ChainVar[i]);

	//
	*CipherTxtLen = BufLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL CFB_EncFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*CipherTxtLen = BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	BlockXor(AlgInfo->ChainVar, AlgInfo->ChainVar, AlgInfo->Buffer);
	memcpy(CipherTxt, AlgInfo->ChainVar, BufLen);

	//
	*CipherTxtLen = BufLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
RET_VAL	AES_EncFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		*CipherTxtLen)	//	               
{
	switch( AlgInfo->ModeID ) 
	{
		case AI_ECB :	return ECB_EncFinal(AlgInfo, CipherTxt, CipherTxtLen);
		case AI_CBC :	return CBC_EncFinal(AlgInfo, CipherTxt, CipherTxtLen);
		case AI_OFB :	return OFB_EncFinal(AlgInfo, CipherTxt, CipherTxtLen);
		case AI_CFB :	return CFB_EncFinal(AlgInfo, CipherTxt, CipherTxtLen);
		default :		return CTR_FATAL_ERROR;
	}
}
/**************************************************************************
*
*/
RET_VAL	AES_DecInit(AES_ALG_INFO *AlgInfo)
{
	AlgInfo->BufLen = 0;
	if( AlgInfo->ModeID!=AI_ECB )
		memcpy(AlgInfo->ChainVar, AlgInfo->IV, AES_BLOCK_LEN);
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL ECB_DecUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	          pointer
		DWORD		CipherTxtLen,	//	               
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN;
	DWORD		BufLen=AlgInfo->BufLen;

	//
	*PlainTxtLen = BufLen + CipherTxtLen;

	//	No one block
	if( BufLen+CipherTxtLen <= BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)CipherTxtLen);
		AlgInfo->BufLen += CipherTxtLen;
		*PlainTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that CipherTxt and PlainTxt are the same buffer
	if( CipherTxt==PlainTxt )	return CTR_FATAL_ERROR;

	//	first block
	*PlainTxtLen = BufLen + CipherTxtLen;
	memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)(BlockLen - BufLen));
	CipherTxt += BlockLen - BufLen;
	CipherTxtLen -= BlockLen - BufLen;

	//	core part
	BlockCopy(PlainTxt, AlgInfo->Buffer);
	AES_Decrypt(ScheduledKey, PlainTxt);
	PlainTxt += BlockLen;
	while( CipherTxtLen>BlockLen ) 
	{
		BlockCopy(PlainTxt, CipherTxt);
		AES_Decrypt(ScheduledKey, PlainTxt);
		CipherTxt += BlockLen;
		PlainTxt += BlockLen;
		CipherTxtLen -= BlockLen;
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, CipherTxt, (int)CipherTxtLen);
	AlgInfo->BufLen = (AlgInfo->BufLen&0xF0000000) + CipherTxtLen;
	*PlainTxtLen -= CipherTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL CBC_DecUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	          pointer
		DWORD		CipherTxtLen,	//	               
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*PlainTxtLen = BufLen + CipherTxtLen;

	//	No one block
	if( BufLen+CipherTxtLen <= BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)CipherTxtLen);
		AlgInfo->BufLen += CipherTxtLen;
		*PlainTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that CipherTxt and PlainTxt are the same buffer
	if( CipherTxt==PlainTxt )	return CTR_FATAL_ERROR;

	//	first block
	*PlainTxtLen = BufLen + CipherTxtLen;
	memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)(BlockLen - BufLen));
	CipherTxt += BlockLen - BufLen;
	CipherTxtLen -= BlockLen - BufLen;

	//	core part
	BlockCopy(PlainTxt, AlgInfo->Buffer);
	AES_Decrypt(ScheduledKey, PlainTxt);
	BlockXor(PlainTxt, PlainTxt, AlgInfo->ChainVar);
	PlainTxt += BlockLen;
	if( CipherTxtLen<=BlockLen ) 
	{
		BlockCopy(AlgInfo->ChainVar, AlgInfo->Buffer);
	}
	else 
	{
		if( CipherTxtLen>BlockLen ) 
		{
			BlockCopy(PlainTxt, CipherTxt);
			AES_Decrypt(ScheduledKey, PlainTxt);
			BlockXor(PlainTxt, PlainTxt, AlgInfo->Buffer);
			CipherTxt += BlockLen;
			PlainTxt += BlockLen;
			CipherTxtLen -= BlockLen;
		}
		while( CipherTxtLen>BlockLen ) 
		{
			BlockCopy(PlainTxt, CipherTxt);
			AES_Decrypt(ScheduledKey, PlainTxt);
			BlockXor(PlainTxt, PlainTxt, CipherTxt-BlockLen);
			CipherTxt += BlockLen;
			PlainTxt += BlockLen;
			CipherTxtLen -= BlockLen;
		}
		BlockCopy(AlgInfo->ChainVar, CipherTxt-BlockLen);
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, CipherTxt, (int)CipherTxtLen);
	AlgInfo->BufLen = (AlgInfo->BufLen&0xF0000000) + CipherTxtLen;
	*PlainTxtLen -= CipherTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL OFB_DecUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	          pointer
		DWORD		CipherTxtLen,	//	               
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN;
	DWORD		BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*PlainTxtLen = BufLen + CipherTxtLen;

	//	No one block
	if( BufLen+CipherTxtLen <= BlockLen )
	{
		memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)CipherTxtLen);
		AlgInfo->BufLen += CipherTxtLen;
		*PlainTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that CipherTxt and PlainTxt are the same buffer
	if( PlainTxt==CipherTxt )
		return CTR_FATAL_ERROR;

	//	first block
	*PlainTxtLen = BufLen + CipherTxtLen;
	memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)(BlockLen - BufLen));
	CipherTxt += BlockLen - BufLen;
	CipherTxtLen -= BlockLen - BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	BlockXor(PlainTxt, AlgInfo->ChainVar, AlgInfo->Buffer);
	PlainTxt += BlockLen;
	while( CipherTxtLen>BlockLen ) 
	{
		AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
		BlockXor(PlainTxt, AlgInfo->ChainVar, CipherTxt);
		CipherTxt += BlockLen;
		PlainTxt += BlockLen;
		CipherTxtLen -= BlockLen;
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, CipherTxt, (int)CipherTxtLen);
	AlgInfo->BufLen = (AlgInfo->BufLen&0xF0000000) + CipherTxtLen;
	*PlainTxtLen -= CipherTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
static RET_VAL CFB_DecUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	          pointer
		DWORD		CipherTxtLen,	//	               
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN;
	DWORD		BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*PlainTxtLen = BufLen + CipherTxtLen;

	//	No one block
	if( BufLen+CipherTxtLen <= BlockLen ) 
	{
		memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)CipherTxtLen);
		AlgInfo->BufLen += CipherTxtLen;
		*PlainTxtLen = 0;
		return CTR_SUCCESS;
	}

	//	control the case that CipherTxt and PlainTxt are the same buffer
	if( PlainTxt==CipherTxt )
		return CTR_FATAL_ERROR;

	//	first block
	*PlainTxtLen = BufLen + CipherTxtLen;
	memcpy(AlgInfo->Buffer+BufLen, CipherTxt, (int)(BlockLen - BufLen));
	CipherTxt += BlockLen - BufLen;
	CipherTxtLen -= BlockLen - BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	BlockXor(PlainTxt, AlgInfo->ChainVar, AlgInfo->Buffer);
	BlockCopy(AlgInfo->ChainVar, AlgInfo->Buffer);
	PlainTxt += BlockLen;
	while( CipherTxtLen>BlockLen ) 
	{
		AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
		BlockXor(PlainTxt, AlgInfo->ChainVar, CipherTxt);
		BlockCopy(AlgInfo->ChainVar, CipherTxt);
		CipherTxt += BlockLen;
		PlainTxt += BlockLen;
		CipherTxtLen -= BlockLen;
	}

	//	save remained data
	memcpy(AlgInfo->Buffer, CipherTxt, (int)CipherTxtLen);
	AlgInfo->BufLen = (AlgInfo->BufLen&0xF0000000) + CipherTxtLen;
	*PlainTxtLen -= CipherTxtLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
RET_VAL	AES_DecUpdate(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*CipherTxt, 	//	         pointer
		DWORD		CipherTxtLen,	//	               
		BYTE		*PlainTxt,		//	         pointer
		DWORD		*PlainTxtLen)	//	              
{
	switch( AlgInfo->ModeID ) 
	{
		case AI_ECB :	return ECB_DecUpdate(AlgInfo, CipherTxt, CipherTxtLen, PlainTxt, PlainTxtLen);
		case AI_CBC :	return CBC_DecUpdate(AlgInfo, CipherTxt, CipherTxtLen, PlainTxt, PlainTxtLen);
		case AI_OFB :	return OFB_DecUpdate(AlgInfo, CipherTxt, CipherTxtLen, PlainTxt, PlainTxtLen);
		case AI_CFB :	return CFB_DecUpdate(AlgInfo, CipherTxt, CipherTxtLen, PlainTxt, PlainTxtLen);
		default :		return CTR_FATAL_ERROR;
	}
}
/**************************************************************************
*
*/
RET_VAL ECB_DecFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;
	RET_VAL		ret;

	//	Check Output Memory Size
	if( BufLen==0 ) 
	{
		*PlainTxtLen = 0;
		return CTR_SUCCESS;
	}
	*PlainTxtLen = BlockLen;

	if( BufLen!=BlockLen )	return CTR_CIPHER_LEN_ERROR;

	//	core part
	BlockCopy(PlainTxt, AlgInfo->Buffer);
	AES_Decrypt(ScheduledKey, PlainTxt);

	//	Padding Check
	ret = PaddCheck(PlainTxt, BlockLen, AlgInfo->PadType);
	if( ret==(DWORD)-3 )	return CTR_PAD_CHECK_ERROR;
	if( ret==(DWORD)-1 )	return CTR_FATAL_ERROR;

	*PlainTxtLen = BlockLen - ret;

	//
	return CTR_SUCCESS;
}
/*************************************************************************
*
*/
RET_VAL CBC_DecFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BlockLen=AES_BLOCK_LEN, BufLen=AlgInfo->BufLen;
	RET_VAL		ret;

	//	Check Output Memory Size
	if( BufLen==0 ) 
	{
		*PlainTxtLen = 0;
		return CTR_SUCCESS;
	}
	*PlainTxtLen = BlockLen;

	if( BufLen!=BlockLen )	return CTR_CIPHER_LEN_ERROR;

	//	core part
	BlockCopy(PlainTxt, AlgInfo->Buffer);
	AES_Decrypt(ScheduledKey, PlainTxt);
	BlockXor(PlainTxt, PlainTxt, AlgInfo->ChainVar);
	BlockCopy(AlgInfo->ChainVar, AlgInfo->Buffer);

	//	Padding Check
	ret = PaddCheck(PlainTxt, BlockLen, AlgInfo->PadType);
	if( ret==(DWORD)-3 )	return CTR_PAD_CHECK_ERROR;
	if( ret==(DWORD)-1 )	return CTR_FATAL_ERROR;

	*PlainTxtLen = BlockLen - ret;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
RET_VAL OFB_DecFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		i, BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*PlainTxtLen = BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	for( i=0; i<BufLen; i++)
		PlainTxt[i] = (BYTE) (AlgInfo->Buffer[i] ^ AlgInfo->ChainVar[i]);

	*PlainTxtLen = BufLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
RET_VAL CFB_DecFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*PlainTxt,		//	        pointer
		DWORD		*PlainTxtLen)	//	              
{
	DWORD		*ScheduledKey=AlgInfo->RoundKey;
	DWORD		BufLen=AlgInfo->BufLen;

	//	Check Output Memory Size
	*PlainTxtLen = BufLen;

	//	core part
	AES_Encrypt(ScheduledKey, AlgInfo->ChainVar);
	BlockXor(AlgInfo->ChainVar, AlgInfo->ChainVar, AlgInfo->Buffer);
	memcpy(PlainTxt, AlgInfo->ChainVar, BufLen);

	*PlainTxtLen = BufLen;

	//
	return CTR_SUCCESS;
}
/**************************************************************************
*
*/
RET_VAL	AES_DecFinal(
		AES_ALG_INFO	*AlgInfo,
		BYTE		*PlainTxt,		//	         pointer
		DWORD		*PlainTxtLen)	//	              
{
	switch( AlgInfo->ModeID ) 
	{
		case AI_ECB :	return ECB_DecFinal(AlgInfo, PlainTxt, PlainTxtLen);
		case AI_CBC :	return CBC_DecFinal(AlgInfo, PlainTxt, PlainTxtLen);
		case AI_OFB :	return OFB_DecFinal(AlgInfo, PlainTxt, PlainTxtLen);
		case AI_CFB :	return CFB_DecFinal(AlgInfo, PlainTxt, PlainTxtLen);
		default :		return CTR_FATAL_ERROR;
	}
}

/*************** END OF FILE **********************************************/
AES.c
 
 
<pre name="code" class="cpp">/*************** Header files *********************************************/
#include "aes.h"

/*************** Assertions ***********************************************/

/*************** New Data Types *******************************************/
typedef struct {
	DWORD	k_len;
	DWORD	RK[64];
} RIJNDAEL_CIPHER_KEY;

/*************** Definitions / Macros  ************************************/
#define u1byte	BYTE
#define u4byte	DWORD
#define rotl	ROTL_DWORD
#define rotr	ROTR_DWORD
#define byte(x,n)	((u1byte)((x) >> (8 * n)))

#define LARGE_TABLES

#define ff_mult(a,b)	(a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)

#ifdef LARGE_TABLES
	#define ls_box(x)				 /
		( fl_tab[0][byte(x, 0)] ^	 /
		  fl_tab[1][byte(x, 1)] ^	 /
		  fl_tab[2][byte(x, 2)] ^	 /
		  fl_tab[3][byte(x, 3)] )
#else
	#define ls_box(x)							 /
		((u4byte)sbx_tab[byte(x, 0)] <<  0) ^	 /
		((u4byte)sbx_tab[byte(x, 1)] <<  8) ^	 /
		((u4byte)sbx_tab[byte(x, 2)] << 16) ^	 /
		((u4byte)sbx_tab[byte(x, 3)] << 24)
#endif
/*************** Global Variables *****************************************/
static u1byte	log_tab[256];
static u1byte	pow_tab[256];
static u1byte	sbx_tab[256];
static u1byte	isb_tab[256];
static u4byte	rco_tab[ 10];
static u4byte	ft_tab[4][256];
static u4byte	it_tab[4][256];

#ifdef	LARGE_TABLES
  static u4byte  fl_tab[4][256];
  static u4byte  il_tab[4][256];
#endif
static u4byte	tab_gen = 0;

/*************** Prototypes ***********************************************/
static void gen_tabs(void)
{
	u4byte	i, t;
	u1byte	p, q;

	/* log and power tables for GF(2**8) finite field with	*/
	/* 0x11b as modular polynomial - the simplest prmitive	*/
	/* root is 0x11, used here to generate the tables		*/

	log_tab[7] = 0;
	for(i = 0,p = 1; i < 256; ++i)
	{
		pow_tab[i] = (BYTE)p;
		log_tab[p] = (BYTE)i;

		p = (BYTE)(p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0));
	}

	log_tab[1] = 0;
	p = 1;

	for(i = 0; i < 10; ++i)
	{
		rco_tab[i] = p; 

		p = (BYTE)((p << 1) ^ (p & 0x80 ? 0x1b : 0));
	}
	/* note that the affine byte transformation matrix in	*/
	/* rijndael specification is in big endian format with	*/
	/* bit 0 as the most significant bit. In the remainder	*/
	/* of the specification the bits are numbered from the	*/
	/* least significant end of a byte. 					*/

	for(i = 0; i < 256; ++i)
	{	
		p = (BYTE)(i ? pow_tab[255 - log_tab[i]] : 0);
		q = p;
		q = (BYTE)((q >> 7) | (q << 1));
		p ^= q;
		q = (BYTE)((q >> 7) | (q << 1));
		p ^= q;
		q = (BYTE)((q >> 7) | (q << 1));
		p ^= q;
		q = (BYTE)((q >> 7) | (q << 1));
		p ^= q ^ 0x63;
		sbx_tab[i] = (u1byte)p;
		isb_tab[p] = (u1byte)i;
	}

	for(i = 0; i < 256; ++i)
	{
		p = sbx_tab[i]; 
#ifdef	LARGE_TABLES
		t = p;
		fl_tab[0][i] = t;
		fl_tab[1][i] = rotl(t,  8);
		fl_tab[2][i] = rotl(t, 16);
		fl_tab[3][i] = rotl(t, 24);
#endif
		t = ((u4byte)ff_mult(2, p)) |
			((u4byte)p <<  8) |
			((u4byte)p << 16) |
			((u4byte)ff_mult(3, p) << 24);
		
		ft_tab[0][i] = t;
		ft_tab[1][i] = rotl(t,	8);
		ft_tab[2][i] = rotl(t, 16);
		ft_tab[3][i] = rotl(t, 24);

		p = isb_tab[i]; 
#ifdef	LARGE_TABLES
		t = p; il_tab[0][i] = t; 
		il_tab[1][i] = rotl(t,	8); 
		il_tab[2][i] = rotl(t, 16); 
		il_tab[3][i] = rotl(t, 24);
#endif 
		t = ((u4byte)ff_mult(14, p)) |
			((u4byte)ff_mult( 9, p) <<	8) |
			((u4byte)ff_mult(13, p) << 16) |
			((u4byte)ff_mult(11, p) << 24);
		
		it_tab[0][i] = t; 
		it_tab[1][i] = rotl(t,	8); 
		it_tab[2][i] = rotl(t, 16); 
		it_tab[3][i] = rotl(t, 24); 
	}

	tab_gen = 1;
};
#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
#define imix_col(y,x)		/
	 u	= star_x(x);		/
	 v	= star_x(u);		/
	 w	= star_x(v);		/
	 t	= w ^ (x);			/
	(y) = u ^ v ^ w;		/
	(y) ^= rotr(u ^ t,  8) ^ /
		  rotr(v ^ t, 16) ^ /
		  rotr(t,24)
/**************************************************************************
*
*	Function Description ...
*	
*	Return values:
*		- CTR_SUCCESS						             .
*		...
*/
static void RIJNDAEL_KeySchedule(
		BYTE		*UserKey,		//	          
		DWORD		k_len,			//	         DWORD  
		DWORD		*e_key)			//	    Round Key   /  
{
	u4byte	i, t;

	////
	if(!tab_gen)
		gen_tabs();

	LITTLE_B2D(&(UserKey[ 0]), e_key[0]);
	LITTLE_B2D(&(UserKey[ 4]), e_key[1]);
	LITTLE_B2D(&(UserKey[ 8]), e_key[2]);
	LITTLE_B2D(&(UserKey[12]), e_key[3]);

        switch(k_len)
	{
		case 4:
				t = e_key[3];
				for(i = 0; i < 10; ++i) {
					t = ls_box(rotr(t,  8)) ^ rco_tab[i];
					t ^= e_key[4 * i];     e_key[4 * i + 4] = t;
					t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t;
					t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t;
					t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t;
				}
				break;

		case 6:
				LITTLE_B2D(&(UserKey[16]), e_key[4]);
				LITTLE_B2D(&(UserKey[20]), e_key[5]);
				t = e_key[5];
				for(i = 0; i < 8; ++i) {
					t = ls_box(rotr(t,	8)) ^ rco_tab[i];
					t ^= e_key[6 * i];	   e_key[6 * i + 6] = t;
					t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t;
					t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t;
					t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t;
					t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t;
					t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t;
				}
//					loop6(i);
				break;

		case 8:
				LITTLE_B2D(&(UserKey[16]), e_key[4]);
				LITTLE_B2D(&(UserKey[20]), e_key[5]);
				LITTLE_B2D(&(UserKey[24]), e_key[6]);
				LITTLE_B2D(&(UserKey[28]), e_key[7]);
				t = e_key[7];
				for(i = 0; i < 7; ++i) {
					t = ls_box(rotr(t,	8)) ^ rco_tab[i];
					t ^= e_key[8 * i];	   e_key[8 * i + 8] = t;
					t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t;
					t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t;
					t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t;
					t  = e_key[8 * i + 4] ^ ls_box(t);
					e_key[8 * i + 12] = t;
					t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t;
					t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t;
					t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t;
				}
//					loop8(i);
				break;
	}
}
/*************** Function *************************************************
* 
*/
RET_VAL AES_EncKeySchedule(
		BYTE		*UserKey,		//	          
		DWORD		UserKeyLen,		//	              
		AES_ALG_INFO	*AlgInfo)	//	   /    Round Key   /  
{
	RIJNDAEL_CIPHER_KEY	*RK_Struct=(RIJNDAEL_CIPHER_KEY *) AlgInfo->RoundKey;
	DWORD	*e_key=RK_Struct->RK;	//	64 DWORDs
	DWORD	k_len;

	//	UserKey              error   
	if( (UserKeyLen!=16) && (UserKeyLen!=24) && (UserKeyLen!=32) )
		return CTR_INVALID_USERKEYLEN;

	////
	k_len = (UserKeyLen + 3) / 4;
	RK_Struct->k_len = k_len;

	RIJNDAEL_KeySchedule(UserKey, k_len, e_key);

	return CTR_SUCCESS;
}
/*************** Function *************************************************
* 
*/
RET_VAL AES_DecKeySchedule(
		BYTE		*UserKey,		//	          
		DWORD		UserKeyLen,		//	              
		AES_ALG_INFO	*AlgInfo)	//	   /    Round Key   /  
{
	RIJNDAEL_CIPHER_KEY	*RK_Struct=(RIJNDAEL_CIPHER_KEY *) AlgInfo->RoundKey;
	DWORD	*d_key=RK_Struct->RK;	//	64 DWORDs
	DWORD	k_len, t_key[64];
	u4byte	i, t, u, v, w;

	//	UserKey              error   
	if( (UserKeyLen!=16) && (UserKeyLen!=24) && (UserKeyLen!=32) )
		return CTR_INVALID_USERKEYLEN;

	////
	k_len = (UserKeyLen + 3) / 4;
	RK_Struct->k_len = k_len;

	RIJNDAEL_KeySchedule(UserKey, k_len, t_key);

	d_key[0] = t_key[4 * k_len + 24];
	d_key[1] = t_key[4 * k_len + 25];
	d_key[2] = t_key[4 * k_len + 26];
	d_key[3] = t_key[4 * k_len + 27];

	for( i=4; i<4*(k_len+6); i+=4) {
		imix_col(d_key[i+0], t_key[4*k_len+24-i+0]);
		imix_col(d_key[i+1], t_key[4*k_len+24-i+1]);
		imix_col(d_key[i+2], t_key[4*k_len+24-i+2]);
		imix_col(d_key[i+3], t_key[4*k_len+24-i+3]);
	}
	d_key[i+0] = t_key[4*k_len+24-i+0];
	d_key[i+1] = t_key[4*k_len+24-i+1];
	d_key[i+2] = t_key[4*k_len+24-i+2];
	d_key[i+3] = t_key[4*k_len+24-i+3];

	return CTR_SUCCESS;
}
/*
	DWORD	A, B, C, D, T0, T1, *K=AlgInfo->RoundKey;

	////
	if( UserKeyLen!=SEED_USER_KEY_LEN )
		return CTR_INVALID_USERKEYLEN;
	////
	BIG_B2D( &(UserKey[0]), A);
	BIG_B2D( &(UserKey[4]), B);
	BIG_B2D( &(UserKey[8]), C);
	BIG_B2D( &(UserKey[12]), D);

	T0 = A + C - KC0;
	T1 = B - D + KC0;
	K[0] = SEED_SL[0][(T0    )&0xFF] ^ SEED_SL[1][(T0>> 8)&0xFF]
		 ^ SEED_SL[2][(T0>>16)&0xFF] ^ SEED_SL[3][(T0>>24)&0xFF];
	K[1] = SEED_SL[0][(T1    )&0xFF] ^ SEED_SL[1][(T1>> 8)&0xFF]
		 ^ SEED_SL[2][(T1>>16)&0xFF] ^ SEED_SL[3][(T1>>24)&0xFF];;

	EncRoundKeyUpdate0(K+ 2, A, B, C, D, KC1 );
	EncRoundKeyUpdate1(K+ 4, A, B, C, D, KC2 );
	EncRoundKeyUpdate0(K+ 6, A, B, C, D, KC3 );
	EncRoundKeyUpdate1(K+ 8, A, B, C, D, KC4 );
	EncRoundKeyUpdate0(K+10, A, B, C, D, KC5 );
	EncRoundKeyUpdate1(K+12, A, B, C, D, KC6 );
	EncRoundKeyUpdate0(K+14, A, B, C, D, KC7 );
	EncRoundKeyUpdate1(K+16, A, B, C, D, KC8 );
	EncRoundKeyUpdate0(K+18, A, B, C, D, KC9 );
	EncRoundKeyUpdate1(K+20, A, B, C, D, KC10);
	EncRoundKeyUpdate0(K+22, A, B, C, D, KC11);
	EncRoundKeyUpdate1(K+24, A, B, C, D, KC12);
	EncRoundKeyUpdate0(K+26, A, B, C, D, KC13);
	EncRoundKeyUpdate1(K+28, A, B, C, D, KC14);
	EncRoundKeyUpdate0(K+30, A, B, C, D, KC15);

	//	Remove sensitive data
	A = B = C = D = T0 = T1 = 0;
	K = NULL;

	//
	return CTR_SUCCESS;
*/
/*************** Macros ***************************************************/
#define f_nround(bo, bi, k) {				/
	bo[0] = ft_tab[0][byte(bi[0],0)]		/
		  ^ ft_tab[1][byte(bi[1],1)]		/
		  ^ ft_tab[2][byte(bi[2],2)]		/
		  ^ ft_tab[3][byte(bi[3],3)] ^ k[0];/
	bo[1] = ft_tab[0][byte(bi[1],0)]		/
		  ^ ft_tab[1][byte(bi[2],1)]		/
		  ^ ft_tab[2][byte(bi[3],2)]		/
		  ^ ft_tab[3][byte(bi[0],3)] ^ k[1];/
	bo[2] = ft_tab[0][byte(bi[2],0)]		/
		  ^ ft_tab[1][byte(bi[3],1)]		/
		  ^ ft_tab[2][byte(bi[0],2)]		/
		  ^ ft_tab[3][byte(bi[1],3)] ^ k[2];/
	bo[3] = ft_tab[0][byte(bi[3],0)]		/
		  ^ ft_tab[1][byte(bi[0],1)]		/
		  ^ ft_tab[2][byte(bi[1],2)]		/
		  ^ ft_tab[3][byte(bi[2],3)] ^ k[3];/
	k += 4;									/
}
#define i_nround(bo, bi, k) {				/
	bo[0] = it_tab[0][byte(bi[0],0)]		/
		  ^ it_tab[1][byte(bi[3],1)]		/
		  ^ it_tab[2][byte(bi[2],2)]		/
		  ^ it_tab[3][byte(bi[1],3)] ^ k[0];/
	bo[1] = it_tab[0][byte(bi[1],0)]		/
		  ^ it_tab[1][byte(bi[0],1)]		/
		  ^ it_tab[2][byte(bi[3],2)]		/
		  ^ it_tab[3][byte(bi[2],3)] ^ k[1];/
	bo[2] = it_tab[0][byte(bi[2],0)]		/
		  ^ it_tab[1][byte(bi[1],1)]		/
		  ^ it_tab[2][byte(bi[0],2)]		/
		  ^ it_tab[3][byte(bi[3],3)] ^ k[2];/
	bo[3] = it_tab[0][byte(bi[3],0)]		/
		  ^ it_tab[1][byte(bi[2],1)]		/
		  ^ it_tab[2][byte(bi[1],2)]		/
		  ^ it_tab[3][byte(bi[0],3)] ^ k[3];/
	k += 4;					/
}
#ifdef LARGE_TABLES
	#define f_lround(bo, bi, k) {				/
		bo[0] = fl_tab[0][byte(bi[0],0)]		/
			  ^ fl_tab[1][byte(bi[1],1)]		/
			  ^ fl_tab[2][byte(bi[2],2)]		/
			  ^ fl_tab[3][byte(bi[3],3)] ^ k[0];/
		bo[1] = fl_tab[0][byte(bi[1],0)]		/
			  ^ fl_tab[1][byte(bi[2],1)]		/
			  ^ fl_tab[2][byte(bi[3],2)]		/
			  ^ fl_tab[3][byte(bi[0],3)] ^ k[1];/
		bo[2] = fl_tab[0][byte(bi[2],0)]		/
			  ^ fl_tab[1][byte(bi[3],1)]		/
			  ^ fl_tab[2][byte(bi[0],2)]		/
			  ^ fl_tab[3][byte(bi[1],3)] ^ k[2];/
		bo[3] = fl_tab[0][byte(bi[3],0)]		/
			  ^ fl_tab[1][byte(bi[0],1)]		/
			  ^ fl_tab[2][byte(bi[1],2)]		/
			  ^ fl_tab[3][byte(bi[2],3)] ^ k[3];/
	}

	#define i_lround(bo, bi, k) {				/
		bo[0] = il_tab[0][byte(bi[0],0)]		/
			  ^ il_tab[1][byte(bi[3],1)]		/
			  ^ il_tab[2][byte(bi[2],2)]		/
			  ^ il_tab[3][byte(bi[1],3)] ^ k[0];/
		bo[1] = il_tab[0][byte(bi[1],0)]		/
			  ^ il_tab[1][byte(bi[0],1)]		/
			  ^ il_tab[2][byte(bi[3],2)]		/
			  ^ il_tab[3][byte(bi[2],3)] ^ k[1];/
		bo[2] = il_tab[0][byte(bi[2],0)]		/
			  ^ il_tab[1][byte(bi[1],1)]		/
			  ^ il_tab[2][byte(bi[0],2)]		/
			  ^ il_tab[3][byte(bi[3],3)] ^ k[2];/
		bo[3] = il_tab[0][byte(bi[3],0)]		/
			  ^ il_tab[1][byte(bi[2],1)]		/
			  ^ il_tab[2][byte(bi[1],2)]		/
			  ^ il_tab[3][byte(bi[0],3)] ^ k[3];/
		}
#else
	#define f_rl(bo, bi, n, k)										/
		bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^					/
			rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]),  8) ^	/
			rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^	/
			rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)
	#define i_rl(bo, bi, n, k)										/
		bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^					/
			rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]),  8) ^	/
			rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^	/
			rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
	#define f_lround(bo, bi, k) /
		f_rl(bo, bi, 0, k); 	/
		f_rl(bo, bi, 1, k); 	/
		f_rl(bo, bi, 2, k); 	/
		f_rl(bo, bi, 3, k)

	#define i_lround(bo, bi, k) /
		i_rl(bo, bi, 0, k); 	/
		i_rl(bo, bi, 1, k); 	/
		i_rl(bo, bi, 2, k); 	/
		i_rl(bo, bi, 3, k)
#endif
/************** Function *************************************************
*	
*/
void	AES_Encrypt(
		void		*CipherKey,		//	 /    Round Key
		BYTE		*Data)			//	                 pointer
{
	RIJNDAEL_CIPHER_KEY	*RK_Struct=CipherKey;
	DWORD	*e_key=RK_Struct->RK;	//	64 DWORDs
	DWORD	k_len=RK_Struct->k_len;
	u4byte	b0[4], b1[4], *kp;

	LITTLE_B2D(&(Data[ 0]), b0[0]);
	LITTLE_B2D(&(Data[ 4]), b0[1]);
	LITTLE_B2D(&(Data[ 8]), b0[2]);
	LITTLE_B2D(&(Data[12]), b0[3]);
	//
	b0[0] ^= e_key[0];
	b0[1] ^= e_key[1];
	b0[2] ^= e_key[2];
	b0[3] ^= e_key[3];

	kp = e_key + 4;

	switch( k_len ) {
		case 8 :
			f_nround(b1, b0, kp); f_nround(b0, b1, kp);
		case 6 :
			f_nround(b1, b0, kp); f_nround(b0, b1, kp);
		case 4 :
			f_nround(b1, b0, kp); f_nround(b0, b1, kp);
			f_nround(b1, b0, kp); f_nround(b0, b1, kp);
			f_nround(b1, b0, kp); f_nround(b0, b1, kp);
			f_nround(b1, b0, kp); f_nround(b0, b1, kp);
			f_nround(b1, b0, kp); f_lround(b0, b1, kp);
	}
	//
	LITTLE_D2B(b0[0], &(Data[ 0]));
	LITTLE_D2B(b0[1], &(Data[ 4]));
	LITTLE_D2B(b0[2], &(Data[ 8]));
	LITTLE_D2B(b0[3], &(Data[12]));
}
/*************** Function *************************************************
*	
*/
void	AES_Decrypt(
		void		*CipherKey,		//	 /    Round Key
		BYTE		*Data)			//	                 pointer
{
	RIJNDAEL_CIPHER_KEY	*RK_Struct=CipherKey;
	DWORD	*d_key=RK_Struct->RK;	//	64 DWORDs
	DWORD	k_len=RK_Struct->k_len;
	u4byte	b0[4], b1[4], *kp;
	LITTLE_B2D(&(Data[ 0]), b0[0]);
	LITTLE_B2D(&(Data[ 4]), b0[1]);
	LITTLE_B2D(&(Data[ 8]), b0[2]);
	LITTLE_B2D(&(Data[12]), b0[3]);
	//
	b0[0] ^= d_key[0];
	b0[1] ^= d_key[1];
	b0[2] ^= d_key[2];
	b0[3] ^= d_key[3];

	kp = d_key + 4;

	switch( k_len ) {
		case 8 :
			i_nround(b1, b0, kp); i_nround(b0, b1, kp);
		case 6 :
			i_nround(b1, b0, kp); i_nround(b0, b1, kp);
		case 4 :
			i_nround(b1, b0, kp); i_nround(b0, b1, kp);
			i_nround(b1, b0, kp); i_nround(b0, b1, kp);
			i_nround(b1, b0, kp); i_nround(b0, b1, kp);
			i_nround(b1, b0, kp); i_nround(b0, b1, kp);
			i_nround(b1, b0, kp); i_lround(b0, b1, kp);
	}
	//
	LITTLE_D2B(b0[0], &(Data[ 0]));
	LITTLE_D2B(b0[1], &(Data[ 4]));
	LITTLE_D2B(b0[2], &(Data[ 8]));
	LITTLE_D2B(b0[3], &(Data[12]));
}
/*************** END OF FILE **********************************************/

다음은 제 가 위 에 봉 인 된 두 개의 암호 화 복호화 함수 에 대한 실현 입 니 다.간단 합 니 다.키 는 고정 되 어 있 습 니 다.
너 는 16 개의 Byte 문자열 을 고정 시 킬 수도 있 고,내 코드 에 죽은 것 을 쓸 수도 있다.0x 10 에서 0x1F
static int AESEncode (const char* srcString, int srcLen, char** dstString, int* dstLen)
{
	//16 * (trunc(string_length / 16) + 1)。
	char *pOut=0;
	unsigned int len = 16 * (srcLen/16 + 1);
	BYTE	UserKey[AES_USER_KEY_LEN]={0};
	BYTE	IV[AES_BLOCK_LEN]={0};
	DWORD	UKLen, IVLen, SrcLen, DstLen;
	RET_VAL	ret;
	AES_ALG_INFO	AlgInfo;
	int eelen = 0;
	UKLen = 16;
	IVLen = 16;
#ifdef _DEBUG
	int t = 0x10;
	for (int i=0; i<16; i++)
	{
		UserKey[i] = t+i;
	}
#else
	snprintf ((char*)UserKey, sizeof(UserKey)-1, "%s", g_Config.encryptKey);
#endif
	pOut = (char*)calloc (1, len+4);
	if (pOut == NULL)	
		return -1;
	DstLen = len;
	//
	AES_SetAlgInfo(AES_ModeType, AES_PadType, IV, &AlgInfo);
	//	Encryption
	ret = AES_EncKeySchedule(UserKey, UKLen, &AlgInfo);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_EncKeySchedule() returns.");
		safe_free (pOut);
		return -1;
	}
	ret = AES_EncInit(&AlgInfo);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_EncInit() returns.");
		safe_free (pOut);
		return -1;
	}
	ret = AES_EncUpdate(&AlgInfo, (unsigned char*)srcString, SrcLen, (unsigned char*)pOut, &DstLen);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_EncUpdate() returns.");
		safe_free (pOut);
		return -1;
	}
	eelen = DstLen;
	ret = AES_EncFinal(&AlgInfo, (unsigned char*)pOut+eelen, &DstLen);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_EncFinal() returns.");
		safe_free (pOut);
		return -1;
	}
	eelen += DstLen;
	*dstLen = eelen;
	*dstString = pOut;
	return 0;
}

static int AESDecode (const char* srcString, int srcLen, char** dstString, int* dstLen)
{
	//FILE	*pIn, *pOut;
	char* pOut = 0;
	unsigned char UserKey[AES_USER_KEY_LEN]={0};
	unsigned char IV[AES_BLOCK_LEN]={0};
	//unsigned char SrcData[1024+32], DstData[1024+32];
	unsigned int  UKLen, IVLen;
	unsigned int SrcLen, DstLen;
	RET_VAL	ret;
	AES_ALG_INFO	AlgInfo;
	int ddlen = 0;
	SrcLen = srcLen;
	pOut = (char*)calloc(1, SrcLen+2);
	if (pOut == NULL) return -1;
	DstLen = SrcLen;
	UKLen = 16;
	IVLen = 16;
#ifdef _DEBUG
	int t = 0x10;
	for (int i=0; i<16; i++)
	{
		UserKey[i] = t+i;
	}
#else
	snprintf ((char*)UserKey, sizeof(UserKey)-1, "%s", g_Config.encryptKey);
#endif
	AES_SetAlgInfo(AES_ModeType, AES_PadType, IV, &AlgInfo);
	//Decryption
	//if( ModeType==AI_ECB || ModeType==AI_CBC )
	ret = AES_DecKeySchedule(UserKey, UKLen, &AlgInfo);
	//else if( ModeType==AI_OFB || ModeType==AI_CFB )
	//	ret = AES_EncKeySchedule(UserKey, UKLen, &AlgInfo);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_DecKeySchedule() returns.");
		safe_free (pOut);
		return -1;
	}
	ret = AES_DecInit(&AlgInfo);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_DecInit() returns.");
		safe_free (pOut);
		return -1;
	}
	ret = AES_DecUpdate(&AlgInfo, (unsigned char*)srcString, SrcLen, (unsigned char*)pOut, &DstLen);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_DecUpdate() returns.");
		safe_free (pOut);
		return -1;
	}
	ddlen = DstLen;
	ret = AES_DecFinal(&AlgInfo, (unsigned char*)pOut+ddlen, &DstLen);
	if( ret!=CTR_SUCCESS )	
	{
		writelog(LOG_DEBUG, "AES_DecFinal() returns.");
		safe_free (pOut);
		return -1;
	}
	ddlen += DstLen;
	*dstLen = ddlen;
	*dstString = pOut;
	return 0;
}
 
 

좋은 웹페이지 즐겨찾기