diff --git a/src/KKdLib/aes.cpp b/src/KKdLib/aes.cpp deleted file mode 100644 index 97b1e604..00000000 --- a/src/KKdLib/aes.cpp +++ /dev/null @@ -1,1346 +0,0 @@ -/* - Original: https://github.com/kokke/tiny-AES-c -*/ - -/* - -This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode. -Block size can be chosen in aes.h - available choices are AES128, AES192, AES256. - -The implementation is verified against the test vectors in: - National Institute of Standards and Technology Special Publication 800-38A 2001 ED - -ECB-AES128 ----------- - - plain-text: - 6bc1bee22e409f96e93d7e117393172a - ae2d8a571e03ac9c9eb76fac45af8e51 - 30c81c46a35ce411e5fbc1191a0a52ef - f69f2445df4f9b17ad2b417be66c3710 - - key: - 2b7e151628aed2a6abf7158809cf4f3c - - resulting cipher - 3ad77bb40d7a3660a89ecaf32466ef97 - f5d3d58503b9699de785895a96fdbaaf - 43b1cd7f598ece23881b00e3ed030688 - 7b0c785e27e8ad3f8223207104725dd4 - - -NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) - You should pad the end of the string with zeros if this is not the case. - For AES192/256 the key size is proportionally larger. - -*/ - -/*****************************************************************************/ -/* Includes: */ -/*****************************************************************************/ -#include "aes.hpp" - -/*****************************************************************************/ -/* Defines: */ -/*****************************************************************************/ -// The number of columns comprising a state in AES. This is a constant in AES. Value=4 -#define Nb 4 - -#define Nk128 4 // The number of 32 bit words in a key. -#define Nr128 10 // The number of rounds in AES Cipher. -#define Nk192 6 -#define Nr192 12 -#define Nk256 8 -#define Nr256 14 - -// jcallan@github points out that declaring Multiply as a function -// reduces code size considerably with the Keil ARM compiler. -// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3 -#ifndef MULTIPLY_AS_A_FUNCTION - #define MULTIPLY_AS_A_FUNCTION 0 -#endif - -/*****************************************************************************/ -/* Private variables: */ -/*****************************************************************************/ -// state - array holding the intermediate results during decryption. -typedef uint8_t state_t[4][4]; - -// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM -// The numbers below can be computed dynamically trading ROM for RAM - -// This can be useful in (embedded) bootloader applications, where ROM is often limited. -static const uint8_t sbox[256] = { - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -static const uint8_t rsbox[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -}; - -// The round constant word array, Rcon[i], contains the values given by -// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) -static const uint8_t Rcon[11] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 -}; - -/* - * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12), - * that you can remove most of the elements in the Rcon array, because they are unused. - * - * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon - * - * "Only the first some of these constants are actually used - up to rcon[10] for AES-128 (as 11 round keys are needed), - * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm." - */ - -extern bool cpu_caps_aes_ni; - -// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. -static void key_expansion_aes128(uint8_t* RoundKey, const uint8_t* Key) { - unsigned i, j, k; - uint8_t tempa[4]; // Used for the column/row operations - - // The first round key is the key itself. - for (i = 0; i < Nk128; ++i) { - RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; - RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; - RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; - RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; - } - - // All other round keys are found from the previous round keys. - for (i = Nk128; i < Nb * (Nr128 + 1); ++i) { - { - k = (i - 1) * 4; - tempa[0] = RoundKey[k + 0]; - tempa[1] = RoundKey[k + 1]; - tempa[2] = RoundKey[k + 2]; - tempa[3] = RoundKey[k + 3]; - } - - if (i % Nk128 == 0) { - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - - // Function RotWord() - { - const uint8_t u8tmp = tempa[0]; - tempa[0] = tempa[1]; - tempa[1] = tempa[2]; - tempa[2] = tempa[3]; - tempa[3] = u8tmp; - } - - // SubWord() is a function that takes a four-byte input word and - // applies the S-box to each of the four bytes to produce an output word. - - // Function Subword() - { - tempa[0] = sbox[tempa[0]]; - tempa[1] = sbox[tempa[1]]; - tempa[2] = sbox[tempa[2]]; - tempa[3] = sbox[tempa[3]]; - } - - tempa[0] = tempa[0] ^ Rcon[i / Nk128]; - } - j = i * 4; k = (i - Nk128) * 4; - RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; - RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; - RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; - RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; - } -} - -static void key_expansion_aes192(uint8_t* RoundKey, const uint8_t* Key) { - unsigned i, j, k; - uint8_t tempa[4]; // Used for the column/row operations - - // The first round key is the key itself. - for (i = 0; i < Nk192; ++i) { - RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; - RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; - RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; - RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; - } - - // All other round keys are found from the previous round keys. - for (i = Nk192; i < Nb * (Nr192 + 1); ++i) { - { - k = (i - 1) * 4; - tempa[0] = RoundKey[k + 0]; - tempa[1] = RoundKey[k + 1]; - tempa[2] = RoundKey[k + 2]; - tempa[3] = RoundKey[k + 3]; - } - - if (i % Nk192 == 0) { - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - - // Function RotWord() - { - const uint8_t u8tmp = tempa[0]; - tempa[0] = tempa[1]; - tempa[1] = tempa[2]; - tempa[2] = tempa[3]; - tempa[3] = u8tmp; - } - - // SubWord() is a function that takes a four-byte input word and - // applies the S-box to each of the four bytes to produce an output word. - - // Function Subword() - { - tempa[0] = sbox[tempa[0]]; - tempa[1] = sbox[tempa[1]]; - tempa[2] = sbox[tempa[2]]; - tempa[3] = sbox[tempa[3]]; - } - - tempa[0] = tempa[0] ^ Rcon[i / Nk192]; - } - j = i * 4; k = (i - Nk192) * 4; - RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; - RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; - RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; - RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; - } -} - -static void key_expansion_aes256(uint8_t* RoundKey, const uint8_t* Key) { - unsigned i, j, k; - uint8_t tempa[4]; // Used for the column/row operations - - // The first round key is the key itself. - for (i = 0; i < Nk256; ++i) { - RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; - RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; - RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; - RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; - } - - // All other round keys are found from the previous round keys. - for (i = Nk256; i < Nb * (Nr256 + 1); ++i) { - { - k = (i - 1) * 4; - tempa[0] = RoundKey[k + 0]; - tempa[1] = RoundKey[k + 1]; - tempa[2] = RoundKey[k + 2]; - tempa[3] = RoundKey[k + 3]; - } - - if (i % Nk256 == 0) { - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - - // Function RotWord() - { - const uint8_t u8tmp = tempa[0]; - tempa[0] = tempa[1]; - tempa[1] = tempa[2]; - tempa[2] = tempa[3]; - tempa[3] = u8tmp; - } - - // SubWord() is a function that takes a four-byte input word and - // applies the S-box to each of the four bytes to produce an output word. - - // Function Subword() - { - tempa[0] = sbox[tempa[0]]; - tempa[1] = sbox[tempa[1]]; - tempa[2] = sbox[tempa[2]]; - tempa[3] = sbox[tempa[3]]; - } - - tempa[0] = tempa[0] ^ Rcon[i / Nk256]; - } - if (i % Nk256 == 4) { - // Function Subword() - { - tempa[0] = sbox[tempa[0]]; - tempa[1] = sbox[tempa[1]]; - tempa[2] = sbox[tempa[2]]; - tempa[3] = sbox[tempa[3]]; - } - } - j = i * 4; k = (i - Nk256) * 4; - RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; - RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; - RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; - RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; - } -} - -inline static __m128i key_expansion_aes128_ni_assist(__m128i temp1, __m128i temp2) { - __m128i temp3; - temp2 = _mm_shuffle_epi32(temp2, 0xFF); - temp3 = _mm_slli_si128(temp1, 0x04); - temp1 = _mm_xor_si128(temp1, temp3); - temp3 = _mm_slli_si128(temp3, 0x04); - temp1 = _mm_xor_si128(temp1, temp3); - temp3 = _mm_slli_si128(temp3, 0x04); - temp1 = _mm_xor_si128(temp1, temp3); - temp1 = _mm_xor_si128(temp1, temp2); - return temp1; -} - -static void key_expansion_aes128_ni(__m128i* RoundKey, const uint8_t* Key) { - __m128i temp1, temp2; - temp1 = _mm_loadu_si128((__m128i*)&Key[0]); - RoundKey[0] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x01); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[1] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x02); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[2] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x04); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[3] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x08); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[4] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x10); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[5] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x20); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[6] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x40); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[7] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x80); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[8] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x1B); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[9] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x36); - temp1 = key_expansion_aes128_ni_assist(temp1, temp2); - RoundKey[10] = temp1; - RoundKey[11] = _mm_aesimc_si128(RoundKey[9]); - RoundKey[12] = _mm_aesimc_si128(RoundKey[8]); - RoundKey[13] = _mm_aesimc_si128(RoundKey[7]); - RoundKey[14] = _mm_aesimc_si128(RoundKey[6]); - RoundKey[15] = _mm_aesimc_si128(RoundKey[5]); - RoundKey[16] = _mm_aesimc_si128(RoundKey[4]); - RoundKey[17] = _mm_aesimc_si128(RoundKey[3]); - RoundKey[18] = _mm_aesimc_si128(RoundKey[2]); - RoundKey[19] = _mm_aesimc_si128(RoundKey[1]); -} - -inline static void key_expansion_aes192_ni_assist(__m128i* temp1, __m128i* temp2, __m128i* temp3) { - __m128i temp4; - *temp2 = _mm_shuffle_epi32(*temp2, 0x55); - temp4 = _mm_slli_si128(*temp1, 0x04); - *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x04); - *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x04); - *temp1 = _mm_xor_si128(*temp1, temp4); - *temp1 = _mm_xor_si128(*temp1, *temp2); - *temp2 = _mm_shuffle_epi32(*temp1, 0xFF); - temp4 = _mm_slli_si128(*temp3, 0x04); - *temp3 = _mm_xor_si128(*temp3, temp4); - *temp3 = _mm_xor_si128(*temp3, *temp2); -} - -static void key_expansion_aes192_ni(__m128i* RoundKey, const uint8_t* Key) { - __m128i temp1, temp2, temp3; - temp1 = _mm_loadu_si128((__m128i*)&Key[0]); - temp3 = _mm_loadu_si128((__m128i*)&Key[16]); - RoundKey[0] = temp1; - RoundKey[1] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x01); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - *(__m128d*)& RoundKey[1] = _mm_shuffle_pd(*(__m128d*)&RoundKey[1], *(__m128d*)&temp1, 0); - *(__m128d*)& RoundKey[2] = _mm_shuffle_pd(*(__m128d*)&temp1, *(__m128d*)&temp3, 1); - temp2 = _mm_aeskeygenassist_si128(temp3, 0x02); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - RoundKey[3] = temp1; - RoundKey[4] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x04); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - *(__m128d*)& RoundKey[4] = _mm_shuffle_pd(*(__m128d*)&RoundKey[4], *(__m128d*)&temp1, 0); - *(__m128d*)& RoundKey[5] = _mm_shuffle_pd(*(__m128d*)&temp1, *(__m128d*)&temp3, 1); - temp2 = _mm_aeskeygenassist_si128(temp3, 0x08); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - RoundKey[6] = temp1; - RoundKey[7] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x10); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - *(__m128d*)& RoundKey[7] = _mm_shuffle_pd(*(__m128d*)&RoundKey[7], *(__m128d*)&temp1, 0); - *(__m128d*)& RoundKey[8] = _mm_shuffle_pd(*(__m128d*)&temp1, *(__m128d*)&temp3, 1); - temp2 = _mm_aeskeygenassist_si128(temp3, 0x20); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - RoundKey[9] = temp1; - RoundKey[10] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x40); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - *(__m128d*)& RoundKey[10] = _mm_shuffle_pd(*(__m128d*)&RoundKey[10], *(__m128d*)&temp1, 0); - *(__m128d*)& RoundKey[11] = _mm_shuffle_pd(*(__m128d*)&temp1, *(__m128d*)&temp3, 1); - temp2 = _mm_aeskeygenassist_si128(temp3, 0x80); - key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); - RoundKey[12] = temp1; - RoundKey[13] = _mm_aesimc_si128(RoundKey[11]); - RoundKey[14] = _mm_aesimc_si128(RoundKey[10]); - RoundKey[15] = _mm_aesimc_si128(RoundKey[9]); - RoundKey[16] = _mm_aesimc_si128(RoundKey[8]); - RoundKey[17] = _mm_aesimc_si128(RoundKey[7]); - RoundKey[18] = _mm_aesimc_si128(RoundKey[6]); - RoundKey[19] = _mm_aesimc_si128(RoundKey[5]); - RoundKey[20] = _mm_aesimc_si128(RoundKey[4]); - RoundKey[21] = _mm_aesimc_si128(RoundKey[3]); - RoundKey[22] = _mm_aesimc_si128(RoundKey[2]); - RoundKey[23] = _mm_aesimc_si128(RoundKey[1]); -} - -inline static void key_expansion_aes256_ni_assist_1(__m128i* temp1, __m128i* temp2) { - __m128i temp4; - *temp2 = _mm_shuffle_epi32(*temp2, 0xFF); - temp4 = _mm_slli_si128(*temp1, 0x04); - *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x04); - *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x04); - *temp1 = _mm_xor_si128(*temp1, temp4); - *temp1 = _mm_xor_si128(*temp1, *temp2); -} - -inline static void key_expansion_aes256_ni_assist_2(__m128i* temp1, __m128i* temp3) { - __m128i temp2, temp4; - temp4 = _mm_aeskeygenassist_si128(*temp1, 0x00); - temp2 = _mm_shuffle_epi32(temp4, 0xAA); - temp4 = _mm_slli_si128(*temp3, 0x04); - *temp3 = _mm_xor_si128(*temp3, temp4); - temp4 = _mm_slli_si128(temp4, 0x04); - *temp3 = _mm_xor_si128(*temp3, temp4); - temp4 = _mm_slli_si128(temp4, 0x04); - *temp3 = _mm_xor_si128(*temp3, temp4); - *temp3 = _mm_xor_si128(*temp3, temp2); -} - -static void key_expansion_aes256_ni(__m128i* RoundKey, const uint8_t* Key) { - __m128i temp1, temp2, temp3; - temp1 = _mm_loadu_si128((__m128i*)&Key[0]); - temp3 = _mm_loadu_si128((__m128i*)&Key[16]); - RoundKey[0] = temp1; - RoundKey[1] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x01); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[2] = temp1; - key_expansion_aes256_ni_assist_2(&temp1, &temp3); - RoundKey[3] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x02); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[4] = temp1; - key_expansion_aes256_ni_assist_2(&temp1, &temp3); - RoundKey[5] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x04); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[6] = temp1; - key_expansion_aes256_ni_assist_2(&temp1, &temp3); - RoundKey[7] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x08); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[8] = temp1; - key_expansion_aes256_ni_assist_2(&temp1, &temp3); - RoundKey[9] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x10); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[10] = temp1; - key_expansion_aes256_ni_assist_2(&temp1, &temp3); - RoundKey[11] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x20); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[12] = temp1; - key_expansion_aes256_ni_assist_2(&temp1, &temp3); - RoundKey[13] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x40); - key_expansion_aes256_ni_assist_1(&temp1, &temp2); - RoundKey[14] = temp1; - RoundKey[15] = _mm_aesimc_si128(RoundKey[13]); - RoundKey[16] = _mm_aesimc_si128(RoundKey[12]); - RoundKey[17] = _mm_aesimc_si128(RoundKey[11]); - RoundKey[18] = _mm_aesimc_si128(RoundKey[10]); - RoundKey[19] = _mm_aesimc_si128(RoundKey[9]); - RoundKey[20] = _mm_aesimc_si128(RoundKey[8]); - RoundKey[21] = _mm_aesimc_si128(RoundKey[7]); - RoundKey[22] = _mm_aesimc_si128(RoundKey[6]); - RoundKey[23] = _mm_aesimc_si128(RoundKey[5]); - RoundKey[24] = _mm_aesimc_si128(RoundKey[4]); - RoundKey[25] = _mm_aesimc_si128(RoundKey[3]); - RoundKey[26] = _mm_aesimc_si128(RoundKey[2]); - RoundKey[27] = _mm_aesimc_si128(RoundKey[1]); -} - -void aes128_init_ctx(aes128_ctx* ctx, const uint8_t* key) { - if (cpu_caps_aes_ni) - key_expansion_aes128_ni(ctx->RoundKeyNI, key); - else - key_expansion_aes128(ctx->RoundKey, key); -} - -void aes192_init_ctx(aes192_ctx* ctx, const uint8_t* key) { - if (cpu_caps_aes_ni) - key_expansion_aes192_ni(ctx->RoundKeyNI, key); - else - key_expansion_aes192(ctx->RoundKey, key); -} - -void aes256_init_ctx(aes256_ctx* ctx, const uint8_t* key) { - if (cpu_caps_aes_ni) - key_expansion_aes256_ni(ctx->RoundKeyNI, key); - else - key_expansion_aes256(ctx->RoundKey, key); -} - -void aes128_init_ctx_iv(aes128_ctx* ctx, const uint8_t* key, const uint8_t* iv) { - if (cpu_caps_aes_ni) - key_expansion_aes128_ni(ctx->RoundKeyNI, key); - else - key_expansion_aes128(ctx->RoundKey, key); - memcpy(ctx->Iv, iv, AES_BLOCKLEN); -} - -void aes192_init_ctx_iv(aes192_ctx* ctx, const uint8_t* key, const uint8_t* iv) { - if (cpu_caps_aes_ni) - key_expansion_aes192_ni(ctx->RoundKeyNI, key); - else - key_expansion_aes192(ctx->RoundKey, key); - memcpy(ctx->Iv, iv, AES_BLOCKLEN); -} - -void aes256_init_ctx_iv(aes256_ctx* ctx, const uint8_t* key, const uint8_t* iv) { - if (cpu_caps_aes_ni) - key_expansion_aes256_ni(ctx->RoundKeyNI, key); - else - key_expansion_aes256(ctx->RoundKey, key); - memcpy(ctx->Iv, iv, AES_BLOCKLEN); -} - -void aes128_ctx_set_iv(aes128_ctx* ctx, const uint8_t* iv) { - memcpy(ctx->Iv, iv, AES_BLOCKLEN); -} - -void aes192_ctx_set_iv(aes192_ctx* ctx, const uint8_t* iv) { - memcpy(ctx->Iv, iv, AES_BLOCKLEN); -} - -void aes256_ctx_set_iv(aes256_ctx* ctx, const uint8_t* iv) { - memcpy(ctx->Iv, iv, AES_BLOCKLEN); -} - -// This function adds the round key to state. -// The round key is added to the state by an XOR function. -inline static void add_round_key(uint8_t round, state_t* state, const uint8_t* RoundKey) { - uint8_t i, j; - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j]; -} - -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -inline static void sub_bytes(state_t* state) { - uint8_t i, j; - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - (*state)[j][i] = sbox[(*state)[j][i]]; -} - -// The ShiftRows() function shifts the rows in the state to the left. -// Each row is shifted with different offset. -// Offset = Row number. So the first row is not shifted. -inline static void shift_rows(state_t* state) { - uint8_t temp; - - // Rotate first row 1 columns to left - temp = (*state)[0][1]; - (*state)[0][1] = (*state)[1][1]; - (*state)[1][1] = (*state)[2][1]; - (*state)[2][1] = (*state)[3][1]; - (*state)[3][1] = temp; - - // Rotate second row 2 columns to left - temp = (*state)[0][2]; - (*state)[0][2] = (*state)[2][2]; - (*state)[2][2] = temp; - - temp = (*state)[1][2]; - (*state)[1][2] = (*state)[3][2]; - (*state)[3][2] = temp; - - // Rotate third row 3 columns to left - temp = (*state)[0][3]; - (*state)[0][3] = (*state)[3][3]; - (*state)[3][3] = (*state)[2][3]; - (*state)[2][3] = (*state)[1][3]; - (*state)[1][3] = temp; -} - -inline static uint8_t xtime(uint8_t x) { - return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); -} - -// MixColumns function mixes the columns of the state matrix -inline static void mix_columns(state_t* state) { - uint8_t i; - uint8_t Tmp, Tm, t; - for (i = 0; i < 4; ++i) { - t = (*state)[i][0]; - Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; - Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; - Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; - Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; - Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; - } -} - -inline static uint8_t Multiply(uint8_t x, uint8_t y) { - return ((y & 1) * x) ^ - (((y >> 1) & 0x01) * xtime(x)) ^ - (((y >> 2) & 0x01) * xtime(xtime(x))) ^ - (((y >> 3) & 0x01) * xtime(xtime(xtime(x)))); -} - -// MixColumns function mixes the columns of the state matrix. -// The method used to multiply may be difficult to understand for the inexperienced. -// Please use the references to gain more information. -inline static void inv_mix_columns(state_t* state) { - int32_t i; - uint8_t a, b, c, d; - for (i = 0; i < 4; ++i) { - a = (*state)[i][0]; - b = (*state)[i][1]; - c = (*state)[i][2]; - d = (*state)[i][3]; - - (*state)[i][0] = Multiply(a, 0x0E) ^ Multiply(b, 0x0B) ^ Multiply(c, 0x0D) ^ Multiply(d, 0x09); - (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0E) ^ Multiply(c, 0x0B) ^ Multiply(d, 0x0D); - (*state)[i][2] = Multiply(a, 0x0D) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0E) ^ Multiply(d, 0x0B); - (*state)[i][3] = Multiply(a, 0x0B) ^ Multiply(b, 0x0D) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0E); - } -} - -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -inline static void inv_sub_bytes(state_t* state) { - uint8_t i, j; - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - (*state)[j][i] = rsbox[(*state)[j][i]]; -} - -inline static void inv_shift_rows(state_t* state) { - uint8_t temp; - - // Rotate first row 1 columns to right - temp = (*state)[3][1]; - (*state)[3][1] = (*state)[2][1]; - (*state)[2][1] = (*state)[1][1]; - (*state)[1][1] = (*state)[0][1]; - (*state)[0][1] = temp; - - // Rotate second row 2 columns to right - temp = (*state)[0][2]; - (*state)[0][2] = (*state)[2][2]; - (*state)[2][2] = temp; - - temp = (*state)[1][2]; - (*state)[1][2] = (*state)[3][2]; - (*state)[3][2] = temp; - - // Rotate third row 3 columns to right - temp = (*state)[0][3]; - (*state)[0][3] = (*state)[1][3]; - (*state)[1][3] = (*state)[2][3]; - (*state)[2][3] = (*state)[3][3]; - (*state)[3][3] = temp; -} - -// Cipher is the main function that encrypts the PlainText. -inline static void cipher_aes128(state_t* state, const uint8_t* RoundKey) { - uint8_t round = 0; - - // Add the First round key to the state before starting the rounds. - add_round_key(0, state, RoundKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr rounds are executed in the loop below. - // Last one without MixColumns() - for (round = 1; ; ++round) { - sub_bytes(state); - shift_rows(state); - if (round == Nr128) - break; - - mix_columns(state); - add_round_key(round, state, RoundKey); - } - // Add round key to last round - add_round_key(Nr128, state, RoundKey); -} - -inline static void cipher_aes192(state_t* state, const uint8_t* RoundKey) { - uint8_t round = 0; - - // Add the First round key to the state before starting the rounds. - add_round_key(0, state, RoundKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr rounds are executed in the loop below. - // Last one without MixColumns() - for (round = 1; ; ++round) { - sub_bytes(state); - shift_rows(state); - if (round == Nr192) - break; - - mix_columns(state); - add_round_key(round, state, RoundKey); - } - // Add round key to last round - add_round_key(Nr192, state, RoundKey); -} - -inline static void cipher_aes256(state_t* state, const uint8_t* RoundKey) { - uint8_t round = 0; - - // Add the First round key to the state before starting the rounds. - add_round_key(0, state, RoundKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr rounds are executed in the loop below. - // Last one without MixColumns() - for (round = 1; ; ++round) { - sub_bytes(state); - shift_rows(state); - if (round == Nr256) - break; - - mix_columns(state); - add_round_key(round, state, RoundKey); - } - // Add round key to last round - add_round_key(Nr256, state, RoundKey); -} - -inline static void cipher_aes128_ni(void* state, const __m128i* round_key) { - __m128i m = _mm_loadu_si128((__m128i*)state); - m = _mm_xor_si128(m, round_key[0]); - m = _mm_aesenc_si128(m, round_key[1]); - m = _mm_aesenc_si128(m, round_key[2]); - m = _mm_aesenc_si128(m, round_key[3]); - m = _mm_aesenc_si128(m, round_key[4]); - m = _mm_aesenc_si128(m, round_key[5]); - m = _mm_aesenc_si128(m, round_key[6]); - m = _mm_aesenc_si128(m, round_key[7]); - m = _mm_aesenc_si128(m, round_key[8]); - m = _mm_aesenc_si128(m, round_key[9]); - m = _mm_aesenclast_si128(m, round_key[10]); - _mm_storeu_si128((__m128i*)state, m); -} - -inline static void cipher_aes192_ni(void* state, const __m128i* round_key) { - __m128i m = _mm_loadu_si128((__m128i*)state); - m = _mm_xor_si128(m, round_key[0]); - m = _mm_aesenc_si128(m, round_key[1]); - m = _mm_aesenc_si128(m, round_key[2]); - m = _mm_aesenc_si128(m, round_key[3]); - m = _mm_aesenc_si128(m, round_key[4]); - m = _mm_aesenc_si128(m, round_key[5]); - m = _mm_aesenc_si128(m, round_key[6]); - m = _mm_aesenc_si128(m, round_key[7]); - m = _mm_aesenc_si128(m, round_key[8]); - m = _mm_aesenc_si128(m, round_key[9]); - m = _mm_aesenc_si128(m, round_key[10]); - m = _mm_aesenc_si128(m, round_key[11]); - m = _mm_aesenclast_si128(m, round_key[12]); - _mm_storeu_si128((__m128i*)state, m); -} - -inline static void cipher_aes256_ni(void* state, const __m128i* round_key) { - __m128i m = _mm_loadu_si128((__m128i*)state); - m = _mm_xor_si128(m, round_key[0]); - m = _mm_aesenc_si128(m, round_key[1]); - m = _mm_aesenc_si128(m, round_key[2]); - m = _mm_aesenc_si128(m, round_key[3]); - m = _mm_aesenc_si128(m, round_key[4]); - m = _mm_aesenc_si128(m, round_key[5]); - m = _mm_aesenc_si128(m, round_key[6]); - m = _mm_aesenc_si128(m, round_key[7]); - m = _mm_aesenc_si128(m, round_key[8]); - m = _mm_aesenc_si128(m, round_key[9]); - m = _mm_aesenc_si128(m, round_key[10]); - m = _mm_aesenc_si128(m, round_key[11]); - m = _mm_aesenc_si128(m, round_key[12]); - m = _mm_aesenc_si128(m, round_key[13]); - m = _mm_aesenclast_si128(m, round_key[14]); - _mm_storeu_si128((__m128i*)state, m); -} - -inline static void inv_cipher_aes128(state_t* state, const uint8_t* RoundKey) { - uint8_t round = 0; - - // Add the First round key to the state before starting the rounds. - add_round_key(Nr128, state, RoundKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr rounds are executed in the loop below. - // Last one without InvMixColumn() - for (round = (Nr128 - 1); ; --round) { - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(round, state, RoundKey); - if (round == 0) - break; - - inv_mix_columns(state); - } - -} - -inline static void inv_cipher_aes192(state_t* state, const uint8_t* RoundKey) { - uint8_t round = 0; - - // Add the First round key to the state before starting the rounds. - add_round_key(Nr192, state, RoundKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr rounds are executed in the loop below. - // Last one without InvMixColumn() - for (round = (Nr192 - 1); ; --round) { - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(round, state, RoundKey); - if (round == 0) - break; - - inv_mix_columns(state); - } - -} - -inline static void inv_cipher_aes256(state_t* state, const uint8_t* RoundKey) { - uint8_t round = 0; - - // Add the First round key to the state before starting the rounds. - add_round_key(Nr256, state, RoundKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr rounds are executed in the loop below. - // Last one without InvMixColumn() - for (round = (Nr256 - 1); ; --round) { - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(round, state, RoundKey); - if (round == 0) - break; - - inv_mix_columns(state); - } - -} - -inline static void inv_cipher_aes128_ni(void* state, const __m128i* round_key) { - __m128i m = _mm_loadu_si128((__m128i*)state); - m = _mm_xor_si128(m, round_key[10]); - m = _mm_aesdec_si128(m, round_key[11]); - m = _mm_aesdec_si128(m, round_key[12]); - m = _mm_aesdec_si128(m, round_key[13]); - m = _mm_aesdec_si128(m, round_key[14]); - m = _mm_aesdec_si128(m, round_key[15]); - m = _mm_aesdec_si128(m, round_key[16]); - m = _mm_aesdec_si128(m, round_key[17]); - m = _mm_aesdec_si128(m, round_key[18]); - m = _mm_aesdec_si128(m, round_key[19]); - m = _mm_aesdeclast_si128(m, round_key[0]); - _mm_storeu_si128((__m128i*)state, m); -} - -inline static void inv_cipher_aes192_ni(void* state, const __m128i* round_key) { - __m128i m = _mm_loadu_si128((__m128i*)state); - m = _mm_xor_si128(m, round_key[12]); - m = _mm_aesdec_si128(m, round_key[13]); - m = _mm_aesdec_si128(m, round_key[14]); - m = _mm_aesdec_si128(m, round_key[15]); - m = _mm_aesdec_si128(m, round_key[16]); - m = _mm_aesdec_si128(m, round_key[17]); - m = _mm_aesdec_si128(m, round_key[18]); - m = _mm_aesdec_si128(m, round_key[19]); - m = _mm_aesdec_si128(m, round_key[20]); - m = _mm_aesdec_si128(m, round_key[21]); - m = _mm_aesdec_si128(m, round_key[22]); - m = _mm_aesdec_si128(m, round_key[23]); - m = _mm_aesdeclast_si128(m, round_key[0]); - _mm_storeu_si128((__m128i*)state, m); -} - -inline static void inv_cipher_aes256_ni(void* state, const __m128i* round_key) { - __m128i m = _mm_loadu_si128((__m128i*)state); - m = _mm_xor_si128(m, round_key[14]); - m = _mm_aesdec_si128(m, round_key[15]); - m = _mm_aesdec_si128(m, round_key[16]); - m = _mm_aesdec_si128(m, round_key[17]); - m = _mm_aesdec_si128(m, round_key[18]); - m = _mm_aesdec_si128(m, round_key[19]); - m = _mm_aesdec_si128(m, round_key[20]); - m = _mm_aesdec_si128(m, round_key[21]); - m = _mm_aesdec_si128(m, round_key[22]); - m = _mm_aesdec_si128(m, round_key[23]); - m = _mm_aesdec_si128(m, round_key[24]); - m = _mm_aesdec_si128(m, round_key[25]); - m = _mm_aesdec_si128(m, round_key[26]); - m = _mm_aesdec_si128(m, round_key[27]); - m = _mm_aesdeclast_si128(m, round_key[0]); - _mm_storeu_si128((__m128i*)state, m); -} - -/*****************************************************************************/ -/* Public functions: */ -/*****************************************************************************/ -void aes128_ecb_encrypt(aes128_ctx* ctx, uint8_t* buf) { - // The next function call encrypts the PlainText with the Key using AES algorithm. - if (cpu_caps_aes_ni) - cipher_aes128_ni(buf, ctx->RoundKeyNI); - else - cipher_aes128((state_t*)buf, ctx->RoundKey); -} - -void aes192_ecb_encrypt(aes192_ctx* ctx, uint8_t* buf) { - // The next function call encrypts the PlainText with the Key using AES algorithm. - if (cpu_caps_aes_ni) - cipher_aes192_ni(buf, ctx->RoundKeyNI); - else - cipher_aes192((state_t*)buf, ctx->RoundKey); -} - -void aes256_ecb_encrypt(aes256_ctx* ctx, uint8_t* buf) { - // The next function call encrypts the PlainText with the Key using AES algorithm. - if (cpu_caps_aes_ni) - cipher_aes256_ni(buf, ctx->RoundKeyNI); - else - cipher_aes256((state_t*)buf, ctx->RoundKey); -} - -void aes128_ecb_decrypt(aes128_ctx* ctx, uint8_t* buf) { - // The next function call decrypts the PlainText with the Key using AES algorithm. - if (cpu_caps_aes_ni) - inv_cipher_aes128_ni(buf, ctx->RoundKeyNI); - else - inv_cipher_aes128((state_t*)buf, ctx->RoundKey); -} - -void aes192_ecb_decrypt(aes192_ctx* ctx, uint8_t* buf) { - // The next function call decrypts the PlainText with the Key using AES algorithm. - if (cpu_caps_aes_ni) - inv_cipher_aes192_ni(buf, ctx->RoundKeyNI); - else - inv_cipher_aes192((state_t*)buf, ctx->RoundKey); -} - -void aes256_ecb_decrypt(aes256_ctx* ctx, uint8_t* buf) { - // The next function call decrypts the PlainText with the Key using AES algorithm. - if (cpu_caps_aes_ni) - inv_cipher_aes256_ni(buf, ctx->RoundKeyNI); - else - inv_cipher_aes256((state_t*)buf, ctx->RoundKey); -} - -void aes128_ecb_encrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length) { - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - cipher_aes128_ni(buf, ctx->RoundKeyNI); - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - cipher_aes128((state_t*)buf, ctx->RoundKey); -} - -void aes192_ecb_encrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length) { - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - cipher_aes192_ni(buf, ctx->RoundKeyNI); - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - cipher_aes192((state_t*)buf, ctx->RoundKey); -} - -void aes256_ecb_encrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length) { - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - cipher_aes256_ni(buf, ctx->RoundKeyNI); - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - cipher_aes256((state_t*)buf, ctx->RoundKey); -} - -void aes128_ecb_decrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length) { - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - inv_cipher_aes128_ni(buf, ctx->RoundKeyNI); - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - inv_cipher_aes128((state_t*)buf, ctx->RoundKey); -} - -void aes192_ecb_decrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length) { - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - inv_cipher_aes192_ni(buf, ctx->RoundKeyNI); - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - inv_cipher_aes192((state_t*)buf, ctx->RoundKey); -} - -void aes256_ecb_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length) { - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - inv_cipher_aes256_ni(buf, ctx->RoundKeyNI); - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) - inv_cipher_aes256((state_t*)buf, ctx->RoundKey); -} - -inline static void XorWithIv(uint8_t* buf, const uint8_t* Iv) { - _mm_storeu_si128((__m128i*)buf, - _mm_xor_si128( - _mm_loadu_si128((const __m128i*)buf), - _mm_loadu_si128((const __m128i*)Iv) - ) - ); -} - -void aes128_cbc_encrypt(aes128_ctx* ctx, uint8_t buf[AES_BLOCKLEN]) { - uint8_t* Iv = ctx->Iv; - if (cpu_caps_aes_ni) { - XorWithIv(buf, Iv); - cipher_aes128_ni(buf, ctx->RoundKeyNI); - Iv = buf; - } - else { - XorWithIv(buf, Iv); - cipher_aes128((state_t*)buf, ctx->RoundKey); - Iv = buf; - } - /* store Iv in ctx for next call */ - memcpy(ctx->Iv, Iv, AES_BLOCKLEN); -} - -void aes192_cbc_encrypt(aes192_ctx* ctx, uint8_t buf[AES_BLOCKLEN]) { - uint8_t* Iv = ctx->Iv; - if (cpu_caps_aes_ni) { - XorWithIv(buf, Iv); - cipher_aes192_ni(buf, ctx->RoundKeyNI); - Iv = buf; - } - else { - XorWithIv(buf, Iv); - cipher_aes192((state_t*)buf, ctx->RoundKey); - Iv = buf; - } - /* store Iv in ctx for next call */ - memcpy(ctx->Iv, Iv, AES_BLOCKLEN); -} - -void aes256_cbc_encrypt(aes256_ctx* ctx, uint8_t buf[AES_BLOCKLEN]) { - uint8_t* Iv = ctx->Iv; - if (cpu_caps_aes_ni) { - XorWithIv(buf, Iv); - cipher_aes256_ni(buf, ctx->RoundKeyNI); - Iv = buf; - } - else { - XorWithIv(buf, Iv); - cipher_aes256((state_t*)buf, ctx->RoundKey); - Iv = buf; - } - /* store Iv in ctx for next call */ - memcpy(ctx->Iv, Iv, AES_BLOCKLEN); -} - -void aes128_cbc_decrypt(aes128_ctx* ctx, uint8_t buf[AES_BLOCKLEN]) { - uint8_t storeNextIv[AES_BLOCKLEN]; - if (cpu_caps_aes_ni) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes128_ni(buf, ctx->RoundKeyNI); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } - else { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes128((state_t*)buf, ctx->RoundKey); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } -} - -void aes192_cbc_decrypt(aes192_ctx* ctx, uint8_t buf[AES_BLOCKLEN]) { - uint8_t storeNextIv[AES_BLOCKLEN]; - if (cpu_caps_aes_ni) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes192_ni(buf, ctx->RoundKeyNI); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } - else { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes192((state_t*)buf, ctx->RoundKey); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } -} - -void aes256_cbc_decrypt(aes256_ctx* ctx, uint8_t buf[AES_BLOCKLEN]) { - uint8_t storeNextIv[AES_BLOCKLEN]; - if (cpu_caps_aes_ni) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes256_ni(buf, ctx->RoundKeyNI); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } - else { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes256((state_t*)buf, ctx->RoundKey); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } -} - -void aes128_cbc_encrypt_buffer(aes128_ctx *ctx, uint8_t* buf, size_t length) { - uint8_t* Iv = ctx->Iv; - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - XorWithIv(buf, Iv); - cipher_aes128_ni(buf, ctx->RoundKeyNI); - Iv = buf; - } - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - XorWithIv(buf, Iv); - cipher_aes128((state_t*)buf, ctx->RoundKey); - Iv = buf; - } - /* store Iv in ctx for next call */ - memcpy(ctx->Iv, Iv, AES_BLOCKLEN); -} - -void aes192_cbc_encrypt_buffer(aes192_ctx *ctx, uint8_t* buf, size_t length) { - uint8_t* Iv = ctx->Iv; - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - XorWithIv(buf, Iv); - cipher_aes192_ni(buf, ctx->RoundKeyNI); - Iv = buf; - } - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - XorWithIv(buf, Iv); - cipher_aes192((state_t*)buf, ctx->RoundKey); - Iv = buf; - } - /* store Iv in ctx for next call */ - memcpy(ctx->Iv, Iv, AES_BLOCKLEN); -} - -void aes256_cbc_encrypt_buffer(aes256_ctx *ctx, uint8_t* buf, size_t length) { - uint8_t* Iv = ctx->Iv; - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - XorWithIv(buf, Iv); - cipher_aes256_ni(buf, ctx->RoundKeyNI); - Iv = buf; - } - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - XorWithIv(buf, Iv); - cipher_aes256((state_t*)buf, ctx->RoundKey); - Iv = buf; - } - /* store Iv in ctx for next call */ - memcpy(ctx->Iv, Iv, AES_BLOCKLEN); -} - -void aes128_cbc_decrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length) { - uint8_t storeNextIv[AES_BLOCKLEN]; - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes128_ni(buf, ctx->RoundKeyNI); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes128((state_t*)buf, ctx->RoundKey); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } -} - -void aes192_cbc_decrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length) { - uint8_t storeNextIv[AES_BLOCKLEN]; - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes192_ni(buf, ctx->RoundKeyNI); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes192((state_t*)buf, ctx->RoundKey); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } -} - -void aes256_cbc_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length) { - uint8_t storeNextIv[AES_BLOCKLEN]; - if (cpu_caps_aes_ni) - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes256_ni(buf, ctx->RoundKeyNI); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } - else - for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) { - memcpy(storeNextIv, buf, AES_BLOCKLEN); - inv_cipher_aes256((state_t*)buf, ctx->RoundKey); - XorWithIv(buf, ctx->Iv); - memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); - } -} - -/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */ -void aes128_ctr_xcrypt_buffer(aes128_ctx* ctx, uint8_t* buf, uint32_t length) { - uint8_t buffer[AES_BLOCKLEN]; - - int32_t bi; - size_t i; - for (i = 0, bi = AES_BLOCKLEN; i < length; i++, bi++) { - if (bi == AES_BLOCKLEN) { /* we need to regen xor compliment in buffer */ - memcpy(buffer, ctx->Iv, AES_BLOCKLEN); - if (cpu_caps_aes_ni) - cipher_aes128_ni(buffer, ctx->RoundKeyNI); - else - cipher_aes128((state_t*)buffer, ctx->RoundKey); - - /* Increment Iv and handle overflow */ - for (bi = (AES_BLOCKLEN - 1); bi >= 0; bi--) { - /* inc will overflow */ - if (ctx->Iv[bi] == 255) { - ctx->Iv[bi] = 0; - continue; - } - ctx->Iv[bi]++; - break; - } - bi = 0; - } - - buf[i] ^= buffer[bi]; - } -} - -void aes192_ctr_xcrypt_buffer(aes192_ctx* ctx, uint8_t* buf, uint32_t length) { - uint8_t buffer[AES_BLOCKLEN]; - - int32_t bi; - size_t i; - for (i = 0, bi = AES_BLOCKLEN; i < length; i++, bi++) { - if (bi == AES_BLOCKLEN) { /* we need to regen xor compliment in buffer */ - memcpy(buffer, ctx->Iv, AES_BLOCKLEN); - if (cpu_caps_aes_ni) - cipher_aes192_ni(buffer, ctx->RoundKeyNI); - else - cipher_aes192((state_t*)buffer, ctx->RoundKey); - - /* Increment Iv and handle overflow */ - for (bi = (AES_BLOCKLEN - 1); bi >= 0; bi--) { - /* inc will overflow */ - if (ctx->Iv[bi] == 255) { - ctx->Iv[bi] = 0; - continue; - } - ctx->Iv[bi]++; - break; - } - bi = 0; - } - - buf[i] ^= buffer[bi]; - } -} - -void aes256_ctr_xcrypt_buffer(aes256_ctx* ctx, uint8_t* buf, uint32_t length) { - uint8_t buffer[AES_BLOCKLEN]; - - int32_t bi; - size_t i; - for (i = 0, bi = AES_BLOCKLEN; i < length; i++, bi++) { - if (bi == AES_BLOCKLEN) { /* we need to regen xor compliment in buffer */ - memcpy(buffer, ctx->Iv, AES_BLOCKLEN); - if (cpu_caps_aes_ni) - cipher_aes256_ni(buffer, ctx->RoundKeyNI); - else - cipher_aes256((state_t*)buffer, ctx->RoundKey); - - /* Increment Iv and handle overflow */ - for (bi = (AES_BLOCKLEN - 1); bi >= 0; bi--) { - /* inc will overflow */ - if (ctx->Iv[bi] == 255) { - ctx->Iv[bi] = 0; - continue; - } - ctx->Iv[bi]++; - break; - } - bi = 0; - } - - buf[i] ^= buffer[bi]; - } -} diff --git a/src/KKdLib/aes.hpp b/src/KKdLib/aes.hpp deleted file mode 100644 index 73fbefc9..00000000 --- a/src/KKdLib/aes.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - Original: https://github.com/kokke/tiny-AES-c -*/ - -#ifndef _AES_H_ -#define _AES_H_ - -#include "default.hpp" -#include - -//#define AES128 1 -//#define AES192 1 -//#define AES256 1 - -#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only - -#define AES128_KEYLEN 16 // Key length in bytes -#define AES128_keyExpSize 176 -#define AES192_KEYLEN 24 -#define AES192_keyExpSize 208 -#define AES256_KEYLEN 32 -#define AES256_keyExpSize 240 - -struct aes128_ctx { - union { - uint8_t RoundKey[AES128_keyExpSize]; - __m128i RoundKeyNI[AES128_keyExpSize / sizeof(__m128i) + 9]; - }; - uint8_t Iv[AES_BLOCKLEN]; -}; - -struct aes192_ctx { - union { - uint8_t RoundKey[AES192_keyExpSize]; - __m128i RoundKeyNI[AES192_keyExpSize / sizeof(__m128i) + 11]; - }; - uint8_t Iv[AES_BLOCKLEN]; -}; - -struct aes256_ctx { - union { - uint8_t RoundKey[AES256_keyExpSize]; - __m128i RoundKeyNI[AES256_keyExpSize / sizeof(__m128i) + 13]; - }; - uint8_t Iv[AES_BLOCKLEN]; -}; - -void aes128_init_ctx(aes128_ctx* ctx, const uint8_t* key); -void aes192_init_ctx(aes192_ctx* ctx, const uint8_t* key); -void aes256_init_ctx(aes256_ctx* ctx, const uint8_t* key); -void aes128_init_ctx_iv(aes128_ctx* ctx, const uint8_t* key, const uint8_t* iv); -void aes192_init_ctx_iv(aes192_ctx* ctx, const uint8_t* key, const uint8_t* iv); -void aes256_init_ctx_iv(aes256_ctx* ctx, const uint8_t* key, const uint8_t* iv); -void aes128_ctx_set_iv(aes128_ctx* ctx, const uint8_t* iv); -void aes192_ctx_set_iv(aes192_ctx* ctx, const uint8_t* iv); -void aes256_ctx_set_iv(aes256_ctx* ctx, const uint8_t* iv); - -// buffer size is exactly AES_BLOCKLEN bytes; -// you need only AES_init_ctx as IV is not used in ECB -void aes128_ecb_encrypt(aes128_ctx* ctx, uint8_t* buf); -void aes192_ecb_encrypt(aes192_ctx* ctx, uint8_t* buf); -void aes256_ecb_encrypt(aes256_ctx* ctx, uint8_t* buf); -void aes128_ecb_decrypt(aes128_ctx* ctx, uint8_t* buf); -void aes192_ecb_decrypt(aes192_ctx* ctx, uint8_t* buf); -void aes256_ecb_decrypt(aes256_ctx* ctx, uint8_t* buf); -void aes128_ecb_encrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length); -void aes192_ecb_encrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length); -void aes256_ecb_encrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length); -void aes128_ecb_decrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length); -void aes192_ecb_decrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length); -void aes256_ecb_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length); - -void aes128_cbc_encrypt(aes128_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); -void aes192_cbc_encrypt(aes192_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); -void aes256_cbc_encrypt(aes256_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); -void aes128_cbc_decrypt(aes128_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); -void aes192_cbc_decrypt(aes192_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); -void aes256_cbc_decrypt(aes256_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); -void aes128_cbc_encrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length); -void aes192_cbc_encrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length); -void aes256_cbc_encrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length); -void aes128_cbc_decrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length); -void aes192_cbc_decrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length); -void aes256_cbc_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length); - -void aes128_ctr_xcrypt_buffer(aes128_ctx* ctx, uint8_t* buf, uint32_t length); -void aes192_ctr_xcrypt_buffer(aes192_ctx* ctx, uint8_t* buf, uint32_t length); -void aes256_ctr_xcrypt_buffer(aes256_ctx* ctx, uint8_t* buf, uint32_t length); - -#endif // _AES_H_ diff --git a/src/KKdLib/divafile.cpp b/src/KKdLib/divafile.cpp index 71dcf24e..680b6a0f 100644 --- a/src/KKdLib/divafile.cpp +++ b/src/KKdLib/divafile.cpp @@ -5,7 +5,7 @@ #include "divafile.hpp" #include "io/file_stream.hpp" -#include "aes.hpp" +#include "prj/rijndael.hpp" #include "str_utils.hpp" namespace divafile { @@ -35,9 +35,9 @@ namespace divafile { void* data = force_malloc(stream_length); s_enc.read(data, stream_length); - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)data, stream_length); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + for (size_t i = 0; i < stream_length; i += prj::Rijndael_Nlen) + rijndael.decrypt16((uint8_t*)data + i); file_stream s_dec; s_dec.open(file_temp, L"wb"); @@ -66,9 +66,9 @@ namespace divafile { void* data = force_malloc(stream_length); memcpy(data, (void*)(d + 16), stream_length); - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)data, stream_length); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + for (size_t i = 0; i < stream_length; i += prj::Rijndael_Nlen) + rijndael.decrypt16((uint8_t*)data + i); *dec_data = data; *dec_size = file_length; @@ -93,9 +93,9 @@ namespace divafile { void* data = force_malloc(stream_length); enc.read(data, stream_length); - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)data, stream_length); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + for (size_t i = 0; i < stream_length; i += prj::Rijndael_Nlen) + rijndael.decrypt16((uint8_t*)data + i); dec.open(data, file_length); free_def(data); @@ -121,9 +121,9 @@ namespace divafile { void* data = force_malloc(len_align); s_dec.read(data, len); - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_encrypt_buffer(&ctx, (uint8_t*)data, len_align); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + for (size_t i = 0; i < len_align; i += prj::Rijndael_Nlen) + rijndael.encrypt16((uint8_t*)data + i); file_stream s_enc; s_enc.open(file_temp, L"wb"); @@ -147,9 +147,9 @@ namespace divafile { size_t d = (size_t)data; memcpy((void*)(d + 16), dec_data, len); - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_encrypt_buffer(&ctx, (uint8_t*)(d + 16), len_align); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + for (size_t i = 0; i < len_align; i += prj::Rijndael_Nlen) + rijndael.encrypt16((uint8_t*)data + i); *(uint64_t*)d = 0x454C494641564944; *(uint32_t*)(d + 8) = (uint32_t)len_align; diff --git a/src/KKdLib/farc.cpp b/src/KKdLib/farc.cpp index a4ad4444..f47cd441 100644 --- a/src/KKdLib/farc.cpp +++ b/src/KKdLib/farc.cpp @@ -7,7 +7,6 @@ #include "io/path.hpp" #include "io/file_stream.hpp" #include "io/memory_stream.hpp" -#include "aes.hpp" #include "deflate.hpp" #include "hash.hpp" #include "str_utils.hpp" @@ -506,9 +505,9 @@ static void farc_pack_files(farc* f, stream& s, farc_signature signature, farc_f s.set_position(align, SEEK_SET); size_t dir_len = f->directory_path.size(); - aes128_ctx ctx; + prj::Rijndael rijndael; if (signature == FARC_FARC) - aes128_init_ctx(&ctx, f->ft ? key_ft : key); + rijndael = prj::Rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, f->ft ? key_ft : key); f->compression_level = clamp_def(f->compression_level, 0, 12); @@ -592,8 +591,14 @@ static void farc_pack_files(farc* f, stream& s, farc_signature signature, farc_f const int32_t pkcs7_pad_len = (int32_t)(t2_len - t1_len - 0x10); memset(t2 + 0x10 + t1_len, pkcs7_pad_len, pkcs7_pad_len); // PKCS7 Padding - aes128_ctx_set_iv(&ctx, t2); - aes128_cbc_encrypt_buffer(&ctx, t2 + 0x10, t2_len - 0x10); + uint8_t iv[prj::Rijndael_Nlen]; + memcpy(iv, t2, prj::Rijndael_Nlen); + for (size_t j = 0; j < t2_len - 0x10; j += prj::Rijndael_Nlen) { + for (uint32_t k = 0; k < prj::Rijndael_Nlen / sizeof(uint32_t); k++) + ((uint32_t*)(t2 + 0x10 + j))[k] ^= ((uint32_t*)iv)[k]; + rijndael.encrypt16(t2 + 0x10 + j); + memcpy(iv, t2 + 0x10 + j, prj::Rijndael_Nlen); + } s.write(t2, t2_len); free_def(t2); @@ -606,7 +611,8 @@ static void farc_pack_files(farc* f, stream& s, farc_signature signature, farc_f memcpy(t2, t1, t1_len); memset(t2 + t1_len, 0x78, t2_len - t1_len); - aes128_ecb_encrypt_buffer(&ctx, t2, t2_len); + for (size_t j = 0; j < t2_len; j += prj::Rijndael_Nlen) + rijndael.encrypt16(t2 + j); s.write(t2, t2_len); free_def(t2); @@ -683,8 +689,14 @@ static void farc_pack_files(farc* f, stream& s, farc_signature signature, farc_f const int32_t pkcs7_pad_len = (int32_t)(head_data_len - (dt - head_data)); memset(dt, pkcs7_pad_len, pkcs7_pad_len); // PKCS7 Padding - aes128_ctx_set_iv(&ctx, head_data); - aes128_cbc_encrypt_buffer(&ctx, head_data + 0x10, head_data_len - 0x10); + uint8_t iv[prj::Rijndael_Nlen]; + memcpy(iv, head_data, prj::Rijndael_Nlen); + for (size_t i = 0; i < head_data_len - 0x10; i += prj::Rijndael_Nlen) { + for (uint32_t j = 0; j < prj::Rijndael_Nlen / sizeof(uint32_t); j++) + ((uint32_t*)(head_data + 0x10 + i))[j] ^= ((uint32_t*)iv)[j]; + rijndael.encrypt16(head_data + 0x10 + i); + memcpy(iv, head_data + 0x10 + i, prj::Rijndael_Nlen); + } } s.write(head_data, head_data_len); @@ -802,10 +814,19 @@ static errno_t farc_read_header(farc* f, stream& s) { if (f->ft) { header_length -= 0x10; - aes128_ctx ctx; - aes128_init_ctx_iv(&ctx, key_ft, dt); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key_ft); + + uint8_t iv[prj::Rijndael_Nlen]; + uint8_t next_iv[prj::Rijndael_Nlen]; + memcpy(iv, dt, prj::Rijndael_Nlen); dt += 0x10; - aes128_cbc_decrypt_buffer(&ctx, dt, header_length); + for (size_t i = 0; i < header_length; i += prj::Rijndael_Nlen) { + memcpy(next_iv, dt + i, prj::Rijndael_Nlen); + rijndael.decrypt16(dt + i); + for (uint32_t j = 0; j < prj::Rijndael_Nlen / sizeof(uint32_t); j++) + ((uint32_t*)(dt + i))[j] ^= ((uint32_t*)iv)[j]; + memcpy(iv, next_iv, prj::Rijndael_Nlen); + } header_length -= ((uint8_t*)dt)[header_length - 1]; // PKCS7 Padding } @@ -1017,34 +1038,44 @@ static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save, char* void* temp = force_malloc(temp_s); s.read(temp, temp_s); - size_t t = (size_t)temp; + uint8_t* t = (uint8_t*)temp; if (ff->encrypted) if (f->ft) { temp_s -= 0x10; t += 0x10; - aes128_ctx ctx; - aes128_init_ctx_iv(&ctx, key_ft, (uint8_t*)temp); - aes128_cbc_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key_ft); - ff->size_compressed = temp_s - ((uint8_t*)t)[temp_s - 1]; // PKCS7 Padding + uint8_t iv[prj::Rijndael_Nlen]; + uint8_t next_iv[prj::Rijndael_Nlen]; + memcpy(iv, (uint8_t*)temp, prj::Rijndael_Nlen); + for (size_t i = 0; i < temp_s; i += prj::Rijndael_Nlen) { + memcpy(next_iv, t + i, prj::Rijndael_Nlen); + rijndael.decrypt16(t + i); + for (uint32_t j = 0; j < prj::Rijndael_Nlen / sizeof(uint32_t); j++) + ((uint32_t*)(t + i))[j] ^= ((uint32_t*)iv)[j]; + memcpy(iv, next_iv, prj::Rijndael_Nlen); + } + + ff->size_compressed = temp_s - t[temp_s - 1]; // PKCS7 Padding } else { - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + + for (size_t i = 0; i < temp_s; i += prj::Rijndael_Nlen) + rijndael.decrypt16(t + i); } if (ff->compressed) { ff->data_compressed = force_malloc(ff->size_compressed); - memcpy(ff->data_compressed, (void*)t, ff->size_compressed); + memcpy(ff->data_compressed, t, ff->size_compressed); deflate::decompress(ff->data_compressed, ff->size_compressed, ff->data, ff->size, deflate::MODE_GZIP); } else { ff->data_compressed = 0; ff->data = force_malloc(ff->size); - memcpy(ff->data, (void*)t, ff->size); + memcpy(ff->data, t, ff->size); } free_def(temp); } diff --git a/src/KKdLib/farc.hpp b/src/KKdLib/farc.hpp index 15d21595..b1bc06e8 100644 --- a/src/KKdLib/farc.hpp +++ b/src/KKdLib/farc.hpp @@ -8,12 +8,7 @@ #include #include #include "default.hpp" - -enum farc_signature { - FARC_FArc = 'FArc', - FARC_FArC = 'FArC', - FARC_FARC = 'FARC', -}; +#include "prj/rijndael.hpp" enum farc_flags { FARC_NONE = 0x00, @@ -21,6 +16,12 @@ enum farc_flags { FARC_AES = 0x04, }; +enum farc_signature { + FARC_FArc = 'FArc', + FARC_FArC = 'FArC', + FARC_FARC = 'FARC', +}; + struct farc_file { std::string name; size_t offset; diff --git a/src/KKdLib/prj/rijndael.cpp b/src/KKdLib/prj/rijndael.cpp new file mode 100644 index 00000000..2198f0d4 --- /dev/null +++ b/src/KKdLib/prj/rijndael.cpp @@ -0,0 +1,392 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "rijndael.hpp" +#include // Added + +namespace prj_rijndael_detail { + union StateUnion { + uint32_t word[0x4]; + uint8_t byte[0x10]; + }; +} + +namespace { + struct PrjRijdaelTest { + PrjRijdaelTest(); + + void test(); + }; +} + +static const uint32_t r_con[] = { + 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, + 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A, + 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A, + 0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39, +}; + +static const uint8_t s_box[] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16, +}; + +static const uint8_t inv_s_box[256] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D, +}; + +static const uint32_t mix_col[] = { + 0x00000000, 0x03010102, 0x06020204, 0x05030306, 0x0C040408, 0x0F05050A, 0x0A06060C, 0x0907070E, + 0x18080810, 0x1B090912, 0x1E0A0A14, 0x1D0B0B16, 0x140C0C18, 0x170D0D1A, 0x120E0E1C, 0x110F0F1E, + 0x30101020, 0x33111122, 0x36121224, 0x35131326, 0x3C141428, 0x3F15152A, 0x3A16162C, 0x3917172E, + 0x28181830, 0x2B191932, 0x2E1A1A34, 0x2D1B1B36, 0x241C1C38, 0x271D1D3A, 0x221E1E3C, 0x211F1F3E, + 0x60202040, 0x63212142, 0x66222244, 0x65232346, 0x6C242448, 0x6F25254A, 0x6A26264C, 0x6927274E, + 0x78282850, 0x7B292952, 0x7E2A2A54, 0x7D2B2B56, 0x742C2C58, 0x772D2D5A, 0x722E2E5C, 0x712F2F5E, + 0x50303060, 0x53313162, 0x56323264, 0x55333366, 0x5C343468, 0x5F35356A, 0x5A36366C, 0x5937376E, + 0x48383870, 0x4B393972, 0x4E3A3A74, 0x4D3B3B76, 0x443C3C78, 0x473D3D7A, 0x423E3E7C, 0x413F3F7E, + 0xC0404080, 0xC3414182, 0xC6424284, 0xC5434386, 0xCC444488, 0xCF45458A, 0xCA46468C, 0xC947478E, + 0xD8484890, 0xDB494992, 0xDE4A4A94, 0xDD4B4B96, 0xD44C4C98, 0xD74D4D9A, 0xD24E4E9C, 0xD14F4F9E, + 0xF05050A0, 0xF35151A2, 0xF65252A4, 0xF55353A6, 0xFC5454A8, 0xFF5555AA, 0xFA5656AC, 0xF95757AE, + 0xE85858B0, 0xEB5959B2, 0xEE5A5AB4, 0xED5B5BB6, 0xE45C5CB8, 0xE75D5DBA, 0xE25E5EBC, 0xE15F5FBE, + 0xA06060C0, 0xA36161C2, 0xA66262C4, 0xA56363C6, 0xAC6464C8, 0xAF6565CA, 0xAA6666CC, 0xA96767CE, + 0xB86868D0, 0xBB6969D2, 0xBE6A6AD4, 0xBD6B6BD6, 0xB46C6CD8, 0xB76D6DDA, 0xB26E6EDC, 0xB16F6FDE, + 0x907070E0, 0x937171E2, 0x967272E4, 0x957373E6, 0x9C7474E8, 0x9F7575EA, 0x9A7676EC, 0x997777EE, + 0x887878F0, 0x8B7979F2, 0x8E7A7AF4, 0x8D7B7BF6, 0x847C7CF8, 0x877D7DFA, 0x827E7EFC, 0x817F7FFE, + 0x9B80801B, 0x98818119, 0x9D82821F, 0x9E83831D, 0x97848413, 0x94858511, 0x91868617, 0x92878715, + 0x8388880B, 0x80898909, 0x858A8A0F, 0x868B8B0D, 0x8F8C8C03, 0x8C8D8D01, 0x898E8E07, 0x8A8F8F05, + 0xAB90903B, 0xA8919139, 0xAD92923F, 0xAE93933D, 0xA7949433, 0xA4959531, 0xA1969637, 0xA2979735, + 0xB398982B, 0xB0999929, 0xB59A9A2F, 0xB69B9B2D, 0xBF9C9C23, 0xBC9D9D21, 0xB99E9E27, 0xBA9F9F25, + 0xFBA0A05B, 0xF8A1A159, 0xFDA2A25F, 0xFEA3A35D, 0xF7A4A453, 0xF4A5A551, 0xF1A6A657, 0xF2A7A755, + 0xE3A8A84B, 0xE0A9A949, 0xE5AAAA4F, 0xE6ABAB4D, 0xEFACAC43, 0xECADAD41, 0xE9AEAE47, 0xEAAFAF45, + 0xCBB0B07B, 0xC8B1B179, 0xCDB2B27F, 0xCEB3B37D, 0xC7B4B473, 0xC4B5B571, 0xC1B6B677, 0xC2B7B775, + 0xD3B8B86B, 0xD0B9B969, 0xD5BABA6F, 0xD6BBBB6D, 0xDFBCBC63, 0xDCBDBD61, 0xD9BEBE67, 0xDABFBF65, + 0x5BC0C09B, 0x58C1C199, 0x5DC2C29F, 0x5EC3C39D, 0x57C4C493, 0x54C5C591, 0x51C6C697, 0x52C7C795, + 0x43C8C88B, 0x40C9C989, 0x45CACA8F, 0x46CBCB8D, 0x4FCCCC83, 0x4CCDCD81, 0x49CECE87, 0x4ACFCF85, + 0x6BD0D0BB, 0x68D1D1B9, 0x6DD2D2BF, 0x6ED3D3BD, 0x67D4D4B3, 0x64D5D5B1, 0x61D6D6B7, 0x62D7D7B5, + 0x73D8D8AB, 0x70D9D9A9, 0x75DADAAF, 0x76DBDBAD, 0x7FDCDCA3, 0x7CDDDDA1, 0x79DEDEA7, 0x7ADFDFA5, + 0x3BE0E0DB, 0x38E1E1D9, 0x3DE2E2DF, 0x3EE3E3DD, 0x37E4E4D3, 0x34E5E5D1, 0x31E6E6D7, 0x32E7E7D5, + 0x23E8E8CB, 0x20E9E9C9, 0x25EAEACF, 0x26EBEBCD, 0x2FECECC3, 0x2CEDEDC1, 0x29EEEEC7, 0x2AEFEFC5, + 0x0BF0F0FB, 0x08F1F1F9, 0x0DF2F2FF, 0x0EF3F3FD, 0x07F4F4F3, 0x04F5F5F1, 0x01F6F6F7, 0x02F7F7F5, + 0x13F8F8EB, 0x10F9F9E9, 0x15FAFAEF, 0x16FBFBED, 0x1FFCFCE3, 0x1CFDFDE1, 0x19FEFEE7, 0x1AFFFFE5, +}; + +static const uint32_t inv_mix_col[] = { + 0x00000000, 0x0B0D090E, 0x161A121C, 0x1D171B12, 0x2C342438, 0x27392D36, 0x3A2E3624, 0x31233F2A, + 0x58684870, 0x5365417E, 0x4E725A6C, 0x457F5362, 0x745C6C48, 0x7F516546, 0x62467E54, 0x694B775A, + 0xB0D090E0, 0xBBDD99EE, 0xA6CA82FC, 0xADC78BF2, 0x9CE4B4D8, 0x97E9BDD6, 0x8AFEA6C4, 0x81F3AFCA, + 0xE8B8D890, 0xE3B5D19E, 0xFEA2CA8C, 0xF5AFC382, 0xC48CFCA8, 0xCF81F5A6, 0xD296EEB4, 0xD99BE7BA, + 0x7BBB3BDB, 0x70B632D5, 0x6DA129C7, 0x66AC20C9, 0x578F1FE3, 0x5C8216ED, 0x41950DFF, 0x4A9804F1, + 0x23D373AB, 0x28DE7AA5, 0x35C961B7, 0x3EC468B9, 0x0FE75793, 0x04EA5E9D, 0x19FD458F, 0x12F04C81, + 0xCB6BAB3B, 0xC066A235, 0xDD71B927, 0xD67CB029, 0xE75F8F03, 0xEC52860D, 0xF1459D1F, 0xFA489411, + 0x9303E34B, 0x980EEA45, 0x8519F157, 0x8E14F859, 0xBF37C773, 0xB43ACE7D, 0xA92DD56F, 0xA220DC61, + 0xF66D76AD, 0xFD607FA3, 0xE07764B1, 0xEB7A6DBF, 0xDA595295, 0xD1545B9B, 0xCC434089, 0xC74E4987, + 0xAE053EDD, 0xA50837D3, 0xB81F2CC1, 0xB31225CF, 0x82311AE5, 0x893C13EB, 0x942B08F9, 0x9F2601F7, + 0x46BDE64D, 0x4DB0EF43, 0x50A7F451, 0x5BAAFD5F, 0x6A89C275, 0x6184CB7B, 0x7C93D069, 0x779ED967, + 0x1ED5AE3D, 0x15D8A733, 0x08CFBC21, 0x03C2B52F, 0x32E18A05, 0x39EC830B, 0x24FB9819, 0x2FF69117, + 0x8DD64D76, 0x86DB4478, 0x9BCC5F6A, 0x90C15664, 0xA1E2694E, 0xAAEF6040, 0xB7F87B52, 0xBCF5725C, + 0xD5BE0506, 0xDEB30C08, 0xC3A4171A, 0xC8A91E14, 0xF98A213E, 0xF2872830, 0xEF903322, 0xE49D3A2C, + 0x3D06DD96, 0x360BD498, 0x2B1CCF8A, 0x2011C684, 0x1132F9AE, 0x1A3FF0A0, 0x0728EBB2, 0x0C25E2BC, + 0x656E95E6, 0x6E639CE8, 0x737487FA, 0x78798EF4, 0x495AB1DE, 0x4257B8D0, 0x5F40A3C2, 0x544DAACC, + 0xF7DAEC41, 0xFCD7E54F, 0xE1C0FE5D, 0xEACDF753, 0xDBEEC879, 0xD0E3C177, 0xCDF4DA65, 0xC6F9D36B, + 0xAFB2A431, 0xA4BFAD3F, 0xB9A8B62D, 0xB2A5BF23, 0x83868009, 0x888B8907, 0x959C9215, 0x9E919B1B, + 0x470A7CA1, 0x4C0775AF, 0x51106EBD, 0x5A1D67B3, 0x6B3E5899, 0x60335197, 0x7D244A85, 0x7629438B, + 0x1F6234D1, 0x146F3DDF, 0x097826CD, 0x02752FC3, 0x335610E9, 0x385B19E7, 0x254C02F5, 0x2E410BFB, + 0x8C61D79A, 0x876CDE94, 0x9A7BC586, 0x9176CC88, 0xA055F3A2, 0xAB58FAAC, 0xB64FE1BE, 0xBD42E8B0, + 0xD4099FEA, 0xDF0496E4, 0xC2138DF6, 0xC91E84F8, 0xF83DBBD2, 0xF330B2DC, 0xEE27A9CE, 0xE52AA0C0, + 0x3CB1477A, 0x37BC4E74, 0x2AAB5566, 0x21A65C68, 0x10856342, 0x1B886A4C, 0x069F715E, 0x0D927850, + 0x64D90F0A, 0x6FD40604, 0x72C31D16, 0x79CE1418, 0x48ED2B32, 0x43E0223C, 0x5EF7392E, 0x55FA3020, + 0x01B79AEC, 0x0ABA93E2, 0x17AD88F0, 0x1CA081FE, 0x2D83BED4, 0x268EB7DA, 0x3B99ACC8, 0x3094A5C6, + 0x59DFD29C, 0x52D2DB92, 0x4FC5C080, 0x44C8C98E, 0x75EBF6A4, 0x7EE6FFAA, 0x63F1E4B8, 0x68FCEDB6, + 0xB1670A0C, 0xBA6A0302, 0xA77D1810, 0xAC70111E, 0x9D532E34, 0x965E273A, 0x8B493C28, 0x80443526, + 0xE90F427C, 0xE2024B72, 0xFF155060, 0xF418596E, 0xC53B6644, 0xCE366F4A, 0xD3217458, 0xD82C7D56, + 0x7A0CA137, 0x7101A839, 0x6C16B32B, 0x671BBA25, 0x5638850F, 0x5D358C01, 0x40229713, 0x4B2F9E1D, + 0x2264E947, 0x2969E049, 0x347EFB5B, 0x3F73F255, 0x0E50CD7F, 0x055DC471, 0x184ADF63, 0x1347D66D, + 0xCADC31D7, 0xC1D138D9, 0xDCC623CB, 0xD7CB2AC5, 0xE6E815EF, 0xEDE51CE1, 0xF0F207F3, 0xFBFF0EFD, + 0x92B479A7, 0x99B970A9, 0x84AE6BBB, 0x8FA362B5, 0xBE805D9F, 0xB58D5491, 0xA89A4F83, 0xA397468D, +}; + +namespace { + PrjRijdaelTest prj_rijdael_test_obj; +} + +extern bool cpu_caps_aes_ni; // Added + +static void prj_rij_inv_mix_columns(uint32_t* key); + +static void prj_rij_mix_columns_add_round_key(prj_rijndael_detail::StateUnion* state, const uint32_t* key); +static void prj_rij_inv_mix_columns_add_round_key(prj_rijndael_detail::StateUnion* state, const uint32_t* key); + +static void prj_rij_sub_bytes_shift_rows(prj_rijndael_detail::StateUnion* state); +static void prj_rij_inv_sub_bytes_shift_rows(prj_rijndael_detail::StateUnion* state); + +static uint32_t prj_rij_mix_columns(uint32_t word); +static uint32_t prj_rij_inv_mix_columns(uint32_t word); +static uint32_t prj_rij_rot_word(uint32_t word); +static uint32_t prj_rij_sub_word(uint32_t word); + +void prj_rij_gkey(PrjRijKeyParam* kp, size_t nb, size_t nk, const void* key) { + *kp = {}; + kp->num_key = (uint32_t)nk; + kp->num_block = (uint32_t)nb; + if (nk == prj::Rijndael_Nk128) + kp->num_round = prj::Rijndael_Nr128; + else if (nk == prj::Rijndael_Nk192) + kp->num_round = prj::Rijndael_Nr192; + else + kp->num_round = prj::Rijndael_Nr256; + + memmove(kp->enc_key, key, nk * sizeof(uint32_t)); + + for (size_t i = nk; i < prj::Rijndael_Nb * (kp->num_round + 1ULL); i++) { + uint32_t temp = kp->enc_key[i - 1]; + if (!(i % nk)) + temp = prj_rij_sub_word(prj_rij_rot_word(temp)) ^ r_con[i / nk]; + else if (nk > 6 && (i % nk) == 4) + temp = prj_rij_sub_word(temp); + + kp->enc_key[i] = kp->enc_key[i - nk] ^ temp; + } + + for (size_t i = 0; i < prj::Rijndael_Nb * (kp->num_round + 1ULL); i++) + kp->dec_key[i] = kp->enc_key[i]; + + for (uint32_t i = 1; i < kp->num_round; i++) + prj_rij_inv_mix_columns(&kp->dec_key[prj::Rijndael_Nb * i]); +} + +void prj_rij_decrypt(PrjRijKeyParam* kp, const void* in_buff16, void* out_buff16) { + if (cpu_caps_aes_ni) { // Added + __m128i* dec_key = (__m128i*)kp->dec_key; + __m128i m = _mm_loadu_si128((__m128i*)in_buff16); + m = _mm_xor_si128(m, dec_key[kp->num_round]); + + for (uint32_t i = 1, j = kp->num_round - 1; i < kp->num_round; i++, j--) + m = _mm_aesdec_si128(m, dec_key[j]); + + m = _mm_aesdeclast_si128(m, dec_key[0]); + _mm_storeu_si128((__m128i*)out_buff16, m); + return; + } + + prj_rijndael_detail::StateUnion state; + memcpy(state.byte, in_buff16, prj::Rijndael_Nb * sizeof(uint32_t)); + + uint32_t* dec_key = &kp->dec_key[prj::Rijndael_Nb * kp->num_round]; + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + state.word[i] ^= dec_key[i]; + + for (uint32_t i = 1, j = kp->num_round - 1; i < kp->num_round; i++, j--) { + prj_rij_inv_sub_bytes_shift_rows(&state); + prj_rij_inv_mix_columns_add_round_key(&state, &kp->dec_key[prj::Rijndael_Nb * j]); + } + + prj_rij_inv_sub_bytes_shift_rows(&state); + + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + state.word[i] ^= kp->dec_key[i]; + + memcpy(out_buff16, state.byte, prj::Rijndael_Nb * sizeof(uint32_t)); +} + +void prj_rij_encrypt(PrjRijKeyParam* kp, const void* in_buff16, void* out_buff16) { + if (cpu_caps_aes_ni) { // Added + const __m128i* enc_key = (const __m128i*)kp->enc_key; + __m128i m = _mm_loadu_si128((__m128i*)in_buff16); + m = _mm_xor_si128(m, enc_key[0]); + + for (uint32_t i = 1; i < kp->num_round; i++) + m = _mm_aesenc_si128(m, enc_key[i]); + + m = _mm_aesenclast_si128(m, enc_key[kp->num_round]); + _mm_storeu_si128((__m128i*)out_buff16, m); + return; + } + + prj_rijndael_detail::StateUnion state; + memcpy(state.byte, in_buff16, prj::Rijndael_Nb * sizeof(uint32_t)); + + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + state.word[i] ^= kp->dec_key[i]; + + for (uint32_t i = 1; i < kp->num_round; i++) { + prj_rij_sub_bytes_shift_rows(&state); + prj_rij_mix_columns_add_round_key(&state, &kp->enc_key[prj::Rijndael_Nb * i]); + } + + prj_rij_sub_bytes_shift_rows(&state); + + uint32_t* enc_key = &kp->dec_key[prj::Rijndael_Nb * kp->num_round]; + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + state.word[i] ^= enc_key[i]; + + memcpy(out_buff16, state.byte, prj::Rijndael_Nb * sizeof(uint32_t)); +} + +void prj_rij_test_encrypt_decrypt(PrjRijKeyParam* kp, const void* plain) { + uint8_t encoded[16]; + uint8_t decoded[16]; + + prj_rij_encrypt(kp, plain, encoded); + prj_rij_decrypt(kp, encoded, decoded); +} + +PrjRijdaelTest::PrjRijdaelTest() { + test(); +} + +void PrjRijdaelTest::test() { + static const uint8_t key[] = { + 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + }; + + static const uint8_t plain[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + }; + + { + prj::Rijndael kp128(prj::Rijndael_Nb, prj::Rijndael_Nk128, &key[0x01]); + kp128.test_encrypt_decrypt(plain); + } + + { + prj::Rijndael kp192(prj::Rijndael_Nb, prj::Rijndael_Nk192, &key[0x01]); + kp192.test_encrypt_decrypt(plain); + } + + { + prj::Rijndael kp256(prj::Rijndael_Nb, prj::Rijndael_Nk256, &key[0x01]); + kp256.test_encrypt_decrypt(plain); + } +} + +static void prj_rij_inv_mix_columns(uint32_t* key) { + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + key[i] = prj_rij_inv_mix_columns(key[i]); +} + +static void prj_rij_mix_columns_add_round_key(prj_rijndael_detail::StateUnion* state, const uint32_t* key) { + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + state->word[i] = prj_rij_mix_columns(state->word[i]) ^ key[i]; +} + +static void prj_rij_inv_mix_columns_add_round_key(prj_rijndael_detail::StateUnion* state, const uint32_t* key) { + for (size_t i = 0; i < prj::Rijndael_Nb; i++) + state->word[i] = prj_rij_inv_mix_columns(state->word[i]) ^ key[i]; +} + +static void prj_rij_sub_bytes_shift_rows(prj_rijndael_detail::StateUnion* state) { + uint8_t temp, temp1, temp2; + + state->byte[0x00] = s_box[state->byte[0x00]]; + state->byte[0x04] = s_box[state->byte[0x04]]; + state->byte[0x08] = s_box[state->byte[0x08]]; + state->byte[0x0C] = s_box[state->byte[0x0C]]; + + temp1 = s_box[state->byte[0x01]]; + state->byte[0x01] = s_box[state->byte[0x05]]; + state->byte[0x05] = s_box[state->byte[0x09]]; + temp2 = s_box[state->byte[0x0D]]; + state->byte[0x0D] = temp1; + state->byte[0x09] = temp2; + + temp = s_box[state->byte[0x0A]]; + state->byte[0x0A] = s_box[state->byte[0x02]]; + state->byte[0x02] = temp; + + temp = s_box[state->byte[0x0E]]; + state->byte[0x0E] = s_box[state->byte[0x06]]; + state->byte[0x06] = temp; + + temp1 = s_box[state->byte[0x0F]]; + state->byte[0x0F] = s_box[state->byte[0x0B]]; + state->byte[0x0B] = s_box[state->byte[0x07]]; + temp2 = s_box[state->byte[0x03]]; + state->byte[0x03] = temp1; + state->byte[0x07] = temp2; +} + +static void prj_rij_inv_sub_bytes_shift_rows(prj_rijndael_detail::StateUnion* state) { + uint8_t temp, temp1, temp2; + + state->byte[0x00] = inv_s_box[state->byte[0x00]]; + state->byte[0x04] = inv_s_box[state->byte[0x04]]; + state->byte[0x08] = inv_s_box[state->byte[0x08]]; + state->byte[0x0C] = inv_s_box[state->byte[0x0C]]; + + temp1 = inv_s_box[state->byte[0x0D]]; + state->byte[0x0D] = inv_s_box[state->byte[0x09]]; + state->byte[0x09] = inv_s_box[state->byte[0x05]]; + temp2 = inv_s_box[state->byte[0x01]]; + state->byte[0x01] = temp1; + state->byte[0x05] = temp2; + + temp = inv_s_box[state->byte[0x06]]; + state->byte[0x06] = inv_s_box[state->byte[0x0E]]; + state->byte[0x0E] = temp; + + temp = inv_s_box[state->byte[0x02]]; + state->byte[0x02] = inv_s_box[state->byte[0x0A]]; + state->byte[0x0A] = temp; + + temp1 = inv_s_box[state->byte[0x03]]; + state->byte[0x03] = inv_s_box[state->byte[0x07]]; + state->byte[0x07] = inv_s_box[state->byte[0x0B]]; + temp2 = inv_s_box[state->byte[0x0F]]; + state->byte[0x0F] = temp1; + state->byte[0x0B] = temp2; +} + +inline static uint32_t prj_rij_mix_columns(uint32_t word) { + return mix_col[word & 0xFFu] ^ _rotl(mix_col[(word >> 8u) & 0xFFu], 8u) + ^ _rotl(mix_col[(word >> 16u) & 0xFFu], 16u) ^ _rotr(mix_col[(word >> 24u) & 0xFFu], 8u); +} + +inline static uint32_t prj_rij_inv_mix_columns(uint32_t word) { + return inv_mix_col[word & 0xFFu] ^ _rotl(inv_mix_col[(word >> 8u) & 0xFFu], 8u) + ^ _rotl(inv_mix_col[(word >> 16u) & 0xFFu], 16u) ^ _rotr(inv_mix_col[(word >> 24u) & 0xFFu], 8u); +} + +inline static uint32_t prj_rij_rot_word(uint32_t word) { + return _rotr(word, 8); +} + +inline static uint32_t prj_rij_sub_word(uint32_t word) { + return (((((s_box[(word >> 24u) & 0xFFu] << 8u) | s_box[(word >> 16u) & 0xFFu]) << 8u) + | s_box[(word >> 8u) & 0xFFu]) << 8u) | s_box[word & 0xFF]; +} diff --git a/src/KKdLib/prj/rijndael.hpp b/src/KKdLib/prj/rijndael.hpp new file mode 100644 index 00000000..599feaa4 --- /dev/null +++ b/src/KKdLib/prj/rijndael.hpp @@ -0,0 +1,84 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../default.hpp" + +namespace prj { + static constexpr size_t Rijndael_Nb = 4; + + static constexpr uint32_t Rijndael_Nk128 = 4; + static constexpr uint32_t Rijndael_Nr128 = 10; + static constexpr uint32_t Rijndael_Nk192 = 6; + static constexpr uint32_t Rijndael_Nr192 = 12; + static constexpr uint32_t Rijndael_Nk256 = 8; + static constexpr uint32_t Rijndael_Nr256 = 14; + + static constexpr size_t Rijndael_Nlen = Rijndael_Nb * sizeof(uint32_t); +} + +struct alignas(prj::Rijndael_Nlen) PrjRijKeyParam { + uint32_t num_key; + uint32_t num_round; + uint32_t num_block; + uint32_t pad0; + uint32_t enc_key[(prj::Rijndael_Nr256 + 1ULL) * prj::Rijndael_Nb]; + uint32_t dec_key[(prj::Rijndael_Nr256 + 1ULL) * prj::Rijndael_Nb]; + uint32_t pad1[4]; +}; + +static_assert(offsetof(PrjRijKeyParam, enc_key) % prj::Rijndael_Nlen == 0, "\"PrjRijKeyParam\" struct should have \"enc_key\" field aligned to prj::Rijndael_Nlen"); +static_assert(offsetof(PrjRijKeyParam, dec_key) % prj::Rijndael_Nlen == 0, "\"PrjRijKeyParam\" struct should have \"dec_key\" field aligned to prj::Rijndael_Nlen"); + +namespace prj { + class Rijndael { + PrjRijKeyParam M_kp; + + public: + Rijndael(); + Rijndael(size_t nb, size_t nk, const void* key); + + void encrypt16(const void* in_buff16, void* out_buff16); + void encrypt16(void* buff16); + void decrypt16(const void* in_buff16, void* out_buff16); + void decrypt16(void* buff16); + + void test_encrypt_decrypt(const void* plain); + }; +} + +extern void prj_rij_gkey(PrjRijKeyParam* kp, size_t nb, size_t nk, const void* key); +extern void prj_rij_decrypt(PrjRijKeyParam* kp, const void* in_buff16, void* out_buff16); +extern void prj_rij_encrypt(PrjRijKeyParam* kp, const void* in_buff16, void* out_buff16); +extern void prj_rij_test_encrypt_decrypt(PrjRijKeyParam* kp, const void* plain); + +namespace prj { + inline Rijndael::Rijndael() : M_kp() { } + + inline Rijndael::Rijndael(size_t nb, size_t nk, const void* key) : M_kp() { + prj_rij_gkey(&M_kp, nb, nk, key); + } + + inline void Rijndael::encrypt16(const void* in_buff16, void* out_buff16) { + prj_rij_encrypt(&M_kp, in_buff16, out_buff16); + } + + inline void Rijndael::encrypt16(void* buff16) { + prj_rij_encrypt(&M_kp, buff16, buff16); + } + + inline void Rijndael::decrypt16(const void* in_buff16, void* out_buff16) { + prj_rij_decrypt(&M_kp, in_buff16, out_buff16); + } + + inline void Rijndael::decrypt16(void* buff16) { + prj_rij_decrypt(&M_kp, buff16, buff16); + } + + inline void Rijndael::test_encrypt_decrypt(const void* plain) { + prj_rij_test_encrypt_decrypt(&M_kp, plain); + } +} diff --git a/src/KKdLib/x_save.cpp b/src/KKdLib/x_save.cpp index 91afd88e..7bb40c09 100644 --- a/src/KKdLib/x_save.cpp +++ b/src/KKdLib/x_save.cpp @@ -6,7 +6,7 @@ #include "x_save.hpp" #include "f2/header.hpp" #include "io/file_stream.hpp" -#include "aes.hpp" +#include "prj/rijndael.hpp" #include "deflate.hpp" static const uint8_t savedata_key[] = { @@ -171,9 +171,9 @@ static bool x_save_decode(std::vector& data, void*& dec, size_t& dec_le uint8_t* section_data = head->get_section_data(); uint32_t section_size = head->get_section_size(); if (section_data && section_size == align_val(section_size, 0x20)) { - aes256_ctx aes; - aes256_init_ctx(&aes, savedata_key); - aes256_ecb_decrypt_buffer(&aes, section_data, section_size); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk256, savedata_key); + for (size_t i = 0; i < section_size; i += prj::Rijndael_Nlen) + rijndael.decrypt16(section_data + i); head->attrib.set_aes(false); } } @@ -270,9 +270,9 @@ static bool x_save_encode(std::vector& data, void*& enc, x_save_encode_ uint8_t* section_data = head->get_section_data(); uint32_t section_size = head->get_section_size(); if (section_data && section_size == align_val(section_size, 0x20)) { - aes256_ctx aes; - aes256_init_ctx(&aes, savedata_key); - aes256_ecb_encrypt_buffer(&aes, section_data, section_size); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk256, savedata_key); + for (size_t i = 0; i < section_size; i += prj::Rijndael_Nlen) + rijndael.encrypt16(section_data + i); head->attrib.set_aes(true); } } diff --git a/src/MMPlusDec/MMPlusDec.cpp b/src/MMPlusDec/MMPlusDec.cpp index cf34b43e..18acd50f 100644 --- a/src/MMPlusDec/MMPlusDec.cpp +++ b/src/MMPlusDec/MMPlusDec.cpp @@ -10,7 +10,7 @@ #include "../KKdLib/default.hpp" #include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/io/path.hpp" -#include "../KKdLib/aes.hpp" +#include "../KKdLib/prj/rijndael.hpp" #include "../KKdLib/str_utils.hpp" #include @@ -67,8 +67,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) { cpu_caps_aes_ni = (cpuid_data[2] & (1 << 25)) ? true : false; cpu_caps_f16c = (cpuid_data[2] & (1 << 29)) ? true : false; - aes256_ctx ctx; - aes256_init_ctx(&ctx, mmplus_key); + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk256, mmplus_key); { std::vector files = path_get_files(indir.c_str()); @@ -85,7 +84,9 @@ int32_t wmain(int32_t argc, wchar_t** argv) { if (in_file.check_not_null() && out_file.check_not_null()) { printf(encrypt ? "Encrypting %ls\n" : "Decrypting %ls\n", i.c_str()); - aes256_ctx_set_iv(&ctx, mmplus_iv); + uint8_t iv[prj::Rijndael_Nlen]; + uint8_t next_iv[prj::Rijndael_Nlen]; + memcpy(iv, mmplus_iv, prj::Rijndael_Nlen); size_t length = in_file.get_length(); @@ -100,7 +101,13 @@ int32_t wmain(int32_t argc, wchar_t** argv) { size += align; } - aes256_cbc_encrypt_buffer(&ctx, buf, size); + for (size_t j = 0; j < size; j += prj::Rijndael_Nlen) { + for (uint32_t k = 0; k < prj::Rijndael_Nlen / sizeof(uint32_t); k++) + ((uint32_t*)(buf + j))[k] ^= ((uint32_t*)iv)[k]; + rijndael.encrypt16(buf + j); + memcpy(iv, buf + j, prj::Rijndael_Nlen); + } + out_file.write(buf, size); length -= min_def(length, size); @@ -108,7 +115,13 @@ int32_t wmain(int32_t argc, wchar_t** argv) { } else { while (length && (size = in_file.read_data(buf))) { - aes256_cbc_decrypt_buffer(&ctx, buf, size); + for (size_t j = 0; j < size; j += prj::Rijndael_Nlen) { + memcpy(next_iv, buf + j, prj::Rijndael_Nlen); + rijndael.decrypt16(buf + j); + for (uint32_t k = 0; k < prj::Rijndael_Nlen / sizeof(uint32_t); k++) + ((uint32_t*)(buf + j))[k] ^= ((uint32_t*)iv)[k]; + memcpy(iv, next_iv, prj::Rijndael_Nlen); + } if (length == size) // PKCS7 Padding size -= buf[size - 1]; @@ -145,7 +158,9 @@ int32_t wmain(int32_t argc, wchar_t** argv) { if (in_file.check_not_null() && out_file.check_not_null()) { printf(encrypt ? "Encrypting %ls\\%ls\n" : "Decrypting %ls\\%ls\n", i.c_str(), j.c_str()); - aes256_ctx_set_iv(&ctx, mmplus_iv); + uint8_t iv[prj::Rijndael_Nlen]; + uint8_t next_iv[prj::Rijndael_Nlen]; + memcpy(iv, mmplus_iv, prj::Rijndael_Nlen); size_t length = in_file.get_length(); @@ -160,7 +175,13 @@ int32_t wmain(int32_t argc, wchar_t** argv) { size += align; } - aes256_cbc_encrypt_buffer(&ctx, buf, size); + for (size_t j = 0; j < size; j += prj::Rijndael_Nlen) { + for (uint32_t k = 0; k < prj::Rijndael_Nlen / sizeof(uint32_t); k++) + ((uint32_t*)(buf + j))[k] ^= ((uint32_t*)iv)[k]; + rijndael.encrypt16(buf + j); + memcpy(iv, buf + j, prj::Rijndael_Nlen); + } + out_file.write(buf, size); length -= size; @@ -168,7 +189,13 @@ int32_t wmain(int32_t argc, wchar_t** argv) { } else { while (length && (size = in_file.read_data(buf))) { - aes256_cbc_decrypt_buffer(&ctx, buf, size); + for (size_t j = 0; j < size; j += prj::Rijndael_Nlen) { + memcpy(next_iv, buf + j, prj::Rijndael_Nlen); + rijndael.decrypt16(buf + j); + for (uint32_t k = 0; k < prj::Rijndael_Nlen / sizeof(uint32_t); k++) + ((uint32_t*)(buf + j))[k] ^= ((uint32_t*)iv)[k]; + memcpy(iv, next_iv, prj::Rijndael_Nlen); + } if (length == size) // PKCS7 Padding size -= buf[size - 1]; diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 38831d14..5cfecf59 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -35,7 +35,7 @@ #if BAKE_X_PACK #include "../KKdLib/f2/header.hpp" #include "../KKdLib/io/memory_stream.hpp" -#include "../KKdLib/aes.hpp" +#include "../KKdLib/prj/rijndael.hpp" #include "../KKdLib/deflate.hpp" #include "../KKdLib/waitable_timer.hpp" #include @@ -10005,9 +10005,18 @@ void obj_set_reflect::pack_file(void** data, size_t* size, bool mmp, for (uint32_t i = 0; i < 0x10; i += sizeof(uint32_t)) *(uint32_t*)(iv + i) = rand_state_array_get_int(4); - aes256_ctx aes; - aes256_init_ctx_iv(&aes, key, iv); - aes256_cbc_encrypt_buffer(&aes, section_data, section_size); + + prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); + + uint8_t _iv[prj::Rijndael_Nlen]; + memcpy(_iv, iv, prj::Rijndael_Nlen); + for (size_t i = 0; i < section_size; i += prj::Rijndael_Nlen) { + for (uint32_t j = 0; j < prj::Rijndael_Nlen / sizeof(uint32_t); j++) + ((uint32_t*)(section_data + i))[j] ^= ((uint32_t*)_iv)[j]; + rijndael.encrypt16(section_data + i); + memcpy(_iv, section_data + i, prj::Rijndael_Nlen); + } + head->attrib.set_aes(true); } }