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 에서 0x1Fstatic 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; }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Android 와. net 이 서로 연 결 된 RSA 암호 화. net RSA 암호 화 에 사용 할 공개 키 는 다음 과 같은 문자열 입 니 다. nGb = < / Modulus > < Exponent > AQAB < / Exponent > < / RSAKyValue > 와 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.