-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8d46fdd
commit 2f3ae74
Showing
16 changed files
with
2,259 additions
and
1,052 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
#include "aes.hpp" | ||
|
||
#include <array> | ||
#include <immintrin.h> | ||
|
||
// Encryption: Forward Rijndael S-box | ||
constexpr unsigned char s[256] = { | ||
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 | ||
}; | ||
|
||
// Used in KeyExpansion | ||
constexpr unsigned char rcon[256] = { | ||
0x8d, 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, | ||
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, | ||
0x74, 0xe8, 0xcb, 0x8d, 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, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, | ||
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, | ||
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, | ||
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x72, 0xe4, 0xd3, 0xbd, | ||
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d | ||
}; | ||
|
||
constexpr auto expandKey(const std::array<uint8_t, 16>& key) { | ||
std::array<uint8_t, 176> out; | ||
|
||
constexpr int v = s[114]; | ||
|
||
out[0] = key[0]; | ||
out[4] = key[1]; | ||
out[8] = key[2]; | ||
out[12] = key[3]; | ||
out[1] = key[4]; | ||
out[5] = key[5]; | ||
out[9] = key[6]; | ||
out[13] = key[7]; | ||
out[2] = key[8]; | ||
out[6] = key[9]; | ||
out[10] = key[10]; | ||
out[14] = key[11]; | ||
out[3] = key[12]; | ||
out[7] = key[13]; | ||
out[11] = key[14]; | ||
out[15] = key[15]; | ||
|
||
uint8_t bVar9 = key[2]; | ||
uint8_t bVar16 = key[4]; | ||
uint8_t bVar12 = key[9]; | ||
uint8_t bVar17 = key[10]; | ||
uint8_t bVar10 = key[11]; | ||
uint8_t bVar11 = key[12]; | ||
uint8_t bVar13 = key[13]; | ||
uint8_t bVar18 = key[14]; | ||
uint8_t bVar14 = key[15]; | ||
|
||
// uint8_t* pbVar8 = out.data() + 31; | ||
|
||
for (size_t lVar15 = 0; lVar15 < 10; lVar15++) { | ||
int local_41 = out[0 + lVar15 * 16]; | ||
local_41 ^= rcon[lVar15 + 1] ^ s[bVar13]; | ||
out[16 + lVar15 * 16] = local_41; | ||
|
||
int local_42 = out[4 + lVar15 * 16]; | ||
local_42 ^= s[bVar18]; | ||
out[20 + lVar15 * 16] = local_42; | ||
|
||
bVar9 ^= s[bVar14]; | ||
out[24 + lVar15 * 16] = bVar9; | ||
|
||
int local_43 = out[12 + lVar15 * 16]; | ||
local_43 ^= s[bVar11]; | ||
out[28 + lVar15 * 16] = local_43; | ||
|
||
bVar16 ^= local_41; | ||
out[17 + lVar15 * 16] = bVar16; | ||
|
||
int local_44 = out[5 + lVar15 * 16]; | ||
local_44 ^= local_42; | ||
out[21 + lVar15 * 16] = local_44; | ||
|
||
int local_45 = out[9 + lVar15 * 16]; | ||
local_45 ^= bVar9; | ||
out[25 + lVar15 * 16] = local_45; | ||
|
||
int local_46 = out[13 + lVar15 * 16]; | ||
local_46 ^= local_43; | ||
out[29 + lVar15 * 16] = local_46; | ||
|
||
int local_47 = out[2 + lVar15 * 16]; | ||
local_47 ^= bVar16; | ||
out[18 + lVar15 * 16] = local_47; | ||
|
||
bVar12 ^= local_44; | ||
out[22 + lVar15 * 16] = bVar12; | ||
|
||
bVar17 ^= local_45; | ||
out[26 + lVar15 * 16] = bVar17; | ||
|
||
bVar10 ^= local_46; | ||
out[30 + lVar15 * 16] = bVar10; | ||
|
||
bVar11 ^= local_47; | ||
out[19 + lVar15 * 16] = bVar11; | ||
|
||
bVar13 ^= bVar12; | ||
out[23 + lVar15 * 16] = bVar13; | ||
|
||
bVar18 ^= bVar17; | ||
out[27 + lVar15 * 16] = bVar18; | ||
|
||
bVar14 ^= bVar10; | ||
out[31 + lVar15 * 16] = bVar14; | ||
} | ||
|
||
return out; | ||
} | ||
|
||
static_assert(expandKey({'G', 'o', 'o', 'd', 'L', 'U', 'c', 'K', 'M', 'y', 'F', 'r', 'i', 'E', 'n', 'd'}) == std::array<uint8_t, 176>{ | ||
0x47, 0x4c, 0x4d, 0x69, 0x6f, 0x55, 0x79, 0x45, 0x6f, 0x63, 0x46, 0x6e, 0x64, 0x4b, 0x72, 0x64, | ||
0x28, 0x64, 0x29, 0x40, 0xf0, 0xa5, 0xdc, 0x99, 0x2c, 0x4f, 0x09, 0x67, 0x9d, 0xd6, 0xa4, 0xc0, | ||
0xc4, 0xa0, 0x89, 0xc9, 0x75, 0xd0, 0x0c, 0x95, 0x96, 0xd9, 0xd0, 0xb7, 0x94, 0x42, 0xe6, 0x26, | ||
0xea, 0x4a, 0xc3, 0x0a, 0xdc, 0x0c, 0x00, 0x95, 0x61, 0xb8, 0x68, 0xdf, 0x49, 0x0b, 0xed, 0xcb, | ||
0xc8, 0x82, 0x41, 0x4b, 0x42, 0x4e, 0x4e, 0xdb, 0x7e, 0xc6, 0xae, 0x71, 0x2e, 0x25, 0xc8, 0x03, | ||
0x61, 0xe3, 0xa2, 0xe9, 0xe1, 0xaf, 0xe1, 0x3a, 0x05, 0xc3, 0x6d, 0x1c, 0x9d, 0xb8, 0x70, 0x73, | ||
0xc1, 0x22, 0x80, 0x69, 0x7d, 0xd2, 0x33, 0x09, 0x8a, 0x49, 0x24, 0x38, 0x83, 0x3b, 0x4b, 0x38, | ||
0x80, 0xa2, 0x22, 0x4b, 0x7a, 0xa8, 0x9b, 0x92, 0x8d, 0xc4, 0xe0, 0xd8, 0x7a, 0x41, 0x0a, 0x32, | ||
0x4f, 0xed, 0xcf, 0x84, 0x1b, 0xb3, 0x28, 0xba, 0xae, 0x6a, 0x8a, 0x52, 0xc9, 0x88, 0x82, 0xb0, | ||
0xa0, 0x4d, 0x82, 0x06, 0x1b, 0xa8, 0x80, 0x3a, 0x49, 0x23, 0xa9, 0xfb, 0x96, 0x1e, 0x9c, 0x2c, | ||
0x16, 0x5b, 0xd9, 0xdf, 0x14, 0xbc, 0x3c, 0x06, 0x38, 0x1b, 0xb2, 0x49, 0xf9, 0xe7, 0x7b, 0x57 | ||
}); | ||
|
||
#ifdef _MSC_VER | ||
inline __m128i operator^(__m128i a, __m128i b) { | ||
return _mm_xor_si128(a, b); | ||
} | ||
#endif | ||
|
||
inline bool eq(__m128i a, __m128i b) { | ||
auto v = a ^ b; | ||
return _mm_test_all_zeros(v, v); | ||
} | ||
|
||
std::vector<uint8_t> encrypt(std::span<const uint8_t> data, const std::array<uint8_t, 16>& key) { | ||
auto expandedKey1 = expandKey(key); | ||
auto _key = (__m128i*)expandedKey1.data(); | ||
|
||
auto length = data.size(); | ||
auto data_ = (__m128i*)data.data(); | ||
|
||
std::vector<uint8_t> out((length & (~0xF)) + ((length & 0xF) != 0) * 16 + 0x20); | ||
auto out_ptr = (__m128i*)out.data(); | ||
|
||
constexpr std::array<uint8_t, 16> iv = { 0xCE, 0x8F, 0xD3, 0x21, 0xD8, 0xFC, 0x28, 0x8A, 0xA5, 0xBC, 0xAE, 0xE3, 0x13, 0x47, 0xCC, 0x8D }; | ||
// todo: random generate iv | ||
*out_ptr = *(__m128i*)iv.data(); | ||
out_ptr++; | ||
|
||
auto step = [&](__m128i val) { | ||
val = val ^ _key[0]; | ||
for (int i = 1; i < 10; i++) { | ||
val = _mm_aesenc_si128(val, _key[i]); | ||
} | ||
*out_ptr = _mm_aesenclast_si128(val, _key[10]); | ||
out_ptr++; | ||
}; | ||
|
||
step(_key[0] ^ *(out_ptr - 1)); | ||
|
||
for (size_t i = 0; i < (length >> 4); i++) { | ||
step(data_[i] ^ *(out_ptr - 1)); | ||
} | ||
if ((length & 0xF) != 0) { | ||
std::array<uint8_t, 16> buf{0}; | ||
for (int i = 0; i < (length & 0xF); ++i) { | ||
buf[i] = data[(length & (~0xF)) + i]; | ||
} | ||
step(*(__m128i*)buf.data() ^ *(out_ptr - 1)); | ||
} | ||
|
||
return out; | ||
} | ||
|
||
bool decrypt(std::span<const uint8_t> data, const std::array<uint8_t, 16>& key, std::vector<uint8_t>& out) { | ||
auto expandedKey1 = expandKey(key); | ||
auto _key = (__m128i*)expandedKey1.data(); | ||
|
||
__m128i inv_key[9]; | ||
for (int i = 0; i < 9; ++i) { | ||
inv_key[i] = _mm_aesimc_si128(_key[i + 1]); | ||
} | ||
|
||
auto step = [&](__m128i val) { | ||
val = val ^ _key[10]; | ||
for (int i = 9; i > 0; i--) { | ||
val = _mm_aesdec_si128(val, inv_key[i - 1]); | ||
} | ||
return _mm_aesdeclast_si128(val, _key[0]); | ||
}; | ||
|
||
auto data_ = (__m128i*)data.data(); | ||
// first 16 bytes of decrypted data should be key again | ||
if (!eq((step(data_[1]) ^ data_[0]), _key[0])) | ||
return false; | ||
|
||
out.resize(data.size() - 0x20); | ||
auto out_ptr = (__m128i*)out.data(); | ||
|
||
auto len = ((data.size() & 0xf) != 0) + ((data.size() - 0x10) >> 4); | ||
for (int i = 1; i < len; i += 1) { | ||
out_ptr[i - 1] = step(data_[i + 1]) ^ data_[i]; | ||
} | ||
|
||
return true; | ||
} |
Oops, something went wrong.