📄 aes.c
字号:
0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, 0x67b35a1d, 0xdb9252d2,
0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c,
0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73,
0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25,
0x3c288b49, 0x0dff4195, 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1,
0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257};
static const ULONG InvTable3[256] = {
0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d,
0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba,
0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174,
0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a,
0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b,
0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479,
0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60,
0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd,
0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b,
0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757,
0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, 0xf2adc78b,
0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623,
0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2,
0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138,
0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8,
0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859,
0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f,
0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef,
0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db,
0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2,
0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2,
0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8};
#endif /* AES_COMPACT */
int IsBigEndian;
#ifdef AES_VERBOSE
int ROUND;
#endif
/******************************************************************************/
/* AES Private Kernel Functions */
inline UCHAR xtime (unsigned int f);
static inline UCHAR xplus1time (unsigned int f);
inline UCHAR polymul (unsigned int f, unsigned int g);
inline void MixColumns (AESSTATE State, int Nb);
inline void InvMixColumns (AESSTATE State, int Nb);
static inline void ShiftRows (AESSTATE State, int Nb);
static inline void InvShiftRows (AESSTATE State, int Nb);
inline void SubBytes (AESSTATE State, int Nb);
inline void InvSubBytes (AESSTATE State, int Nb);
inline void AddRoundKey (AESSTATE State, AESROUNDKEY RoundKey, int Nb);
static inline void Round (AESSTATE State, AESROUNDKEY RoundKey, int Nb);
static inline void FinalRound (AESSTATE State, AESROUNDKEY RoundKey, int Nb);
static inline void InvRound (AESSTATE State, AESROUNDKEY RoundKey, int Nb);
static inline void InvFinalRound (AESSTATE State, AESROUNDKEY RoundKey, int Nb);
/* Functions for purging security critical data */
static inline void ZeroUchar (UCHAR *a);
static inline void Zero2Uchar (UCHAR *a, UCHAR *b);
static inline void Zero4Uchar (UCHAR *a, UCHAR *b, UCHAR *c, UCHAR *d);
static inline void ZeroUlong (ULONG *a);
static inline void Zero2Ulong (ULONG *a, ULONG *b);
static inline void Zero4Ulong (ULONG *a, ULONG *b, ULONG *c, ULONG *d);
static inline void ZeroUcharArray (UCHAR *a, int Len);
/* Test of Endianness */
static void TestEndian(int *IsBigEndian);
#ifdef AES_VERBOSE
static inline void PrintState (char * step, AESSTATE State, int Nb);
#endif /* AES_VERBOSE? */
/******************************************************************************/
/* */
/* Function: Key Schedule */
/* Syntax: int */
/* AESKeySched_l (AESKEYSCHED *CookedKey, AESKEY RawKey, */
/* int KeyLength, int BlkLength, int DFlag, int mode); */
/* Input: AESKEY RawKey (Key vector provided by user) */
/* int KeyLength (Length of user key in bit: 128, 192, 256) */
/* int BlkLength (Length of plaintext/cipherblocks in bit) */
/* int DFlag (Encipher/decipher mode AES_ENC, AES_DEC) */
/* int mode (Mode of operation AES_ECB, AES_CBC) */
/* Output: AESKEYSCHED *CookedKey (Keyschedule) */
/* Returns: E_AES_OK if everything is O.K. */
/* E_AES_DIRECTION if DFlag != AES_ENC or AES_DEC */
/* E_AES_MODE if mode != AES_ECB or AES_CBC */
/* E_AES_KEYLENGTH if KeyLength != 128, 192 or 256 */
/* */
/******************************************************************************/
int __FLINT_API
AESKeySched_l (AESKEYSCHED *CookedKey, AESKEY RawKey, int KeyLength,
int BlkLength, int DFlag, int mode)
{
if ((DFlag != AES_ENC) && (DFlag != AES_DEC))
{
#if defined AES_VERBOSE
fprintf (stderr, "AES_ERR_DIRECTION in line %d\n", __LINE__);
#endif
return AES_ERR_DIRECTION;
}
if ((KeyLength != 128) && (KeyLength != 192) && (KeyLength != 256))
{
#if defined AES_VERBOSE
fprintf (stderr, "AES_ERR_KEYLENGTH in line %d\n", __LINE__);
#endif
return AES_ERR_KEYLENGTH;
}
if ((BlkLength != 128) && (BlkLength != 192) && (BlkLength != 256))
{
#ifdef AES_VERBOSE
fprintf (stderr, "AES_ERR_BLKLENGTH in line %d\n", __LINE__);
#endif
return AES_ERR_BLKLENGTH;
}
switch (DFlag)
{
case AES_ENC:
AESKeyExpansion (CookedKey->ExpandedKey, RawKey, KeyLength, BlkLength);
break;
case AES_DEC:
AESInvKeyExpansion (CookedKey->ExpandedKey, RawKey, KeyLength, BlkLength);
break;
default:
return AES_ERR_MODE;
}
CookedKey->mode = mode;
CookedKey->KeyLength = KeyLength;
CookedKey->BlkLength = BlkLength;
CookedKey->DFlag = DFlag;
return AES_OK;
}
/******************************************************************************/
/* */
/* Function: Initialization of AES routines */
/* Syntax: int */
/* AESInit_l (AESWORKSPACE *ws, int mode, int BlkLength, */
/* AESBLOCK IV, AESKEYSCHED *CookedKey, AESKEY RawKey, */
/* int KeyLength, int DFlag); */
/* Input: int mode (Mode of operation AES_ECB, AES_CBC) */
/* int BlkLength (Length of plaintext/cipherblocks in bit) */
/* AESBLOCK IV (Initialization vector for CBC mode operation, */
/* IV may be NULL for ECB mode) */
/* AESKEY RawKey (Key vector provided by user) */
/* int KeyLength (Length of user key in bit: 128, 192, 256) */
/* int DFlag (Encipher/decipher mode AES_ENC, AES_DEC) */
/* Output: AESWORKSPACE *ws (Initialized buffer) */
/* AESKEYSCHED *CookedKey (Keyschedule) */
/* Returns: E_AES_OK if everything is O.K. */
/* E_AES_DIRECTION if DFlag != AES_ENC or AES_DEC */
/* E_AES_MODE if mode != AES_ECB or AES_CBC */
/* E_AES_KEYLENGTH if KeyLength != 128, 192 or 256 */
/* E_AES_BLKLENGTH if BlkLength != 128, 192 or 256 */
/* */
/******************************************************************************/
int __FLINT_API
AESInit_l (AESWORKSPACE *ws, int mode, int BlkLength, AESBLOCK IV,
AESKEYSCHED *CookedKey, AESKEY RawKey, int KeyLength, int DFlag)
{
int col, col4, Nb;
if ((mode != AES_CBC) && (mode != AES_ECB))
{
#ifdef AES_TEST
fprintf (stderr, "AES_ERR_MODE in line %d\n", __LINE__);
#endif
return AES_ERR_MODE;
}
if ((BlkLength != 128) && (BlkLength != 192) && (BlkLength != 256))
{
#ifdef AES_TEST
fprintf (stderr, "AES_ERR_BLKLENGTH in line %d\n", __LINE__);
#endif
return AES_ERR_BLKLENGTH;
}
if ((KeyLength != 128) && (KeyLength != 192) && (KeyLength != 256))
{
#ifdef AES_TEST
fprintf (stderr, "AES_ERR_KEYLENGTH in line %d\n", __LINE__);
#endif
return AES_ERR_KEYLENGTH;
}
if ((DFlag != AES_ENC) && (DFlag != AES_DEC))
{
#ifdef AES_TEST
fprintf (stderr, "AES_ERR_DIRECTION in line %d\n", __LINE__);
#endif
return AES_ERR_DIRECTION;
}
TestEndian (&IsBigEndian);
ws->mode = mode;
ws->BlkLength = BlkLength;
Nb = BlkLength/32;
AESKeySched (CookedKey, RawKey, KeyLength, BlkLength, DFlag, mode);
if (ws->mode == AES_CBC)
{
switch (CookedKey->DFlag)
{
case AES_ENC:
for (col = col4 = 0; col < Nb; col++, col4+=4)
{
ws->State[col] = UC2UL(&IV[col4]);
}
break;
case AES_DEC:
for (col = col4 = 0; col < Nb; col++, col4+=4)
{
ws->Block[col] = UC2UL(&IV[col4]);
}
break;
}
}
return AES_OK;
}
/******************************************************************************/
/* */
/* Function: AES encryption and decryption with support for ECB/CBC modes */
/* Processing of several portions of text by subsequent calls to */
/* AESCrypt_l is supported for ECB and CBC mode */
/* If not #defined AES_COMPACT fast table lookup is performed */
/* Syntax: int */
/* AESCrypt_l (AESBLOCK OutBlock, AESWORKSPACE *ws, */
/* AESKEYSCHED *ks, AESBLOCK InBlock, int InLength); */
/* Input: AESWORKSPACE *ws (Initialized buffer) */
/* AESKEYSCHED *ks (Initialized Keyschedule) */
/* AESBLOCK InBlock (Plaintext/Ciphertext) */
/* int InLength (Length of InBlock in bytes */
/* InLength = 0 mod BlkLength/8 given in AESInit_l */
/* Output: AESBLOCK OutBlock (Ciphertext/Plaintext) */
/* Returns: E_AES_OK if everything is O.K. */
/* E_AES_DIRECTION if DFlag differs in ws and ks */
/* E_AES_MODE if mode differs in ws and ks */
/* E_AES_KEYLENGTH if KeyLength given in ks != 128, 192 or 256 */
/* E_AES_BLKLENGTH if BlkLength differs in ws and ks */
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -