Rcon = new _u8[44];
_u8 Rcon_temp[44] =
{ 0x00?? 0x00?? 0x00?? 0x00?? 0x01?? 0x00?? 0x00?? 0x00?? 0x02?? 0x00?? 0x00?? 0x00??
0x04?? 0x00?? 0x00?? 0x00?? 0x08?? 0x00?? 0x00?? 0x00?? 0x10?? 0x00?? 0x00??
0x00?? 0x20?? 0x00?? 0x00?? 0x00?? 0x40?? 0x00?? 0x00?? 0x00?? 0x80?? 0x00??
0x00?? 0x00?? 0x1b?? 0x00?? 0x00?? 0x00?? 0x36?? 0x00?? 0x00?? 0x00 };
for (int i = 0; i < 44; i++)
{
Rcon[i] = Rcon_temp[i];
}
}
void AES::aes_init(ctx_aes* aes?? int keySize?? _u8* keyBytes)
{
SetNbNkNr(aes?? keySize);
memcpy(aes->key?? keyBytes?? keySize);
KeyExpansion(aes);
}
void AES::aes_cipher(ctx_aes* aes?? _u8* input?? _u8* output) // encipher 16-bit input
{
// state = input
int i;
int round;
memset(&aes->State[0][0]?? 0?? 16);
for (i = 0; i < (4 * aes->Nb); i++)  //
{
aes->State[i % 4][i / 4] = input[i];
}
AddRoundKey(aes?? 0);
for (round = 1; round <= (aes->Nr - 1); round++)  // main round loop
{
SubBytes(aes);
ShiftRows(aes);
MixColumns(aes);
AddRoundKey(aes?? round);
}  // main round loop
SubBytes(aes);
ShiftRows(aes);
AddRoundKey(aes?? aes->Nr);
// output = state
for (i = 0; i < (4 * aes->Nb); i++)
{
output[i] = aes->State[i % 4][i / 4];
}
}  // Cipher()
void AES::aes_invcipher(ctx_aes* aes?? _u8* input?? _u8* output) // decipher 16-bit input
{
// state = input
int i;
int round;
memset(&aes->State[0][0]?? 0?? 16);
for (i = 0; i < (4 * aes->Nb); i++)
{
aes->State[i % 4][i / 4] = input[i];
}
AddRoundKey(aes?? aes->Nr);
for (round = aes->Nr - 1; round >= 1; round--)  // main round loop
{
InvShiftRows(aes);
InvSubBytes(aes);
AddRoundKey(aes?? round);
InvMixColumns(aes);
}  // end main round loop for InvCipher
InvShiftRows(aes);
InvSubBytes(aes);
AddRoundKey(aes?? 0);
// output = state
for (i = 0; i < (4 * aes->Nb); i++)
{
output[i] = aes->State[i % 4][i / 4];
}
}  // InvCipher()
void AES::SetNbNkNr(ctx_aes* aes?? _int32 keyS)
{
aes->Nb = 4;    // block size always = 4 words = 16 bytes = 128 bits for AES
aes->Nk = 4;
if (keyS == Bits128)
{
aes->Nk = 4;   // key size = 4 words = 16 bytes = 128 bits
aes->Nr = 10;  // rounds for algorithm = 10
}
else if (keyS == Bits192)
{
aes->Nk = 6;   // 6 words = 24 bytes = 192 bits
aes->Nr = 12;
}
else if (keyS == Bits256)
{
aes->Nk = 8;   // 8 words = 32 bytes = 256 bits
aes->Nr = 14;
}
}  // SetNbNkNr()
void AES::AddRoundKey(ctx_aes* aes?? _int32 round)
{
int r?? c;
for (r = 0; r < 4; r++)
{
for (c = 0; c < 4; c++)
{  //w:    4*x+y
aes->State[r][c] = (unsigned char) ((int) aes->State[r][c]
^ (int) aes->w[4 * ((round * 4) + c) + r]);
}
}
}  // AddRoundKey()
void AES::SubBytes(ctx_aes* aes)
{
int r?? c;
for (r = 0; r < 4; r++)
{
for (c = 0; c < 4; c++)
{
aes->State[r][c] = Sbox[16 * (aes->State[r][c] >> 4)
+ (aes->State[r][c] & 0x0f)];
}
}
}  // SubBytes
void AES::InvSubBytes(ctx_aes* aes)
{
int r?? c;
for (r = 0; r < 4; r++)
{
for (c = 0; c < 4; c++)
{
aes->State[r][c] = iSbox[16 * (aes->State[r][c] >> 4)
+ (aes->State[r][c] & 0x0f)];
}
}
}  // InvSubBytes
void AES::ShiftRows(ctx_aes* aes)
{
unsigned char temp[4 * 4];
int r?? c;
for (r = 0; r < 4; r++)  // copy State into temp[]
{
for (c = 0; c < 4; c++)
{
temp[4 * r + c] = aes->State[r][c];
}
}
//??
for (r = 1; r < 4; r++)  // shift temp into State
{
for (c = 0; c < 4; c++)
{
aes->State[r][c] = temp[4 * r + (c + r) % aes->Nb];
}
}
}  // ShiftRows()
void AES::InvShiftRows(ctx_aes* aes)
{
unsigned char temp[4 * 4];
int r?? c;
for (r = 0; r < 4; r++)  // copy State into temp[]
{
for (c = 0; c < 4; c++)
{
temp[4 * r + c] = aes->State[r][c];
}
}
for (r = 1; r < 4; r++)  // shift temp into State
{
for (c = 0; c < 4; c++)
{
aes->State[r][(c + r) % aes->Nb] = temp[4 * r + c];
}
}
}  // InvShiftRows()
void AES::MixColumns(ctx_aes* aes)
{
unsigned char temp[4 * 4];
int r?? c;
for (r = 0; r < 4; r++)  // copy State into temp[]
{
for (c = 0; c < 4; c++)
{
temp[4 * r + c] = aes->State[r][c];
}
}
for (c = 0; c < 4; c++)
{
aes->State[0][c] = (unsigned char) ((int) gfmultby02(temp[0 + c])
^ (int) gfmultby03(temp[4 * 1 + c])
^ (int) gfmultby01(temp[4 * 2 + c])
^ (int) gfmultby01(temp[4 * 3 + c]));
aes->State[1][c] = (unsigned char) ((int) gfmultby01(temp[0 + c])
^ (int) gfmultby02(temp[4 * 1 + c])
^ (int) gfmultby03(temp[4 * 2 + c])
^ (int) gfmultby01(temp[4 * 3 + c]));
aes->State[2][c] = (unsigned char) ((int) gfmultby01(temp[0 + c])
^ (int) gfmultby01(temp[4 * 1 + c])
^ (int) gfmultby02(temp[4 * 2 + c])
^ (int) gfmultby03(temp[4 * 3 + c]));
aes->State[3][c] = (unsigned char) ((int) gfmultby03(temp[0 + c])
^ (int) gfmultby01(temp[4 * 1 + c])
^ (int) gfmultby01(temp[4 * 2 + c])
^ (int) gfmultby02(temp[4 * 3 + c]));
}
}  // MixColumns
void AES::InvMixColumns(ctx_aes* aes)
{
unsigned char temp[4 * 4];
int r?? c;
for (r = 0; r < 4; r++)  // copy State into temp[]
{
for (c = 0; c < 4; c++)
{
temp[4 * r + c] = aes->State[r][c];
}
}
for (c = 0; c < 4; c++)
{
aes->State[0][c] = (unsigned char) ((int) gfmultby0e(temp[c])
^ (int) gfmultby0b(temp[4 + c])
^ (int) gfmultby0d(temp[4 * 2 + c])
^ (int) gfmultby09(temp[4 * 3 + c]));
aes->State[1][c] = (unsigned char) ((int) gfmultby09(temp[c])
^ (int) gfmultby0e(temp[4 + c])
^ (int) gfmultby0b(temp[4 * 2 + c])
^ (int) gfmultby0d(temp[4 * 3 + c]));
aes->State[2][c] = (unsigned char) ((int) gfmultby0d(temp[c])
^ (int) gfmultby09(temp[4 + c])
^ (int) gfmultby0e(temp[4 * 2 + c])
^ (int) gfmultby0b(temp[4 * 3 + c]));
aes->State[3][c] = (unsigned char) ((int) gfmultby0b(temp[c])
^ (int) gfmultby0d(temp[4 + c])
^ (int) gfmultby09(temp[4 * 2 + c])
^ (int) gfmultby0e(temp[4 * 3 + c]));
}
}  // InvMixColumns
_u8 AES::gfmultby01(_u8 b)
{
return b;
}
_u8 AES::gfmultby02(_u8 b)
{
if (b < 0x80)
return (_u8) (_int32) (b << 1);
else
return (_u8) ((_int32) (b << 1) ^ (_int32) (0x1b));
}
_u8 AES::gfmultby03(_u8 b)
{
return (_u8) ((_int32) gfmultby02(b) ^ (_int32) b);
}
unsigned char AES::gfmultby09(unsigned char b)
{
return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b)))
^ (int) b);
}
unsigned char AES::gfmultby0b(unsigned char b)
{
return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b)))
^ (int) gfmultby02(b) ^ (int) b);
}
unsigned char AES::gfmultby0d(unsigned char b)
{
return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b)))
^ (int) gfmultby02(gfmultby02(b)) ^ (int) (b));
}
unsigned char AES::gfmultby0e(unsigned char b)
{
return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b)))
^ (int) gfmultby02(gfmultby02(b)) ^ (int) gfmultby02(b));
}
void AES::KeyExpansion(ctx_aes* aes)
{
int row;
_u8 temp[4];
_u8 result[4]?? result2[4];
memset(aes->w?? 0?? 16 * 15);
for (row = 0; row < aes->Nk; row++)  //Nk=4??6??8
{
aes->w[4 * row + 0] = aes->key[4 * row];
aes->w[4 * row + 1] = aes->key[4 * row + 1];
aes->w[4 * row + 2] = aes->key[4 * row + 2];
aes->w[4 * row + 3] = aes->key[4 * row + 3];
}
for (row = aes->Nk; row < aes->Nb * (aes->Nr + 1); row++)
{
temp[0] = aes->w[4 * (row - 1) + 0];
temp[1] = aes->w[4 * (row - 1) + 1];
temp[2] = aes->w[4 * (row - 1) + 2];
temp[3] = aes->w[4 * (row - 1) + 3];
if (row % aes->Nk == 0)
{
RotWord(temp?? result);
SubWord(result?? result2);
memcpy(temp?? result2?? 4);  //
temp[0] = (unsigned char) ((int) temp[0]
^ (int) Rcon[4 * (row / aes->Nk) + 0]);
temp[1] = (unsigned char) ((int) temp[1]
^ (int) Rcon[4 * (row / aes->Nk) + 1]);
temp[2] = (unsigned char) ((int) temp[2]
^ (int) Rcon[4 * (row / aes->Nk) + 2]);
temp[3] = (unsigned char) ((int) temp[3]
^ (int) Rcon[4 * (row / aes->Nk) + 3]);
}
else if (aes->Nk > 6 && (row % aes->Nk == 4))
{
SubWord(temp?? result);
memcpy(temp?? result?? 4);
}
// w[row] = w[row-Nk] xor temp
aes->w[4 * row + 0] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk)
+ 0] ^ (int) temp[0]);
aes->w[4 * row + 1] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk)
+ 1] ^ (int) temp[1]);
aes->w[4 * row + 2] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk)
+ 2] ^ (int) temp[2]);
aes->w[4 * row + 3] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk)
+ 3] ^ (int) temp[3]);
}  // for loop
}  // KeyExpansion()
void AES::SubWord(_u8 *word?? _u8 *result)
{  //2?òa?a?ù·μ?????
result[0] = Sbox[16 * (word[0] >> 4) + (word[0] & 0x0f)];
result[1] = Sbox[16 * (word[1] >> 4) + (word[1] & 0x0f)];
result[2] = Sbox[16 * (word[2] >> 4) + (word[2] & 0x0f)];
result[3] = Sbox[16 * (word[3] >> 4) + (word[3] & 0x0f)];
}
void AES::RotWord(_u8 *word?? _u8 *result)
{  //2?òa?a?ù·μ??
result[0] = word[1];
result[1] = word[2];
result[2] = word[3];
result[3] = word[0];
}
_int32 AES::aes_encrypt_with_known_key(char* buffer?? _u32* len?? _u8 *key??
std::string &outData)
{
_int32 ret;
char *pOutBuff;
_int32 nOutLen;
_int32 nBeginOffset;
ctx_aes aes;
int nInOffset;
int nOutOffset;
unsigned char inBuff[ENCRYPT_BLOCK_SIZE]?? ouBuff[ENCRYPT_BLOCK_SIZE];
if (buffer == NULL)
{
return -1;
}
pOutBuff = (char*) malloc(*len + 16);
if (pOutBuff == NULL)
return -1;
nOutLen = 0;
nBeginOffset = 0;
aes_init(&aes?? 16?? key);
nInOffset = nBeginOffset;
nOutOffset = 0;
memset(inBuff?? 0?? ENCRYPT_BLOCK_SIZE);
memset(ouBuff?? 0?? ENCRYPT_BLOCK_SIZE);
while (TRUE)
{
if (*len - nInOffset >= ENCRYPT_BLOCK_SIZE)
{
memcpy(inBuff?? buffer + nInOffset?? ENCRYPT_BLOCK_SIZE);
aes_cipher(&aes?? inBuff?? ouBuff);
memcpy(pOutBuff + nOutOffset?? ouBuff?? ENCRYPT_BLOCK_SIZE);
nInOffset += ENCRYPT_BLOCK_SIZE;
nOutOffset += ENCRYPT_BLOCK_SIZE;
}
else
{
int nDataLen = *len - nInOffset;
int nFillData = ENCRYPT_BLOCK_SIZE - nDataLen;
memset(inBuff?? nFillData?? ENCRYPT_BLOCK_SIZE);
memset(ouBuff?? 0?? ENCRYPT_BLOCK_SIZE);
if (nDataLen > 0)
{
memcpy(inBuff?? buffer + nInOffset?? nDataLen);
aes_cipher(&aes?? inBuff?? ouBuff);
memcpy(pOutBuff + nOutOffset?? ouBuff?? ENCRYPT_BLOCK_SIZE);
nInOffset += nDataLen;
nOutOffset += ENCRYPT_BLOCK_SIZE;
}
else
{
aes_cipher(&aes?? inBuff?? ouBuff);
memcpy(pOutBuff + nOutOffset?? ouBuff?? ENCRYPT_BLOCK_SIZE);
nOutOffset += ENCRYPT_BLOCK_SIZE;
}
break;
}
}
nOutLen = nOutOffset;
outData = std::string(pOutBuff?? nOutLen);
free(pOutBuff);
if (nOutLen + nBeginOffset > *len + 16)
return -1;
*len = nOutLen + nBeginOffset;
return 0;
}
_int32 AES::aes_decrypt_with_known_key(char* pDataBuff?? _u32* nBuffLen??
_u8 *p_aeskey?? std::string &outData)
{
_int32 ret;
int nBeginOffset;
char *pOutBuff;
int nOutLen;
ctx_aes aes;
int nInOffset;
int nOutOffset;
unsigned char inBuff[ENCRYPT_BLOCK_SIZE]?? ouBuff[ENCRYPT_BLOCK_SIZE];
char * out_ptr;
if (pDataBuff == NULL)
{
return -1;
}
nBeginOffset = 0;
if ((*nBuffLen - nBeginOffset) % ENCRYPT_BLOCK_SIZE != 0)
{
return -2;
}
pOutBuff = (char*) malloc(*nBuffLen + 16);
if (pOutBuff == NULL)
return -1;
nOutLen = 0;
aes_init(&aes?? 16?? p_aeskey);
nInOffset = nBeginOffset;
nOutOffset = 0;
memset(inBuff?? 0?? ENCRYPT_BLOCK_SIZE);
memset(ouBuff?? 0?? ENCRYPT_BLOCK_SIZE);
while (*nBuffLen - nInOffset > 0)
{
memcpy(inBuff?? pDataBuff + nInOffset?? ENCRYPT_BLOCK_SIZE);
aes_invcipher(&aes?? inBuff?? ouBuff);
memcpy(pOutBuff + nOutOffset?? ouBuff?? ENCRYPT_BLOCK_SIZE);
nInOffset += ENCRYPT_BLOCK_SIZE;
nOutOffset += ENCRYPT_BLOCK_SIZE;
}
nOutLen = nOutOffset;
out_ptr = pOutBuff + nOutLen - 1;
if (*out_ptr <= 0 || *out_ptr > ENCRYPT_BLOCK_SIZE)
{
ret = -3;
}
else
{
if (nBeginOffset + nOutLen - *out_ptr < *nBuffLen)
{
*nBuffLen = nBeginOffset + nOutLen - *out_ptr;
ret = 0;
}
else
{
ret = -4;
}
}
outData = std::string(pOutBuff??*nBuffLen);
free(pOutBuff);
return ret;
}
int AES::encrypt4aes(const std::string &inData?? const std::string &strKey??
std::string &outData?? std::string &errMsg)
{
outData = "";
errMsg = "";
if (inData.empty() || strKey.empty())
{
errMsg = "indata or key is empty!!";
return -1;
}
unsigned int iKeyLen = strKey.length();
if (iKeyLen != AES_KEY_LENGTH_16 && iKeyLen != AES_KEY_LENGTH_24
&& iKeyLen != AES_KEY_LENGTH_32)
{
errMsg = "aes key invalid!!";
return -2;
}
char* aes_data = const_cast<char*>(inData.c_str());
unsigned int aes_data_len = (unsigned int) (inData.length());
unsigned char* md5_result_data =
(unsigned char*) (const_cast<char*>(strKey.c_str()));
outData = "";
int iResult = aes_encrypt_with_known_key(aes_data?? &aes_data_len??
md5_result_data?? outData);
if(iResult)
{
errMsg = "aes_encrypt_with_known_key failed!!";
iResult = -3;
}
return iResult;
}
int AES::decrypt4aes(const std::string &inData?? const std::string &strKey??
std::string &outData?? std::string &errMsg)
{
outData = "";
errMsg = "";
if (inData.empty() || strKey.empty())
{
errMsg = "indata or key is empty!!";
return -1;
}
unsigned int iKeyLen = strKey.length();
if (iKeyLen != AES_KEY_LENGTH_16 && iKeyLen != AES_KEY_LENGTH_24
&& iKeyLen != AES_KEY_LENGTH_32)
{
errMsg = "aes key invalid!!";
return -2;
}
int iResult = 0;
char* aes_data = const_cast<char*>(inData.c_str());
unsigned int aes_data_len = (unsigned int) (inData.length());
unsigned char* md5_result_data =
(unsigned char*) (const_cast<char*>(strKey.c_str()));
outData = "";
iResult = aes_decrypt_with_known_key(aes_data?? &aes_data_len??
md5_result_data?? outData);
if(iResult)
{
errMsg = "aes_encrypt_with_known_key failed!!";
iResult = -3;
}
return iResult;
}
int main(int argc?? char**argv)
{
std::string md5_data = "123456789";
std::string aes_data = "";
comm::util::MD5 md5;
std::string strResult = md5.md5(md5_data);
comm::util::AES aes;
std::string errMsg;
std::string outData;
aes.encrypt4aes(aes_data?? strResult?? outData?? errMsg);
std::string strInput;
aes.decrypt4aes(outData?? strResult?? strInput?? errMsg);
for (int i = 0; i < strInput.length(); i++)
{
printf("%c"?? strInput[i] & 255);
}
printf(" ");
return 0;
}