From ec75402e24b7d043d015b0ee56537bf8d3f3c8e3 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 12:27:10 +0500 Subject: [PATCH 01/15] Fix building on Linux & create simple Makefile --- blkstuff/Makefile | 7 +++++++ blkstuff/main.cpp | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 blkstuff/Makefile diff --git a/blkstuff/Makefile b/blkstuff/Makefile new file mode 100644 index 0000000..d4695eb --- /dev/null +++ b/blkstuff/Makefile @@ -0,0 +1,7 @@ +CXX=g++ +LD=g++ +LIBS=-llz4 -lc +CXXFLAGS=-std=c++17 + +blkstuff: main.o util.o + $(LD) $(LIBS) $^ -o $@ diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 9b9ad5f..1988839 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -115,8 +115,8 @@ void mhy0_header_scramble2(uint8_t* a1) { // UnityPlayer:$152300 // TODO: more cleanup - __int64 v1; // r10 - unsigned __int8* v14; // rsi + int64_t v1; // r10 + uint8_t* v14; // rsi uint8_t v20_0[16]; uint8_t* v26; // [rsp+10h] [rbp-70h] uint8_t* v57; // [rsp+98h] [rbp+18h] @@ -406,4 +406,4 @@ int main(int argc, char** argv) { } else { extract_blk(argv[1], "output%d.bin"); } -} \ No newline at end of file +} From ee1fdd7cb4694b3847d6b08889b7f962ce5a0622 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 12:27:42 +0500 Subject: [PATCH 02/15] Updated .gitignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 9c1e6dc..a98348e 100644 --- a/.gitignore +++ b/.gitignore @@ -389,3 +389,13 @@ FodyWeavers.xsd # JetBrains Rider .idea/ *.sln.iml + +# Vim temp files +.*.swp +.*.swo + +# Object files +*.o + +# Linux binary +blkstuff/blkstuff From b3d12c62296867032cdadd5c94ca5bd99d50c5d2 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 13:02:24 +0500 Subject: [PATCH 03/15] printf => iostream, updated .gitignore --- .gitignore | 10 ------ blkstuff/main.cpp | 79 +++++++++++++++++++++++++---------------------- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index a98348e..9c1e6dc 100644 --- a/.gitignore +++ b/.gitignore @@ -389,13 +389,3 @@ FodyWeavers.xsd # JetBrains Rider .idea/ *.sln.iml - -# Vim temp files -.*.swp -.*.swo - -# Object files -*.o - -# Linux binary -blkstuff/blkstuff diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 1988839..38e252d 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include @@ -10,6 +10,8 @@ #include "util.h" #include "magic_constants.h" +using std::cout, std::endl, std::hex, std::dec; + // notes are from the genshin impact 1.5 dev build leak UnityEngine.dll (sha256 38399169552791bbfb7b3792dd3e91d3788067e29ffc2437f595060b051d2dd3) void key_scramble1(uint8_t* key) { @@ -29,7 +31,7 @@ uint8_t xor_combine(uint8_t* input) { void create_decrypt_vector(uint8_t* key, uint8_t* encrypted_data, uint64_t encrypted_size, uint8_t* output, uint64_t output_size) { if (output_size != 4096) { - printf("create_decrypt_vector does not support an output_size other than 4096\n"); + cout << "create_decrypt_vector does not support an output_size other than 4096" << endl; exit(1); } @@ -47,7 +49,7 @@ void create_decrypt_vector(uint8_t* key, uint8_t* encrypted_data, uint64_t encry auto* key_qword = (uint64_t*)key; // another magic constant, this time from blk_stuff2 uint64_t seed = key_qword[1] ^ 0x567BA22BABB08098 ^ i ^ key_qword[0]; - //printf("seed: 0x%llx\n", seed); + //cout << "seed: 0x" << hex << seed << endl; auto mt_rand = std::mt19937_64(seed); for (uint64_t i = 0; i < output_size >> 3; i++) @@ -153,7 +155,7 @@ void mhy0_header_scramble2(uint8_t* a1) void mhy0_header_scramble(uint8_t* input, uint64_t a2, uint8_t* input2, uint64_t a4) { if (!((a2 == 0x39 && a4 == 0x1C) || (a2 == 0x21 && a4 == 8))) { - printf("unsupported parameters for mhy0_header_scramble\n"); + cout << "unsupported parameters for mhy0_header_scramble" << endl; exit(1); } @@ -185,16 +187,16 @@ void mhy0_extract(const char* out_format, int block_index, uint8_t* input, size_ // loosely based on UnityPlayer:$1C64C0 // TODO: bounds checks if (*(uint32_t*)input != 0x3079686D) { // mhy0 - printf("decrypted data didn't start with mhy0, so decryption probably failed\n"); + cout << "decrypted data didn't start with mhy0, so decryption probably failed" << endl; exit(1); } uint32_t size = *(uint32_t*)(input + 4); - //printf("first size 0x%x\n", size); + //cout << "first size 0x" << std::hex << size << endl; if (size > input_size) { // TODO: this is probably caused by the awful mhy0 searching approach i do instead of properly calculating offsets - printf("oh shit! attempted to get 0x%x bytes out of a 0x%llx input! skipping mhy0 %d...", size, input_size, block_index); + cout << "oh shit! attempted to get 0x" << hex << size << " bytes out of a 0x" << hex << input_size << " input! skipping mhy0 " << dec << block_index << endl; return; } @@ -212,48 +214,48 @@ void mhy0_extract(const char* out_format, int block_index, uint8_t* input, size_ // TODO: there is a different path for calculating this, so this might mess up on some inputs //uint32_t decomp_size = MAKE_UINT32(data[0x20 + 1], data[0x20 + 6], data[0x20 + 3], data[0x20 + 2]); uint32_t decomp_size = MAKE_UINT32(data, 0x20 + 1, 0x20 + 6, 0x20 + 3, 0x20 + 2); - //printf("decompressed size: 0x%x\n", decomp_size); + //cout << "decompressed size: 0x" << hex << decomp_size << endl; uint8_t* decomp_output = new uint8_t[decomp_size]; auto lz4_res = LZ4_decompress_safe((const char*)(data + 0x27), (char*)decomp_output, size - 0x27, decomp_size); if (lz4_res < 0) { - printf("decompression failed: %d\n", lz4_res); + cout << "decompression failed: " << lz4_res << endl; exit(1); } delete[] data; //dump_to_file("mhy0_header.bin", decomp_output, decomp_size); - //printf("next data cmp size: 0x%x\n", MAKE_UINT32(decomp_output, 0x11F + 2, 0x11F + 4, 0x11F, 0x11F + 5)); - //printf("next data decmp size: 0x%x\n", MAKE_UINT32(decomp_output, 0x112 + 1, 0x112 + 6, 0x112 + 3, 0x112 + 2)); - //printf("unknown 1: 0x%x\n", MAKE_UINT32(decomp_output, 0x10C + 2, 0x10C + 4, 0x10C, 0x10C + 5)); + //cout << "next data cmp size: 0x" << hex << MAKE_UINT32(decomp_output, 0x11F + 2, 0x11F + 4, 0x11F, 0x11F + 5) << endl; + //cout << "next data decmp size: 0x" << hex << MAKE_UINT32(decomp_output, 0x112 + 1, 0x112 + 6, 0x112 + 3, 0x112 + 2) << endl; + //cout << "unknown 1: 0x" << hex << MAKE_UINT32(decomp_output, 0x10C + 2, 0x10C + 4, 0x10C, 0x10C + 5) << endl; auto cab_count = MAKE_UINT32(decomp_output, 2, 4, 0, 5); - //printf("cab count: 0x%x\n", cab_count); + //cout << "cab count: 0x" << hex << cab_count << endl; //auto entry_count = MAKE_UINT32(decomp_output, 0x119 + 2, 0x119 + 4, 0x119, 0x119 + 5); auto entry_count = MAKE_UINT32(decomp_output, cab_count * 0x113 + 6 + 2, cab_count * 0x113 + 6 + 4, cab_count * 0x113 + 6, cab_count * 0x113 + 6 + 5); - //printf("entry count: 0x%x\n", entry_count); + //cout << "entry count: 0x" << hex << entry_count << endl; //dump_to_file("bruh.bin", decomp_output, decomp_size); //hexdump("asdf", decomp_output, decomp_size); //exit(1); //if (entry_count > 0x10000) { //hexdump("wtf???? something probably went wrong!", decomp_output, decomp_size); - //printf("0x%x\n", MAKE_UINT32(decomp_output, 2, 4, 0, 5)); + //cout << "0x" << hex << MAKE_UINT32(decomp_output, 2, 4, 0, 5) << endl; //exit(1); //} uint8_t* entry_ptr = input + 0x8 + size; char filename[0x100] = {}; - //printf("%s\n", out_format); + //cout << out_format << endl; snprintf(filename, sizeof(filename), out_format, block_index); auto* output = fopen(filename, "wb"); if (!output) { - printf("failed to open %s\n", filename); + cout << "failed to open " << filename << endl; exit(1); } for (int i = 0; i < entry_count; i++) { - //printf("processing entry %d\n", i); + //cout << "processing entry " << i << endl; auto offset = i * 13 + cab_count * 0x113 + 6; auto entry_cmp_size = MAKE_UINT32(decomp_output, offset + 6 + 2, offset + 6 + 4, offset + 6, offset + 6 + 5); auto entry_decmp_size = MAKE_UINT32(decomp_output, offset + 0xC + 1, offset + 0xC + 6, offset + 0xC + 3, offset + 0xC + 2); - //printf("%x\n", entry_cmp_size); + //cout << hex << entry_cmp_size << endl; //hexdump("initial data", entry_ptr, entry_cmp_size); mhy0_header_scramble(entry_ptr, 0x21, entry_ptr + 4, 8); //hexdump("data after scramble", entry_ptr, entry_cmp_size); @@ -261,7 +263,7 @@ void mhy0_extract(const char* out_format, int block_index, uint8_t* input, size_ auto* entry_decmp = new uint8_t[entry_decmp_size]; auto lz4_res = LZ4_decompress_safe((const char*)(entry_ptr + 0xC), (char*)entry_decmp, entry_cmp_size - 0xC, entry_decmp_size); if (lz4_res < 0) { - printf("decompression failed: %d\n", lz4_res); + cout << "decompression failed: " << lz4_res << endl; exit(1); } //dump_to_file(filename, entry_decmp, entry_decmp_size); @@ -279,7 +281,7 @@ int extract_blk(char* in_filename, const char* out_format) { //auto* blk_file = fopen("D:\\Games\\Genshin Impact\\Genshin Impact game\\GenshinImpact_Data\\StreamingAssets\\VideoAssets\\26236578.blk", "rb"); auto* blk_file = fopen(in_filename, "rb"); if (!blk_file) { - printf("failed to open blk\n"); + cout << "failed to open blk" << endl; return 1; } @@ -287,7 +289,7 @@ int extract_blk(char* in_filename, const char* out_format) { uint32_t magic = 0; fread(&magic, 4, 1, blk_file); if (magic != 0x6B6C62) { // blk\x00 - printf("bad file magic"); + cout << "bad file magic" << endl; return 1; } } @@ -296,7 +298,7 @@ int extract_blk(char* in_filename, const char* out_format) { uint32_t unk1 = 0; fread(&unk1, 4, 1, blk_file); if (unk1 != 0x10) { - printf("unk1 is not 0x10"); + cout << "unk1 is not 0x10" << endl; return 1; } } @@ -316,7 +318,7 @@ int extract_blk(char* in_filename, const char* out_format) { uint16_t block_size = 0; fread(&block_size, sizeof(block_size), 1, blk_file); - //printf("0x%x\n", block_size); + //cout << "0x" << hex << block_size << endl; fseek(blk_file, 0, SEEK_END); size_t size = ftell(blk_file); @@ -351,7 +353,7 @@ int extract_blk(char* in_filename, const char* out_format) { if (res) { auto loc = (uint8_t*)res - data; mhy0_locs.push_back(loc); - //printf("found mhy0 at 0x%llx\n", loc); + //cout << "found mhy0 at 0x" << hex << loc << endl; mhy0_extract(out_format, i, data + loc, size); last_loc = loc + 4; } else { @@ -362,46 +364,49 @@ int extract_blk(char* in_filename, const char* out_format) { //mhy0_extract(data, size); delete[] data; + + return 0; } int main(int argc, char** argv) { if (argc < 2) { - printf("you need an input file\n"); + cout << "you need an input file" << endl; return 1; } if (!strcmp(argv[1], "batch")) { if (argc < 4) { - printf("you need input and output folders for batch mode\n"); + cout << "you need input and output folders for batch mode" << endl; return 1; } auto base_path = std::filesystem::path(argv[2]); std::vector blk_paths; - printf("scanning for blks\n"); + cout << "scanning for blks" << endl; try { for (auto& p : std::filesystem::recursive_directory_iterator(base_path)) { if (p.path().extension() == ".blk") - //printf("%ws\n", p.path().lexically_relative(base_path).c_str()); + //cout << p.path().lexically_relative(base_path) << endl; blk_paths.push_back(p.path().lexically_relative(base_path)); } } catch (const std::exception& e) { - printf("failed to search for blk files with error: %s\n", e.what()); + cout << "failed to search for blk files with error: " << e.what() << endl; return 1; } - printf("found %llu blks to extract\n", blk_paths.size()); + cout << "found " << blk_paths.size() << " blks to extract" << endl; auto output_base = std::filesystem::path(argv[3]); for (auto& p : blk_paths) { - printf("processing %ws...", p.c_str()); + cout << "processing " << p << "... "; auto input_path = base_path / p; auto output_path = (output_base / p).replace_extension(".%d.bin"); auto output_dir = std::filesystem::path(output_path).remove_filename(); - //printf("%ws\n", output_path.c_str()); + //cout << output_path << endl; std::filesystem::create_directories(output_dir); - extract_blk((char*)input_path.generic_string().c_str(), output_path.generic_string().c_str()); + int ret = extract_blk((char*)input_path.generic_string().c_str(), output_path.generic_string().c_str()); - printf("ok\n"); + if (!ret) + cout << "ok" << endl; } } else { extract_blk(argv[1], "output%d.bin"); From 49653c824075524edfdcff49f6e4707969841209 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 13:20:50 +0500 Subject: [PATCH 04/15] Lord's way of doing things in parallel --- blkstuff/Makefile | 7 +++++-- blkstuff/main.cpp | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/blkstuff/Makefile b/blkstuff/Makefile index d4695eb..264b36d 100644 --- a/blkstuff/Makefile +++ b/blkstuff/Makefile @@ -1,7 +1,10 @@ CXX=g++ LD=g++ -LIBS=-llz4 -lc -CXXFLAGS=-std=c++17 +LIBS=-llz4 -lc -lomp +CXXFLAGS=-std=c++17 -fopenmp -Wall -Wextra blkstuff: main.o util.o $(LD) $(LIBS) $^ -o $@ + +clean: + -rm main.o util.o blkstuff diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 38e252d..7b9f308 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -395,7 +395,10 @@ int main(int argc, char** argv) { cout << "found " << blk_paths.size() << " blks to extract" << endl; auto output_base = std::filesystem::path(argv[3]); - for (auto& p : blk_paths) { + //for (auto& p : blk_paths) { + #pragma omp parallel for + for (int i = 0; i < blk_paths.size(); i++) { + auto p = blk_paths[i]; cout << "processing " << p << "... "; auto input_path = base_path / p; From 51f64932729ee8f7802a9d310cb374c562bac34a Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 13:22:05 +0500 Subject: [PATCH 05/15] Updated .gitignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 9c1e6dc..a98348e 100644 --- a/.gitignore +++ b/.gitignore @@ -389,3 +389,13 @@ FodyWeavers.xsd # JetBrains Rider .idea/ *.sln.iml + +# Vim temp files +.*.swp +.*.swo + +# Object files +*.o + +# Linux binary +blkstuff/blkstuff From 85a05e7ad063380c80cb321d5392fb619de3fce9 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 22:53:04 +0500 Subject: [PATCH 06/15] Improve readability of the code --- blkstuff/magic_constants.h | 20 +++++++++--- blkstuff/main.cpp | 62 ++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/blkstuff/magic_constants.h b/blkstuff/magic_constants.h index 1fe7aa3..268eef6 100644 --- a/blkstuff/magic_constants.h +++ b/blkstuff/magic_constants.h @@ -1044,7 +1044,7 @@ const uint8_t blk_stuff1_p7[] = { 0x58,0x00,0xA1, }; -const uint8_t mhy0_table1[] = { +const uint8_t gf256_exp[] = { 0x01,0x03,0x05,0x0F,0x11,0x33,0x55,0xFF,0x1A,0x2E,0x72, 0x96,0xA1,0xF8,0x13,0x35,0x5F,0xE1,0x38,0x48,0xD8,0x73, 0x95,0xA4,0xF7,0x02,0x06,0x0A,0x1E,0x22,0x66,0xAA,0xE5, @@ -1068,11 +1068,13 @@ const uint8_t mhy0_table1[] = { 0xC6,0x51,0xF3,0x0E,0x12,0x36,0x5A,0xEE,0x29,0x7B,0x8D, 0x8C,0x8F,0x8A,0x85,0x94,0xA7,0xF2,0x0D,0x17,0x39,0x4B, 0xDD,0x7C,0x84,0x97,0xA2,0xFD,0x1C,0x24,0x6C,0xB4,0xC7, - 0x52,0xF6,0xC5, + //0x52,0xF6,0xC5, // Shouldn't really matter as in GF256 exp(255) = exp(0) and 255'th element of the table is unused + 0x52,0xF6,0x01, }; -const uint8_t mhy0_table2[] = { - 0x3E,0x00,0x19,0x01,0x32,0x02,0x1A,0xC6,0x4B,0xC7,0x1B, +const uint8_t gf256_log[] = { + //0x3E,0x00,0x19,0x01,0x32,0x02,0x1A,0xC6,0x4B,0xC7,0x1B, // Shouldn't really matter as log(0) is undefined and 0'th element of the table is unused + 0x00,0x00,0x19,0x01,0x32,0x02,0x1A,0xC6,0x4B,0xC7,0x1B, 0x68,0x33,0xEE,0xDF,0x03,0x64,0x04,0xE0,0x0E,0x34,0x8D, 0x81,0xEF,0x4C,0x71,0x08,0xC8,0xF8,0x69,0x1C,0xC1,0x7D, 0xC2,0x1D,0xB5,0xF9,0xB9,0x27,0x6A,0x4D,0xE4,0xA6,0x72, @@ -1096,4 +1098,12 @@ const uint8_t mhy0_table2[] = { 0x89,0xB4,0x7C,0xB8,0x26,0x77,0x99,0xE3,0xA5,0x67,0x4A, 0xED,0xDE,0xC5,0x31,0xFE,0x18,0x0D,0x63,0x8C,0x80,0xC0, 0xF7,0x70,0x07, -}; \ No newline at end of file +}; + +static inline uint8_t gf256_mul(uint8_t a, uint8_t b) +{ + if (a == 0 || b == 0) + return 0; + + return gf256_exp[(gf256_log[a] + gf256_log[b]) % 255]; +} diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 7b9f308..ace6f55 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -113,73 +113,75 @@ void key_scramble2(uint8_t* key) { key[i] = xor_combine(&expanded_key[16 * i]); } -void mhy0_header_scramble2(uint8_t* a1) +void mhy0_header_scramble2(uint8_t* input) { // UnityPlayer:$152300 // TODO: more cleanup - int64_t v1; // r10 - uint8_t* v14; // rsi - uint8_t v20_0[16]; - uint8_t* v26; // [rsp+10h] [rbp-70h] - uint8_t* v57; // [rsp+98h] [rbp+18h] + uint8_t* ptr; // rsi + uint8_t tmp[16]; - v26 = a1; uint8_t mhy0_index_scramble[] = { 0x0B,0x02,0x08,0x0C,0x01,0x05,0x00,0x0F,0x06,0x07,0x09,0x03,0x0D,0x04,0x0E,0x0A, 0x04,0x05,0x07,0x0A,0x02,0x0F,0x0B,0x08,0x0E,0x0D,0x09,0x06,0x0C,0x03,0x00,0x01, 0x08,0x00,0x0C,0x06,0x04,0x0B,0x07,0x09,0x05,0x03,0x0F,0x01,0x0D,0x0A,0x02,0x0E, }; - uint8_t v20_1[] = { + + uint8_t smol_key[] = { 0x48, 0x14, 0x36, 0xED, 0x8E, 0x44, 0x5B, 0xB6 }; + uint8_t v25[] = { 0xA7, 0x99, 0x66, 0x50, 0xB9, 0x2D, 0xF0, 0x78 }; - for (int v17 = 0; v17 < 3; v17++) + + for (int k = 0; k < 3; k++) { for (int i = 0; i < 16; ++i) - v20_0[i] = v26[mhy0_index_scramble[32 + -16 * v17 + i]]; - memcpy(v26, v20_0, 16); + tmp[i] = input[mhy0_index_scramble[(2 - k)*16 + i]]; + + memcpy(input, tmp, 16); + for (int j = 0; j < 16; ++j) { - v57 = v20_1; - v14 = &v26[j]; - v1 = j % 8; - if (*v14 == 0 || !v25[v1]) - *v14 = key_scramble_table1[j % 4 * 256] ^ v57[j % 8]; - else - *v14 = v57[v1] ^ key_scramble_table1[j % 4 * 256 | mhy0_table1[(mhy0_table2[v25[v1]] + mhy0_table2[*v14]) % 255]]; + ptr = &input[j]; + int idx = j % 8; + + *ptr = smol_key[idx] ^ key_scramble_table1[j % 4 * 256 | gf256_mul(v25[idx], *ptr)]; } } } -void mhy0_header_scramble(uint8_t* input, uint64_t a2, uint8_t* input2, uint64_t a4) { - if (!((a2 == 0x39 && a4 == 0x1C) || (a2 == 0x21 && a4 == 8))) { +void mhy0_header_scramble(uint8_t* input, uint64_t limit, uint8_t* input2, uint64_t chunk_size) { + if (!((limit == 0x39 && chunk_size == 0x1C) || (limit == 0x21 && chunk_size == 8))) { cout << "unsupported parameters for mhy0_header_scramble" << endl; exit(1); } // UnityPlayer:$151090 // TODO: reimplement this properly instead of copy and pasting from decomp - int v10 = (a4 + 15) & 0xFFFFFFF0; - for (int i = 0; i < v10; i += 16) + int rounded_size = (chunk_size + 15) & 0xFFFFFFF0; + + for (int i = 0; i < rounded_size; i += 16) mhy0_header_scramble2(&input[i + 4]); + for (int j = 0; j < 4; j++) input[j] ^= input2[j]; - uint64_t v8 = (uint64_t)v10 + 4; - int v13 = 0; - while (v8 < a2 && !v13) + + uint64_t total_rounded_size = (uint64_t)rounded_size + 4; + + bool finished = false; + while (total_rounded_size < limit && !finished) { - for (int k = 0; k < a4; ++k) + for (int k = 0; k < chunk_size; ++k) { - input[k + v8] ^= input2[k]; - if (k + v8 >= a2 - 1) + input[k + total_rounded_size] ^= input2[k]; + if (k + total_rounded_size >= limit - 1) { - v13 = 1; + finished = true; break; } } - v8 += a4; + total_rounded_size += chunk_size; } } From 15965d9f265dad9db352136a77f951a1190b9e1b Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 23:02:37 +0500 Subject: [PATCH 07/15] Enable optimizations in Linux build --- blkstuff/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blkstuff/Makefile b/blkstuff/Makefile index 264b36d..0080225 100644 --- a/blkstuff/Makefile +++ b/blkstuff/Makefile @@ -1,7 +1,7 @@ CXX=g++ LD=g++ LIBS=-llz4 -lc -lomp -CXXFLAGS=-std=c++17 -fopenmp -Wall -Wextra +CXXFLAGS=-O2 -std=c++17 -fopenmp -Wall -Wextra blkstuff: main.o util.o $(LD) $(LIBS) $^ -o $@ From fbee0b3b46f07a35c70fcb9b4f0456d7909100fb Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Aug 2021 23:12:48 +0500 Subject: [PATCH 08/15] Improve readability again --- blkstuff/main.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index ace6f55..a0e12d7 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -36,19 +36,15 @@ void create_decrypt_vector(uint8_t* key, uint8_t* encrypted_data, uint64_t encry } // TODO: reimplement this properly instead of copy and pasting from decomp - int v9 = 0; - int64_t i; - int64_t v12; - for (i = -1; ; i = v12) { - if (v9 >= (int)(encrypted_size >> 3)) - break; - v12 = ((uint64_t*)encrypted_data)[v9] ^ i; - ++v9; + uint64_t val = 0xFFFFFFFFFFFFFFFF; + + for (int i = 0; i < encrypted_size >> 3; i++) { + val = ((uint64_t*)encrypted_data)[i] ^ val; } auto* key_qword = (uint64_t*)key; // another magic constant, this time from blk_stuff2 - uint64_t seed = key_qword[1] ^ 0x567BA22BABB08098 ^ i ^ key_qword[0]; + uint64_t seed = key_qword[1] ^ 0x567BA22BABB08098 ^ val ^ key_qword[0]; //cout << "seed: 0x" << hex << seed << endl; auto mt_rand = std::mt19937_64(seed); From 4d42cec16b667747b740293d134d5bfce49bb912 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 12:09:24 +0500 Subject: [PATCH 09/15] Comment --- blkstuff/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index a0e12d7..d494209 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -64,6 +64,7 @@ void key_scramble2(uint8_t* key) { expanded_key[i] ^= blk_stuff1_p1[i] ^ stack_stuff[i]; // should probably be in magic_constants.h, but it's very small + // that's a lookup table for row shifts in AES, motherfucker const uint8_t index_scramble[16] = { 0, 13, 10, 7, 4, 1, 14, 11, From f6c251f2618ff0d4455c94922fdc07232cf689be Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 13:18:42 +0500 Subject: [PATCH 10/15] Simplify header_scramble2 --- blkstuff/main.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index d494209..5e884cb 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -113,8 +113,6 @@ void key_scramble2(uint8_t* key) { void mhy0_header_scramble2(uint8_t* input) { // UnityPlayer:$152300 - // TODO: more cleanup - uint8_t* ptr; // rsi uint8_t tmp[16]; uint8_t mhy0_index_scramble[] = { @@ -133,18 +131,15 @@ void mhy0_header_scramble2(uint8_t* input) for (int k = 0; k < 3; k++) { - for (int i = 0; i < 16; ++i) - tmp[i] = input[mhy0_index_scramble[(2 - k)*16 + i]]; - - memcpy(input, tmp, 16); - for (int j = 0; j < 16; ++j) { - ptr = &input[j]; + int i = mhy0_index_scramble[(2 - k)*16 + j]; + int idx = j % 8; - *ptr = smol_key[idx] ^ key_scramble_table1[j % 4 * 256 | gf256_mul(v25[idx], *ptr)]; + tmp[j] = smol_key[idx] ^ key_scramble_table1[j % 4 * 256 | gf256_mul(v25[idx], input[i])]; } + memcpy(input, tmp, 16); } } From 71e4ebb180f741b28584f5a07765f06a2476fd1f Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 14:39:43 +0500 Subject: [PATCH 11/15] Comment --- blkstuff/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 5e884cb..7e783cd 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -150,7 +150,6 @@ void mhy0_header_scramble(uint8_t* input, uint64_t limit, uint8_t* input2, uint6 } // UnityPlayer:$151090 - // TODO: reimplement this properly instead of copy and pasting from decomp int rounded_size = (chunk_size + 15) & 0xFFFFFFF0; for (int i = 0; i < rounded_size; i += 16) From 7be2922a69662467bb5e1f8cb96f7a517c0b1ef9 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 17:32:55 +0500 Subject: [PATCH 12/15] Some intermediate state, just for the history --- blkstuff/main.cpp | 211 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 7e783cd..7f198f0 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -52,7 +52,195 @@ void create_decrypt_vector(uint8_t* key, uint8_t* encrypted_data, uint64_t encry ((uint64_t*)output)[i] = mt_rand(); } +void add_round_key(uint8_t* data, const uint8_t* round_keys, int round) +{ + for (int i = 0; i < 16; i++) + data[i] ^= round_keys[round * 16 + i]; +} + +void try_expand_round_keys(uint8_t* round_keys, const uint8_t* seed) +{ + int N = 4; + + static const uint8_t lookup_rcon[] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a}; + + static const uint8_t lookup_sbox[] = { + 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 lookup_sbox_inv[] = { + 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}; + + auto rot_word = [](uint32_t word) { + //return (word << 8) | ((word >> 24) & 0x000000FF); + return (word >> 8) | ((word << 24) & 0xFF000000); + }; + + auto sub_word = [](uint32_t word) { + return + lookup_sbox[ word & 0xFF] | + lookup_sbox[(word >> 8) & 0xFF] << 8 | + lookup_sbox[(word >> 16) & 0xFF] << 16 | + lookup_sbox[(word >> 24) & 0xFF] << 24 ; + }; + + for (int i = 0; i < 16; i++) + round_keys[i] = seed[i]; + + uint32_t* round_key_words = (uint32_t*)round_keys; + + for (int i = N; i < N*11; i++) + { + if (i % N == 0) + { + round_key_words[i] = round_key_words[i-N] ^ sub_word(rot_word(round_key_words[i-1])) ^ (lookup_rcon[i/N]); + } else { + round_key_words[i] = round_key_words[i-N] ^ round_key_words[i-1]; + } + } + + for (int round = 0; round <= 10; round++) + { + hexdump("Derived round key: ", round_keys + round*16, 16); + } +} + +void kinda_expand_round_keys(uint8_t* round_keys) +{ + // First round key + int round = 0; + + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) + { + uint64_t idx = (round << 8) + (i*16) + j; + round_keys[round * 16 + i] ^= blk_stuff1_p1[idx] ^ stack_stuff[idx]; + } + + // Round keys 1-9 + for (round = 1; round < 10; round++) + { + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) + { + uint64_t idx = (round << 8) + (i*16) + j; + round_keys[round * 16 + i] ^= blk_stuff1_p1[idx] ^ stack_stuff[idx]; + } + } + + // Round key 10 + round = 10; + + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) + { + uint64_t idx = (round << 8) + (i*16) + j; + round_keys[round * 16 + i] ^= blk_stuff1_p7[i * 16 + j] ^ stack_stuff[idx]; // Note the different index for blk_stuff_p7 + } + + for (int round = 0; round <= 10; round++) + { + hexdump("Round key: ", round_keys + round*16, 16); + } +} + +// This function is not exported, so hackaround it +extern "C" void oqs_aes128_enc_c(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext); + void key_scramble2(uint8_t* key) { + uint8_t round_keys[11*16] = {0}; + + kinda_expand_round_keys(round_keys); + + uint8_t chip[16]; + + oqs_aes128_enc_c(key, round_keys, chip); + + memcpy(key, chip, 16); +} + +// Rewritten +void _key_scramble2(uint8_t* key) { + uint8_t round_keys[11*16] = {0}; + + kinda_expand_round_keys(round_keys); + + const uint8_t index_scramble[16] = { + 0, 13, 10, 7, + 4, 1, 14, 11, + 8, 5, 2, 15, + 12, 9, 6, 3 + }; + + hexdump("Initial data: ", key, 16); + + add_round_key(key, round_keys, 0); + + for (uint64_t round = 1; round < 10; round++) { + + // Here sub_bytes, shift_rows and mix_columns are fused together + uint32_t scratch[4] = {}; + for (uint64_t j = 0; j < 4; j++) { + uint8_t temp = 0; + + temp = key[index_scramble[4 * j + 0]]; + scratch[j] ^= ((uint32_t*)blk_stuff1_p2)[temp]; + + temp = key[index_scramble[4 * j + 1]]; + scratch[j] ^= ((uint32_t*)blk_stuff1_p3)[temp]; + + temp = key[index_scramble[4 * j + 2]]; + scratch[j] ^= ((uint32_t*)blk_stuff1_p4)[temp]; + + temp = key[index_scramble[4 * j + 3]]; + scratch[j] ^= ((uint32_t*)blk_stuff1_p5)[temp]; + } + memcpy(key, scratch, 16); + add_round_key(key, round_keys, round); + } + + uint8_t scratch[16] = {}; + // Last round don't have mix_columns step, only sub_bytes and shift_rows + for (int i = 0; i < 16; i++) { + uint8_t t = key[index_scramble[i]]; + scratch[i] = blk_stuff1_p6[t] ^ ~t; + } + memcpy(key, scratch, 16); + add_round_key(key, round_keys, 10); + + hexdump("Final data: ", key, 16); +} + +void __key_scramble2(uint8_t* key) { // UnityPlayer:$26EA90 uint8_t expanded_key[256] = {}; @@ -362,6 +550,29 @@ int extract_blk(char* in_filename, const char* out_format) { } int main(int argc, char** argv) { + #if 0 + uint32_t box[256] = {0}; + for (int i = 0; i < 256; i++) { + box[i] = + ((uint32_t*)blk_stuff1_p2)[i] ^ + ((uint32_t*)blk_stuff1_p3)[i] ^ + ((uint32_t*)blk_stuff1_p4)[i] ^ + ((uint32_t*)blk_stuff1_p5)[i] ; + } + hexdump("Box: ", (uint8_t*)box, 256*4); + exit(0); + #endif + + #if 0 + uint8_t round_keys[11*16] = {0}; + uint8_t seed[] = {0x54, 0x2f, 0xed, 0x67, 0x5d, 0xdd, 0x11, 0x2e, 0xb7, 0x40, 0x13, 0xe3, 0x29, 0xab, 0x6d, 0x28}; + + try_expand_round_keys(round_keys, seed); + memset(round_keys, 0, 11*16); + kinda_expand_round_keys(round_keys); + exit(0); + #endif + if (argc < 2) { cout << "you need an input file" << endl; return 1; From fb9de91bed705f6bd21295e77f9e7e9e41078f2a Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 17:54:30 +0500 Subject: [PATCH 13/15] Throw out decompiled code and use public domain AES library (Chris Hulbert - chris.hulbert@gmail.com) --- blkstuff/Makefile | 3 +- blkstuff/aes.c | 340 ++++++++++++++++++++++++++++++ blkstuff/aes.h | 66 ++++++ blkstuff/magic_constants.h | 419 +------------------------------------ blkstuff/main.cpp | 173 +-------------- 5 files changed, 420 insertions(+), 581 deletions(-) create mode 100644 blkstuff/aes.c create mode 100644 blkstuff/aes.h diff --git a/blkstuff/Makefile b/blkstuff/Makefile index 0080225..15adc77 100644 --- a/blkstuff/Makefile +++ b/blkstuff/Makefile @@ -2,8 +2,9 @@ CXX=g++ LD=g++ LIBS=-llz4 -lc -lomp CXXFLAGS=-O2 -std=c++17 -fopenmp -Wall -Wextra +CFLAGS=-O2 -std=c17 -fopenmp -Wall -Wextra -blkstuff: main.o util.o +blkstuff: main.o util.o aes.o $(LD) $(LIBS) $^ -o $@ clean: diff --git a/blkstuff/aes.c b/blkstuff/aes.c new file mode 100644 index 0000000..553b4d1 --- /dev/null +++ b/blkstuff/aes.c @@ -0,0 +1,340 @@ +// Simple, thoroughly commented implementation of 128-bit AES / Rijndael using C +// Chris Hulbert - chris.hulbert@gmail.com - http://splinter.com.au/blog +// References: +// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard +// http://en.wikipedia.org/wiki/Rijndael_key_schedule +// http://en.wikipedia.org/wiki/Rijndael_mix_columns +// http://en.wikipedia.org/wiki/Rijndael_S-box +// This code is public domain, or any OSI-approved license, your choice. No warranty. + +#include +#include +#include + +#include "aes.h" + +typedef unsigned char byte; + +// Here are all the lookup tables for the row shifts, rcon, s-boxes, and galois field multiplications +static const byte shift_rows_table[] = {0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11}; +static const byte shift_rows_table_inv[] = {0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3}; +static const byte lookup_rcon[] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a}; +static const byte lookup_sbox[] = { + 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 byte lookup_sbox_inv[] = { + 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 byte lookup_g2[] = { + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, + 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, + 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, + 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, + 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, + 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, + 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5}; +static const byte lookup_g3[] = { + 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, + 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, + 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, + 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, + 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, + 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, + 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, + 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, + 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, + 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, + 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, + 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, + 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a}; +static const byte lookup_g9[] = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, + 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, + 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, + 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, + 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, + 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, + 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, + 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, + 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, + 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, + 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, + 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, + 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46}; +static const byte lookup_g11[] = { + 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, + 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, + 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, + 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, + 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, + 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, + 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, + 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, + 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, + 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, + 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, + 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, + 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, + 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, + 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, + 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3}; +static const byte lookup_g13[] = { + 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, + 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, + 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, + 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, + 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, + 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, + 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, + 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, + 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, + 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, + 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, + 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, + 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, + 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, + 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, + 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97}; +static const byte lookup_g14[] = { + 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, + 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, + 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, + 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, + 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, + 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, + 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, + 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, + 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, + 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, + 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, + 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, + 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, + 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, + 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, + 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d}; + +// Xor's all elements in a n byte array a by b +static void xor (byte * a, const byte *b, int n) { + int i; + for (i = 0; i < n; i++) { + a[i] ^= b[i]; + } +} + + // Xor the current cipher state by a specific round key + static void xor_round_key(byte *state, const byte *keys, int round) { + xor(state, keys + round * 16, 16); +} + +// Apply the rijndael s-box to all elements in an array +// http://en.wikipedia.org/wiki/Rijndael_S-box +static void sub_bytes(byte *a, int n) { + int i; + for (i = 0; i < n; i++) { + a[i] = lookup_sbox[a[i]]; + } +} +static void sub_bytes_inv(byte *a, int n) { + int i; + for (i = 0; i < n; i++) { + a[i] = lookup_sbox_inv[a[i]]; + } +} + +// Perform the core key schedule transform on 4 bytes, as part of the key expansion process +// http://en.wikipedia.org/wiki/Rijndael_key_schedule#Key_schedule_core +static void key_schedule_core(byte *a, int i) { + byte temp = a[0]; // Rotate the output eight bits to the left + a[0] = a[1]; + a[1] = a[2]; + a[2] = a[3]; + a[3] = temp; + sub_bytes(a, 4); // Apply Rijndael's S-box on all four individual bytes in the output word + a[0] ^= lookup_rcon[i]; // On just the first (leftmost) byte of the output word, perform the rcon operation with i + // as the input, and exclusive or the rcon output with the first byte of the output word +} + +// Expand the 16-byte key to 11 round keys (176 bytes) +// http://en.wikipedia.org/wiki/Rijndael_key_schedule#The_key_schedule +void oqs_aes128_load_schedule_c(const uint8_t *key, void **_schedule) { + *_schedule = malloc(16 * 11); + assert(*_schedule != NULL); + uint8_t *schedule = (uint8_t *) *_schedule; + int bytes = 16; // The count of how many bytes we've created so far + int i = 1; // The rcon iteration value i is set to 1 + int j; // For repeating the second stage 3 times + byte t[4]; // Temporary working area known as 't' in the Wiki article + memcpy(schedule, key, 16); // The first 16 bytes of the expanded key are simply the encryption key + + while (bytes < 176) { // Until we have 176 bytes of expanded key, we do the following: + memcpy(t, schedule + bytes - 4, 4); // We assign the value of the previous four bytes in the expanded key to t + key_schedule_core(t, i); // We perform the key schedule core on t, with i as the rcon iteration value + i++; // We increment i by 1 + xor(t, schedule + bytes - 16, 4); // We exclusive-or t with the four-byte block 16 bytes before the new expanded key. + memcpy(schedule + bytes, t, 4); // This becomes the next 4 bytes in the expanded key + bytes += 4; // Keep track of how many expanded key bytes we've added + + // We then do the following three times to create the next twelve bytes + for (j = 0; j < 3; j++) { + memcpy(t, schedule + bytes - 4, 4); // We assign the value of the previous 4 bytes in the expanded key to t + xor(t, schedule + bytes - 16, 4); // We exclusive-or t with the four-byte block n bytes before + memcpy(schedule + bytes, t, 4); // This becomes the next 4 bytes in the expanded key + bytes += 4; // Keep track of how many expanded key bytes we've added + } + } +} + +void oqs_aes128_free_schedule_c(void *schedule) { + if (schedule != NULL) { + free(schedule); + } +} + +// Apply the shift rows step on the 16 byte cipher state +// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard#The_ShiftRows_step +static void shift_rows(byte *state) { + int i; + byte temp[16]; + memcpy(temp, state, 16); + for (i = 0; i < 16; i++) { + state[i] = temp[shift_rows_table[i]]; + } +} +static void shift_rows_inv(byte *state) { + int i; + byte temp[16]; + memcpy(temp, state, 16); + for (i = 0; i < 16; i++) { + state[i] = temp[shift_rows_table_inv[i]]; + } +} + +// Perform the mix columns matrix on one column of 4 bytes +// http://en.wikipedia.org/wiki/Rijndael_mix_columns +static void mix_col(byte *state) { + byte a0 = state[0]; + byte a1 = state[1]; + byte a2 = state[2]; + byte a3 = state[3]; + state[0] = lookup_g2[a0] ^ lookup_g3[a1] ^ a2 ^ a3; + state[1] = lookup_g2[a1] ^ lookup_g3[a2] ^ a3 ^ a0; + state[2] = lookup_g2[a2] ^ lookup_g3[a3] ^ a0 ^ a1; + state[3] = lookup_g2[a3] ^ lookup_g3[a0] ^ a1 ^ a2; +} + +// Perform the mix columns matrix on each column of the 16 bytes +static void mix_cols(byte *state) { + mix_col(state); + mix_col(state + 4); + mix_col(state + 8); + mix_col(state + 12); +} + +// Perform the inverse mix columns matrix on one column of 4 bytes +// http://en.wikipedia.org/wiki/Rijndael_mix_columns +static void mix_col_inv(byte *state) { + byte a0 = state[0]; + byte a1 = state[1]; + byte a2 = state[2]; + byte a3 = state[3]; + state[0] = lookup_g14[a0] ^ lookup_g9[a3] ^ lookup_g13[a2] ^ lookup_g11[a1]; + state[1] = lookup_g14[a1] ^ lookup_g9[a0] ^ lookup_g13[a3] ^ lookup_g11[a2]; + state[2] = lookup_g14[a2] ^ lookup_g9[a1] ^ lookup_g13[a0] ^ lookup_g11[a3]; + state[3] = lookup_g14[a3] ^ lookup_g9[a2] ^ lookup_g13[a1] ^ lookup_g11[a0]; +} + +// Perform the inverse mix columns matrix on each column of the 16 bytes +static void mix_cols_inv(byte *state) { + mix_col_inv(state); + mix_col_inv(state + 4); + mix_col_inv(state + 8); + mix_col_inv(state + 12); +} + +void oqs_aes128_enc_c(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext) { + const uint8_t *schedule = (const uint8_t *) _schedule; + int i; // To count the rounds + + // First Round + memcpy(ciphertext, plaintext, 16); + xor_round_key(ciphertext, schedule, 0); + + // Middle rounds + for (i = 0; i < 9; i++) { + sub_bytes(ciphertext, 16); + shift_rows(ciphertext); + mix_cols(ciphertext); + xor_round_key(ciphertext, schedule, i + 1); + } + + // Final Round + sub_bytes(ciphertext, 16); + shift_rows(ciphertext); + xor_round_key(ciphertext, schedule, 10); +} + +void oqs_aes128_dec_c(const uint8_t *ciphertext, const void *_schedule, uint8_t *plaintext) { + const uint8_t *schedule = (const uint8_t *) _schedule; + int i; // To count the rounds + + // Reverse the final Round + memcpy(plaintext, ciphertext, 16); + xor_round_key(plaintext, schedule, 10); + shift_rows_inv(plaintext); + sub_bytes_inv(plaintext, 16); + + // Reverse the middle rounds + for (i = 0; i < 9; i++) { + xor_round_key(plaintext, schedule, 9 - i); + mix_cols_inv(plaintext); + shift_rows_inv(plaintext); + sub_bytes_inv(plaintext, 16); + } + + // Reverse the first Round + xor_round_key(plaintext, schedule, 0); +} diff --git a/blkstuff/aes.h b/blkstuff/aes.h new file mode 100644 index 0000000..f905742 --- /dev/null +++ b/blkstuff/aes.h @@ -0,0 +1,66 @@ +/** + * \file aes.h + * \brief Header defining the API for OQS AES + */ + +#ifndef __OQS_AES_H +#define __OQS_AES_H + +#include +#include + +/** + * Function to fill a key schedule given an initial key. + * + * @param key Initial Key. + * @param schedule Abstract data structure for a key schedule. + * @param forEncryption 1 if key schedule is for encryption, 0 if for decryption. + */ +void OQS_AES128_load_schedule(const uint8_t *key, void **schedule, int for_encryption); + +/** + * Function to free a key schedule. + * + * @param schedule Schedule generated with OQS_AES128_load_schedule(). + */ +void OQS_AES128_free_schedule(void *schedule); + +/** + * Function to encrypt blocks of plaintext using ECB mode. + * A schedule based on the key is generated and used internally. + * + * @param plaintext Plaintext to be encrypted. + * @param plaintext_len Length on the plaintext in bytes. Must be a multiple of 16. + * @param key Key to be used for encryption. + * @param ciphertext Pointer to a block of memory which >= in size to the plaintext block. The result will be written here. + */ +void OQS_AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext); + +/** + * Function to decrypt blocks of plaintext using ECB mode. + * A schedule based on the key is generated and used internally. + * + * @param ciphertext Ciphertext to be decrypted. + * @param ciphertext_len Length on the ciphertext in bytes. Must be a multiple of 16. + * @param key Key to be used for encryption. + * @param ciphertext Pointer to a block of memory which >= in size to the ciphertext block. The result will be written here. + */ +void OQS_AES128_ECB_dec(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext); + +/** + * Same as OQS_AES128_ECB_enc() except a schedule generated by + * OQS_AES128_load_schedule() is passed rather then a key. This is faster + * if the same schedule is used for multiple encryptions since it does + * not have to be regenerated from the key. + */ +void OQS_AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext); + +/** + * Same as OQS_AES128_ECB_dec() except a schedule generated by + * OQS_AES128_load_schedule() is passed rather then a key. This is faster + * if the same schedule is used for multiple encryptions since it does + * not have to be regenerated from the key. + */ +void OQS_AES128_ECB_dec_sch(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext); + +#endif diff --git a/blkstuff/magic_constants.h b/blkstuff/magic_constants.h index 268eef6..029c76e 100644 --- a/blkstuff/magic_constants.h +++ b/blkstuff/magic_constants.h @@ -600,424 +600,9 @@ const uint8_t blk_stuff1_p1[] = { 0x95,0x3E,0xEC,0x13,0x04,0x30,0xF8,0xF8,0x3F,0xCC,0xB7, 0xE9,0x95,0x31,0x89,0x80,0x01,0x3F,0xE2,0x88,0xAD,0x9F, 0xF4,0x2D,0x51,0xEC,0x57,0x46,0xD7,0xF4, -}; - -const uint8_t blk_stuff1_p2[] = { - 0x48,0x70,0xB5,0x57,0x67,0xC5,0x77,0x54,0x03,0x93,0xB6, - 0xC4,0x23,0xA3,0x4C,0x91,0x22,0x2F,0x79,0xCC,0x06,0x19, - 0x57,0xF6,0xB5,0x7E,0x4A,0xAC,0x52,0x67,0x11,0x94,0x39, - 0xB4,0xE8,0x52,0xB4,0xF2,0x7F,0xF1,0x91,0x48,0x64,0x96, - 0xEC,0x86,0x5E,0x22,0x56,0x61,0xC5,0xFB,0xDC,0xAE,0xD9, - 0xD0,0x3F,0xB1,0x56,0x87,0xAC,0xE6,0xB1,0x88,0xC7,0x35, - 0x48,0x4E,0x3C,0x3E,0x09,0x60,0x5C,0x6E,0x1C,0x9F,0x44, - 0x7A,0xD2,0xE6,0xDA,0xAB,0x67,0x05,0x98,0xC8,0xE2,0x15, - 0x94,0xC2,0x85,0xA4,0x72,0x57,0xEB,0xC1,0x1A,0x0B,0x4D, - 0xE0,0x0C,0x16,0x8E,0x92,0xA6,0xE9,0x68,0xEC,0x8C,0xD6, - 0x4B,0xDD,0xCD,0x3A,0x91,0x2A,0x41,0xF0,0x33,0xD4,0x50, - 0x64,0x7B,0x2E,0x97,0x4D,0xDA,0x43,0x6C,0x46,0x9B,0x6D, - 0xED,0x0A,0x6B,0x7F,0x80,0xDC,0x2C,0x6C,0x3E,0x3D,0x63, - 0xDA,0xA7,0x65,0x5D,0xB1,0xE9,0x0C,0xBF,0x10,0xD0,0xA4, - 0xBE,0x61,0x64,0x4A,0x28,0xB3,0x7A,0x5B,0x58,0x1F,0xFC, - 0x9E,0x23,0x85,0x8E,0xD5,0x21,0x67,0x7B,0xD7,0x6D,0x42, - 0xA8,0xE0,0x65,0xE7,0xA2,0xEF,0xBC,0x83,0xE7,0x05,0xB2, - 0x1B,0xE0,0x8C,0x39,0x93,0x69,0xCC,0x7A,0x5F,0x96,0xC1, - 0xEF,0x1E,0x8D,0x5A,0x7E,0x80,0x4B,0xFF,0xEA,0xB0,0xB2, - 0xF7,0xC1,0x24,0x6B,0xCF,0x10,0xE5,0xFA,0x9B,0x9D,0x50, - 0x7F,0xD1,0xB9,0x2D,0xAB,0x6F,0x3A,0x00,0x36,0x31,0xD0, - 0x04,0x9F,0x41,0x69,0x9D,0xCA,0xB3,0x1A,0xA2,0x29,0xAC, - 0x95,0xF5,0x3A,0x3B,0xB7,0xB5,0x1B,0x87,0x78,0xBD,0xF4, - 0x92,0x90,0x5B,0x93,0x4B,0x0E,0x2C,0xBE,0xFD,0xA6,0x95, - 0xEA,0x83,0xE0,0xF7,0x57,0xED,0xF0,0xA6,0x7C,0x5E,0xE6, - 0xCA,0x1F,0x81,0xAC,0xD2,0xC8,0xB0,0x70,0x18,0xDD,0x22, - 0xEC,0x8D,0x2D,0xAA,0x41,0x9A,0xBB,0x77,0x47,0xA7,0x1C, - 0x0E,0xF3,0x35,0xBD,0x72,0xF9,0x72,0x12,0x07,0xFE,0x3E, - 0x59,0xE4,0xFD,0xAD,0x47,0xF5,0x8D,0x01,0xA4,0xEA,0x02, - 0x56,0x27,0xA5,0x98,0xFE,0x8F,0x59,0x14,0x3A,0xC4,0xBA, - 0x17,0xA9,0x54,0x62,0xAF,0x41,0x88,0xD0,0x9F,0xB2,0x68, - 0x40,0x4F,0x02,0x1D,0x82,0xC6,0x68,0x79,0xD4,0x07,0xF8, - 0x00,0x1C,0xE9,0x23,0xCF,0x39,0xFB,0x90,0x90,0xC4,0x51, - 0xCB,0x7E,0x5D,0x8C,0x70,0xA9,0x6C,0x50,0xBA,0x1E,0x0D, - 0x99,0x8F,0xFE,0x9D,0x49,0x3F,0x60,0x4C,0xFC,0xDC,0xB8, - 0xF8,0x18,0x40,0x65,0xC6,0x1D,0xEE,0xE1,0x00,0x0C,0xCE, - 0x19,0x84,0x12,0x07,0x10,0x04,0x94,0x84,0x2B,0xAF,0xFF, - 0x4F,0x07,0x95,0x62,0xAB,0x75,0xDE,0x60,0x49,0xE4,0x8A, - 0xED,0xFC,0x16,0x01,0x2A,0x51,0x24,0x2A,0xC7,0x19,0x2F, - 0xA9,0x2B,0x20,0x13,0x8B,0xCB,0x63,0x71,0xD8,0xB4,0x26, - 0x82,0xDF,0x46,0xD6,0x3D,0xB2,0x3C,0x3D,0x15,0x8E,0x75, - 0xB6,0x8A,0xD3,0xF5,0x08,0xAD,0x6A,0x84,0xD5,0x02,0x1F, - 0x83,0x99,0x99,0x44,0xD7,0x48,0x78,0x58,0x32,0xA5,0x43, - 0xF3,0x59,0x6E,0x05,0x96,0x08,0x11,0xFB,0x17,0xA8,0x0D, - 0xD9,0x24,0x38,0xE2,0x25,0xA6,0xF2,0x44,0x0B,0x9F,0x05, - 0x1A,0x17,0x8D,0x1F,0x0C,0xEB,0x0F,0xD5,0xAA,0x34,0x32, - 0xBA,0xBE,0x0D,0x9A,0xBB,0xCF,0x4E,0x75,0x0B,0x82,0xB6, - 0xF1,0x15,0x4B,0xF7,0x1D,0xCF,0xBC,0xBA,0xFB,0x72,0xFA, - 0xEE,0x85,0x34,0x98,0x45,0xF6,0xE7,0xBB,0x5D,0xE2,0x29, - 0xC2,0x42,0x7F,0x6C,0x33,0x92,0xC7,0x3B,0x71,0xD2,0xA7, - 0xD4,0xDB,0xAF,0x69,0xEE,0x6F,0xA1,0x60,0xE3,0x64,0xCE, - 0xB5,0xCE,0xCD,0x5B,0xE7,0x97,0x17,0x0A,0x13,0x30,0x47, - 0x9D,0x42,0x03,0x27,0x9C,0xCE,0x36,0x7A,0xCB,0x3F,0x2F, - 0xFF,0xB7,0x7D,0x20,0x16,0xDE,0xAD,0xB3,0x6A,0x04,0x1A, - 0x3D,0x4C,0xC5,0x36,0x22,0xF4,0x14,0x02,0x40,0xEB,0x6E, - 0x45,0xF1,0xD7,0x32,0x37,0x04,0x6B,0xB0,0xF4,0xAB,0x9E, - 0x08,0x10,0x5A,0xFD,0x5E,0x6D,0x76,0x25,0xB1,0x78,0x9E, - 0xC3,0xB9,0x74,0x2D,0x1D,0x4F,0xF9,0x3E,0xDF,0x3B,0xB7, - 0x82,0xE8,0x9E,0xCD,0x5C,0xC0,0xC0,0xBC,0xC3,0xC6,0x95, - 0x4E,0xB0,0xF9,0x81,0x50,0x19,0x31,0xBF,0x71,0x93,0xC8, - 0xBC,0xFE,0xCC,0x2F,0xC3,0x33,0x9C,0x21,0x26,0x29,0xAD, - 0xA3,0x35,0xBE,0x8F,0xE3,0x49,0xFC,0x80,0x0A,0x73,0xDB, - 0xDE,0x9C,0x4D,0xFA,0x54,0x65,0xEF,0x09,0x01,0xC5,0x89, - 0x5C,0xAA,0xEF,0x37,0xBD,0xE5,0x59,0x9B,0x47,0xBD,0xF2, - 0x86,0xD9,0x92,0xB9,0x70,0x54,0x81,0x7B,0x76,0x51,0x3F, - 0xAE,0xD6,0xA1,0x00,0xB4,0xD1,0x28,0x8B,0x3C,0x09,0x9C, - 0x6F,0xA0,0xF1,0x18,0x71,0x69,0xC2,0xBF,0xA9,0x7C,0xD4, - 0xA2,0x6A,0x0E,0x77,0xDD,0x0A,0xF3,0xF5,0x1E,0xA5,0x06, - 0x9A,0xCB,0x88,0xAF,0xFF,0x11,0x7C,0x62,0xB3,0x7B,0xF4, - 0x79,0x38,0x38,0xDD,0x0F,0xF6,0x91,0xFA,0xE1,0xA3,0x63, - 0x89,0xDE,0x53,0xEB,0x24,0xC9,0xF3,0x1B,0x1B,0xD3,0x30, - 0x34,0x6E,0xD1,0x28,0x20,0xA0,0xA8,0x33,0xBB,0x31,0x36, - 0xDF,0x21,0x86,0x37,0x2C,0x26,0x74,0xC7,0x6D,0xCA,0xAE, - 0x30,0xE5,0x06,0xD8,0xA1,0xF9,0x14,0xC2,0xB7,0x2A,0x23, - 0xCA,0x12,0xE8,0x80,0x8A,0x4D,0x58,0x68,0xC8,0xF0,0x66, - 0x49,0x42,0x09,0x0E,0x15,0xE4,0x28,0x6F,0xC9,0xC4,0x8A, - 0x5A,0x6B,0xA2,0x4A,0xD5,0x2E,0x5F,0x53,0xFD,0x12,0x16, - 0xD8,0x87,0x55,0xA7,0xE4,0x55,0xEE,0x9A,0x1C,0xD8,0xA8, - 0x0D,0xBF,0x5F,0xE1,0x43,0x78,0x84,0xDA,0xF8,0x03,0x18, - 0x08,0x27,0x5A,0xE3,0x03,0x66,0x74,0xE2,0x8F,0x53,0x29, - 0xAA,0xE3,0x0F,0x5D,0x8B,0x5F,0xC0,0x55,0xF0,0x94,0x44, - 0x34,0x74,0x52,0x55,0x14,0x83,0x53,0x73,0x8B,0x2E,0x25, - 0x1E,0x7D,0x40,0x7C,0x06,0x89,0xF2,0x97,0x2E,0x8E,0xD7, - 0x2D,0x35,0xE9,0xAE,0xE5,0xDB,0x32,0xF8,0x98,0xF7,0xEA, - 0x63,0xC3,0xA3,0x3B,0x85,0x56,0xCD,0x5E,0x4C,0x76,0x61, - 0x38,0x01,0x90,0xDC,0x7E,0x6A,0x43,0x25,0xB8,0x4A,0x73, - 0xDF,0xED,0x46,0x79,0xB8,0x5C,0xC6,0xB9,0x7D,0x13,0x61, - 0xC0,0xC9,0x81,0xD3,0x2B,0xE1,0x86,0xA0,0xEC,0xD6,0x39, - 0x21,0xA0,0x26,0x2B,0xDB,0x27,0x52,0x58,0x0F,0x99,0xD1, - 0x75,0xA5,0x66,0x37,0x0B,0x31,0xB8,0x5B,0x8C,0xE6,0x89, - 0x87,0x46,0x20,0x2C,0x13,0x76,0x11,0x88,0xA1,0xD9,0xC1, - 0x30,0xF6,0x9B,0x7D,0xD2,0xD3,0x97,0x62,0x4F,0x96,0x66, - 0xCC,0xB6,0xA4,0x77,0x51,0xE8,0x4E,0x73,0xC9,0x3C,0x45, - 0x45, -}; - -const uint8_t blk_stuff1_p3[] = { - 0x49,0xD5,0xE6,0xA0,0x4A,0xFA,0x53,0x62,0xDA,0x9E,0x05, - 0xA3,0x8F,0xBE,0x35,0x59,0xD2,0xBF,0xB9,0x6C,0xE8,0x9B, - 0x8F,0x42,0xB2,0x28,0xE8,0x5F,0x8A,0xCF,0xF1,0x04,0x4C, - 0xA4,0x22,0xFD,0xEF,0x29,0x64,0x6A,0x88,0x0C,0xDE,0x71, - 0x3C,0x71,0x10,0x4B,0xE5,0xCB,0xF7,0xD0,0xCE,0x41,0x38, - 0xCC,0x99,0xA2,0x27,0x43,0x96,0x31,0x70,0xA4,0x50,0x5A, - 0xA3,0x5D,0x7E,0xA1,0xA8,0x1C,0x81,0xC1,0xF8,0x09,0xF8, - 0xD9,0xEC,0xC7,0x1B,0x47,0x3D,0x72,0x0B,0x05,0x5E,0xF7, - 0xBA,0x09,0x54,0x90,0xDF,0xEF,0xC1,0xFE,0xFE,0x87,0x9D, - 0x58,0x8C,0x91,0x80,0x9B,0xF2,0x3B,0x7F,0x7D,0xC3,0x11, - 0x40,0x5E,0x34,0x50,0xAC,0x84,0xCA,0xDC,0x66,0x26,0x30, - 0xCD,0xF2,0x6E,0x5D,0x0A,0xDB,0xCF,0x73,0xF1,0xD0,0x8E, - 0x61,0x70,0x9C,0x7E,0x72,0x1D,0x4A,0x39,0xC4,0xA3,0xAB, - 0x76,0xAF,0x3A,0xF3,0x48,0x0E,0x74,0x9A,0xAA,0x7F,0x4D, - 0x32,0xAB,0xAD,0xF9,0xDC,0x3D,0x01,0xE7,0xCD,0x4D,0x9B, - 0x61,0x08,0x36,0x79,0x13,0x43,0x34,0x5C,0xE6,0x41,0x78, - 0xF9,0x35,0x76,0x70,0x9D,0x3F,0x79,0xA9,0x05,0x7A,0x93, - 0xA7,0x8D,0x7D,0x1A,0x2C,0x41,0xF4,0x5A,0x6F,0x00,0x0B, - 0x57,0xFA,0x9E,0x10,0xCC,0x6B,0xAE,0xD6,0x69,0xFF,0x3A, - 0x2F,0x61,0xD4,0xFB,0xF6,0x59,0x05,0x4E,0x67,0x0D,0x88, - 0x33,0xE2,0x47,0xAC,0x1E,0x36,0xF9,0x2F,0x1A,0xAB,0xA7, - 0xC5,0x83,0x02,0xD7,0x7C,0xBC,0x57,0x25,0x0F,0xEB,0xB4, - 0x3A,0x80,0xAB,0xA7,0xAD,0xA2,0xA3,0x86,0x11,0x6D,0x45, - 0x69,0x04,0x85,0x32,0x0E,0xDD,0x1B,0x8B,0x23,0x6B,0xB3, - 0xE9,0x77,0x15,0xF5,0xB8,0xCA,0x7B,0xE5,0xD4,0xE1,0xC8, - 0xF3,0xCC,0x82,0x17,0xB9,0x06,0x55,0x26,0x65,0x93,0x40, - 0xB4,0xF9,0x84,0xB0,0x3C,0x54,0xB9,0x26,0xE1,0x52,0x2B, - 0x81,0x98,0xE6,0x6C,0x20,0xE4,0xEC,0x20,0x8F,0x91,0xEB, - 0xB3,0xC4,0x72,0xE8,0x1F,0xDA,0x63,0x98,0x48,0x39,0x7C, - 0x17,0xE0,0xBA,0x33,0x8D,0x24,0x12,0xCF,0x01,0xB7,0x59, - 0x2C,0x02,0x5F,0xC9,0xF4,0xBA,0xAC,0x15,0x46,0x8A,0x1C, - 0xF5,0xD6,0x5A,0x76,0x80,0x14,0xD3,0xE6,0xE4,0x42,0x12, - 0x3D,0x9D,0x8A,0xFC,0x8E,0x52,0xAF,0xEE,0xD5,0x0D,0x52, - 0x44,0x6E,0xE3,0xCB,0x99,0xA4,0x34,0xFA,0x45,0x91,0x83, - 0x9B,0x8C,0x21,0x63,0x0B,0x5C,0xC2,0xFD,0xDA,0xE9,0x5E, - 0x25,0x6E,0x0D,0xF0,0xF8,0x50,0x08,0xD0,0x7C,0x96,0x19, - 0x19,0x84,0x12,0x07,0x9A,0x8D,0x92,0x81,0x51,0xB6,0x39, - 0xEA,0xB5,0x9A,0x03,0x77,0x57,0xE8,0x48,0x75,0xE2,0x79, - 0x1C,0xF8,0x4F,0x8B,0x97,0x3F,0x07,0xB9,0xBC,0xD2,0x3E, - 0xB2,0x3F,0x3E,0x7D,0x8E,0x1D,0xDE,0x38,0xEC,0x4E,0xA1, - 0xC8,0x1F,0x49,0x53,0x23,0xA0,0x24,0x29,0xA8,0x88,0x18, - 0x60,0x16,0x17,0x45,0xE0,0xCB,0x30,0xFC,0x91,0x87,0x9F, - 0x89,0x96,0x56,0x04,0xD2,0xC2,0xBB,0xE5,0xCE,0x27,0x70, - 0xDE,0x65,0x4C,0x0F,0x98,0x00,0x1D,0x13,0x66,0x81,0xBD, - 0xFC,0x44,0xB2,0x2D,0x5A,0xB8,0x30,0xE7,0x04,0x96,0x09, - 0x10,0x12,0x8A,0x1B,0x0A,0xB4,0x76,0x99,0xC0,0xA0,0xA9, - 0xA4,0xAF,0xD1,0x90,0x0C,0xAE,0x9C,0xD3,0xE3,0x1E,0x55, - 0x2B,0x67,0x00,0xA2,0x6A,0x8B,0xDA,0xE4,0x27,0x6D,0x67, - 0x86,0x73,0x13,0x21,0xA5,0xD8,0x60,0xF2,0xDC,0xC0,0x74, - 0x3C,0x2D,0xDF,0xE9,0x79,0x6F,0x0F,0x51,0x2E,0xC5,0x4F, - 0x31,0xC1,0x71,0x32,0xFF,0xFB,0x7A,0x3C,0xF6,0xF6,0xD3, - 0x53,0x23,0xDB,0x09,0xC6,0x71,0x82,0x59,0x97,0x85,0x25, - 0x39,0x00,0xD4,0x16,0x64,0x01,0x58,0x23,0xE1,0x56,0xA9, - 0x3A,0x08,0x2A,0xEB,0x35,0x74,0x43,0x3B,0xA6,0x52,0x99, - 0x8C,0x28,0xEA,0x58,0xA0,0x37,0xF5,0x89,0x94,0x55,0xC9, - 0xF3,0xD3,0xE4,0x75,0xAF,0xA1,0x11,0x80,0x2D,0x62,0xBE, - 0xE3,0x95,0x86,0x4F,0x3B,0xC3,0xFB,0x63,0xDD,0x2C,0xEE, - 0x8B,0x03,0x24,0xE2,0x38,0xC1,0xD2,0x6F,0x2B,0xF6,0xA6, - 0x21,0x97,0xDE,0x03,0x5B,0x49,0xD8,0x5D,0x2A,0xD6,0xE7, - 0x08,0xD8,0xA5,0x2F,0x1C,0xC6,0x0C,0xD6,0x22,0xE7,0x86, - 0x31,0x21,0x68,0xD9,0x3F,0x5E,0xA5,0x89,0xBD,0xBB,0xBF, - 0xB8,0xFD,0xA8,0x28,0x9A,0x14,0xD4,0x6A,0x95,0x82,0xEE, - 0x4D,0xCB,0x7B,0xD0,0x6C,0x41,0xDB,0x72,0x9F,0x14,0xF1, - 0x14,0xCA,0xBF,0x47,0xAA,0x2B,0xF0,0xEC,0x06,0xD1,0xA8, - 0xA7,0x1B,0x4F,0x87,0x65,0xED,0xC2,0x94,0xB0,0xEB,0xC7, - 0x2A,0xAA,0x4B,0x37,0x15,0x22,0x4C,0xBE,0x9E,0xBE,0x94, - 0x0A,0x7A,0x77,0x6C,0x8E,0x64,0x62,0x5F,0x29,0xBC,0x10, - 0x49,0x34,0x7F,0xED,0xEA,0x4B,0x1F,0x18,0x68,0x88,0xB0, - 0xB1,0x07,0x5D,0x9D,0x7C,0x62,0x87,0x69,0x67,0x2E,0xED, - 0xE1,0x11,0xA5,0xAE,0xC8,0xFF,0x6B,0x07,0xEF,0xC0,0x3E, - 0xF5,0x9C,0xD7,0xCE,0x7D,0x31,0xCD,0x6E,0x8D,0x0E,0xCF, - 0xAD,0xA2,0x7B,0xB6,0xB5,0xB6,0xB5,0x28,0xAE,0x2D,0x24, - 0x29,0x42,0xB7,0x93,0xD9,0xB1,0xB0,0x61,0x2E,0xF0,0x5C, - 0xBB,0xBF,0x78,0x90,0xCD,0xA9,0x64,0x82,0xD7,0x0C,0xB7, - 0xB5,0xDF,0x53,0x75,0x16,0x9F,0xEE,0xC5,0xFE,0xDD,0x17, - 0xFB,0xDF,0x57,0x36,0x93,0x83,0xF1,0x94,0xF2,0x5F,0xD1, - 0x54,0xC7,0xFD,0xB7,0x4D,0x48,0xB8,0x4A,0xC6,0x60,0x84, - 0x03,0xFA,0x1A,0xC3,0xB2,0x02,0xC8,0x78,0x8F,0xA1,0x45, - 0x3E,0x18,0x66,0xC2,0x77,0x56,0x1D,0x19,0x4C,0xED,0x44, - 0x85,0x9E,0x32,0x6A,0x7E,0x95,0x73,0x37,0x7F,0x19,0x46, - 0x43,0x37,0x75,0x1A,0x4B,0x16,0xC9,0xD5,0x2A,0x6D,0x02, - 0x51,0x0A,0xE9,0xC4,0x40,0x95,0x1E,0xC5,0x66,0x63,0xB3, - 0xB3,0x0B,0x97,0xDD,0xEA,0x13,0x90,0x6F,0x01,0x3B,0xF7, - 0x4A,0xBB,0x20,0x2C,0x33,0x73,0xCE,0xF4,0x65,0x0E,0xE2, - 0x25,0xFE,0x55,0xB6,0x40,0x18,0xC0,0xD8,0x26,0xD1,0xE0, - 0x74,0x60,0x9C,0x06,0xC9,0xA6,0xF7,0xD5,0x30,0xF3,0xD7, - 0xE5,0xCA,0x42,0xDB,0xEF,0xAD,0x0D,0x5B,0x2F,0x68,0x9F, - 0xFC,0x56,0xDC,0x98,0x4E,0xBD,0xF4,0x27,0x3D,0x7A,0xC3, - 0x35,0xBC,0x36,0x33,0x46,0x46,0xB1,0x47,0x6B,0x92,0x0F, - 0xC4,0x15,0x38,0xF0,0x22,0x92,0xAC,0x2E,0x4E,0x58,0x7B, - 0x1F,0x92,0x68,0xBD,0xBA,0x06,0xC7,0x8C,0x1E,0xB4,0x85, - 0x5C,0xA6,0xE3,0x89,0xE0,0x44,0xC6,0x78,0xFF,0xD9,0x83, - 0x69,0x51,0x20,0xB1,0x6D,0xCC,0x7E,0x5B,0x5B,0x54,0xAA, - 0x50, -}; - -const uint8_t blk_stuff1_p4[] = { - 0xBE,0xD4,0x43,0xF3,0x7C,0xD7,0x6C,0x46,0xBD,0x47,0x08, - 0x10,0x47,0x12,0x28,0x20,0x72,0x4F,0x29,0xAC,0x5C,0x75, - 0x0D,0x9A,0x41,0x2F,0xBE,0xFD,0x1A,0x17,0x59,0xE4,0xE3, - 0xD1,0x32,0x37,0x74,0x72,0xBF,0x71,0x6F,0x15,0x9A,0xCB, - 0x55,0xA1,0xE7,0x05,0xCE,0x78,0x5D,0xE2,0xD2,0x53,0xD7, - 0x2D,0x5D,0x04,0x34,0x32,0xBA,0x0B,0xA7,0x65,0x43,0xCD, - 0xCC,0xB6,0x02,0xE3,0x37,0xBD,0x17,0x1C,0x57,0xED,0xD9, - 0x65,0x4F,0xF9,0x6C,0x86,0xD1,0x28,0xE9,0x96,0x93,0x4B, - 0x8E,0x27,0x9F,0x41,0xE0,0x42,0x79,0xD4,0x46,0x63,0x11, - 0x88,0x85,0x11,0x07,0x95,0x63,0x6F,0xAD,0x6A,0x40,0x5E, - 0x87,0x55,0x9A,0xA9,0xC6,0xB9,0x38,0x57,0x4A,0x73,0x70, - 0xAD,0x5B,0xE7,0xD1,0xC0,0x9C,0xCE,0x90,0xEE,0x67,0xC5, - 0x60,0xFC,0xE6,0x89,0x27,0xEF,0x8B,0x5F,0x68,0x59,0x35, - 0xBE,0x56,0x32,0xAC,0xE6,0xB4,0x93,0xE2,0x8F,0xB5,0xE2, - 0xDB,0x27,0x23,0x30,0x6F,0xC9,0x53,0x9C,0x71,0xD8,0x28, - 0x06,0xF7,0x1D,0x2A,0xE4,0x85,0x56,0x66,0xC1,0x70,0x54, - 0x6E,0x64,0xA3,0x63,0xB7,0x00,0xA9,0x6C,0xB9,0x98,0xEC, - 0x86,0x32,0x10,0xEB,0x0F,0x71,0xDC,0x62,0x4F,0xE4,0x9D, - 0x9D,0x42,0x75,0x03,0x86,0xD9,0xE1,0x33,0x40,0x7C,0xCA, - 0xA7,0xB9,0x74,0x1B,0x66,0x60,0x4C,0x96,0xD3,0xF1,0x18, - 0xB2,0xAE,0x74,0x52,0x31,0x83,0xA0,0xEC,0xDB,0x87,0x3D, - 0xB2,0x62,0x1E,0x94,0xC2,0x11,0x21,0xC1,0x30,0x9E,0x76, - 0x22,0x2F,0xBC,0x36,0x31,0xB8,0x73,0x3E,0x10,0x04,0x9B, - 0xD8,0xFF,0x11,0x05,0xAF,0x98,0xC8,0xAD,0x16,0xB5,0x7E, - 0xEB,0x74,0xE1,0x00,0xFB,0x25,0x5C,0x6E,0xED,0x49,0x77, - 0xDD,0xA7,0x51,0x14,0x02,0x7B,0x9B,0xC3,0x33,0xE7,0x0E, - 0xD6,0xA1,0x4A,0x19,0x26,0x29,0x4C,0x24,0xB0,0xF4,0xF8, - 0xB6,0x17,0x8D,0xF2,0xF1,0xB6,0xF1,0xF5,0xBD,0x19,0x84, - 0xF6,0x2E,0x52,0x67,0x86,0x82,0x4C,0x76,0x09,0xD5,0xAF, - 0x69,0x93,0x7D,0x2C,0x26,0x1F,0xB9,0x84,0xDA,0x1C,0x2A, - 0xCF,0x39,0xA4,0xC2,0x5F,0xE1,0x94,0x31,0x83,0x53,0x44, - 0x81,0x63,0xC3,0xCD,0xEB,0x16,0x01,0x0C,0x7B,0x72,0x57, - 0xE2,0xA0,0x0B,0x9F,0xF0,0x13,0xC4,0xBA,0x5A,0x48,0x9B, - 0x47,0x87,0xF3,0x75,0xDE,0x5B,0x39,0xA2,0xEF,0x92,0x0C, - 0x15,0x8E,0x42,0xBC,0xF5,0x1E,0xF7,0x5F,0x6B,0xCF,0x13, - 0xC3,0xB3,0x7B,0x16,0x6D,0x6E,0x45,0x07,0x4D,0xEA,0x83, - 0x19,0x84,0x12,0x07,0x9F,0x07,0x1B,0x87,0xF4,0xCC,0x20, - 0x2C,0x69,0x28,0x0C,0x16,0x6B,0xCA,0x7E,0x5D,0xE6,0x7F, - 0xEF,0x09,0x21,0xD2,0x1D,0x82,0xCC,0x9A,0x2F,0xA9,0x20, - 0xA3,0x24,0x2A,0xC0,0xE0,0x18,0x08,0xBF,0xA5,0x7A,0x5B, - 0x4D,0x55,0x89,0x5C,0x37,0xBE,0x36,0x31,0x7E,0x35,0x1E, - 0x0D,0xFE,0x8B,0x81,0x50,0x8F,0x56,0xA6,0xE9,0x88,0x1A, - 0x09,0x9C,0xDC,0xCB,0x92,0xC7,0x39,0x26,0x73,0xDB,0x52, - 0xED,0x48,0x70,0x03,0x92,0x0E,0x15,0xA3,0x8E,0xF0,0x94, - 0x33,0x61,0xD2,0xA7,0xF9,0xC7,0x2E,0x25,0x0E,0x99,0x00, - 0x1C,0x14,0x8F,0x1C,0x0E,0xDE,0x29,0xE0,0x8C,0xB1,0x3D, - 0x3F,0xB1,0xB0,0x4C,0x06,0x19,0x00,0x01,0x45,0xF6,0x1E, - 0xC8,0xBD,0x72,0xC4,0x3F,0xFC,0x9E,0x79,0x79,0xB1,0x78, - 0x3F,0x1B,0xE5,0x06,0xEC,0x38,0x4E,0x75,0x22,0x41,0x56, - 0x61,0x67,0xB0,0x49,0xFC,0x30,0xF2,0x99,0x44,0xDF,0x58, - 0xD9,0x24,0xE5,0xEC,0xA4,0xEA,0xE8,0xE7,0xAA,0xE3,0xC5, - 0x4E,0xC5,0x36,0x9C,0x94,0x50,0x64,0x3B,0xC4,0x01,0x90, - 0x08,0xA4,0x96,0xC1,0x3D,0xF9,0x97,0x4D,0x24,0x7C,0xC0, - 0xBC,0x2B,0x95,0xBC,0xFE,0xB8,0xE9,0xD5,0x2E,0x36,0xCF, - 0x0F,0x99,0x29,0x77,0xCE,0xB5,0x4B,0x68,0x1F,0x81,0xFA, - 0x54,0x65,0xC6,0x0F,0xE8,0x39,0xB4,0xA0,0x1D,0xBB,0x77, - 0x51,0x7E,0x03,0x93,0x7D,0xA6,0x55,0xEE,0x95,0x40,0xBA, - 0xFB,0x26,0x9E,0xB2,0xF7,0x35,0x5C,0x44,0x7A,0x89,0x6B, - 0x30,0x34,0x57,0x43,0x95,0x4E,0xC8,0x45,0xCB,0x3F,0xBB, - 0x7A,0x9E,0xCD,0x12,0xB2,0x8A,0xD3,0x98,0x4B,0xB4,0xF2, - 0xC7,0xAC,0xB7,0x7D,0x97,0xA2,0xC8,0xB0,0xA6,0x20,0x2D, - 0xAA,0x84,0x60,0x3E,0x3D,0x8B,0x89,0x42,0x7F,0xD5,0x1F, - 0x78,0x58,0x5F,0xE6,0x46,0x79,0x0A,0x46,0xE4,0x8A,0xA1, - 0x6C,0x82,0xDF,0xEE,0xDA,0x3C,0x3E,0xB6,0x71,0x90,0xC4, - 0x99,0x3A,0x8D,0x5A,0x8A,0xF8,0x7B,0xD7,0x34,0x2D,0x7D, - 0xD2,0x0B,0x37,0xDD,0x22,0x80,0xBF,0xDA,0xAB,0x64,0x23, - 0x02,0x1F,0x7A,0xEA,0xFA,0x9B,0xA2,0xFF,0xC9,0x3C,0x61, - 0x8D,0xDF,0x21,0x01,0x70,0x7C,0x5E,0xAE,0x85,0xFE,0x9D, - 0x83,0x2C,0x91,0x48,0x77,0xE1,0xF4,0x92,0xFF,0xFA,0xB8, - 0xF8,0xD6,0x8C,0x33,0xBB,0xF1,0x62,0xFD,0x12,0x82,0x5D, - 0xA8,0xE0,0x2F,0x4A,0x58,0x68,0x10,0x50,0xF8,0x98,0x65, - 0x52,0x3B,0xB7,0xAB,0x2B,0x23,0xA3,0x3A,0xB5,0x38,0x38, - 0x8D,0xB4,0xD4,0xA2,0x7F,0x44,0x27,0xA5,0xA5,0xB3,0x66, - 0x49,0xD3,0x22,0xEE,0x85,0xC9,0x34,0xF2,0x97,0xC1,0x91, - 0x21,0xA0,0x81,0xCE,0xE3,0x03,0xC3,0x73,0x53,0xEB,0x49, - 0x8A,0x6D,0xCA,0xEF,0xAB,0x05,0x96,0xCF,0x09,0x64,0x4A, - 0xA9,0xC9,0x51,0xE8,0x54,0xD0,0xDE,0xAD,0x1D,0x5B,0xF6, - 0x91,0xAC,0x67,0x8C,0xD6,0x91,0x9F,0x5E,0x6D,0x06,0x3C, - 0xD3,0x2B,0x48,0xFB,0x54,0x62,0xF3,0x80,0x8F,0x59,0x2C, - 0xD9,0x13,0x8B,0x6D,0xF7,0xE8,0x80,0x58,0xAA,0xE9,0x0C, - 0x04,0xDE,0xA1,0x60,0xCB,0xD6,0x80,0xDC,0x4F,0xB7,0xFB, - 0x17,0x5E,0x97,0x7F,0xD1,0x78,0x08,0x88,0xD0,0x15,0xFE, - 0x25,0xA6,0x0D,0x0A,0x4B,0xFF,0x25,0x0D,0xF9,0x14,0x3E, - 0x6A,0xDC,0xAE,0xD0,0xB1,0xA5,0x66,0xFC,0x69,0xF3,0x1B, - 0xA8,0xB8,0x68,0x40,0xC6,0xDD,0x8E,0xD5,0x6A,0xBB,0x47, - 0xF5,0xD7,0xFD,0x0A,0x13,0x2E,0x3B,0x61,0xC0,0xD4,0x6E, - 0x41,0xF0,0xB3,0xDF,0x4D,0xFA,0x76,0x90,0xCD,0x3A,0xC2, - 0x02,0x6A,0x43,0xEA,0x05,0xD8,0xA8,0xDD,0xBA,0xAB,0x6F, - 0x2D,0xA8,0x2A,0x23,0x59,0xDB,0xD0,0xA4,0xDA,0xF6,0x04, - 0x1A,0x3C,0x88,0xAE,0xE5,0x50,0x0F,0x3A,0x3B,0x8C,0xC5, - 0xED,0x0A,0x18,0xF5,0x2B,0xAF,0xAA,0x5A,0x1A,0x0B,0xFD, - 0x18,0xCA,0xB3,0xD8,0x14,0x76,0x51,0x9D,0xE5,0x69,0xCC, - 0xAF,0xF4,0xC7,0x35,0x45,0xF0,0x5A,0x6B,0x4E,0xC6,0xC2, - 0xBF, -}; - -const uint8_t blk_stuff1_p5[] = { - 0xED,0x23,0x42,0x56,0x58,0xE1,0x41,0x79,0x0E,0x20,0xD1, - 0x1D,0x3E,0xDA,0x84,0x3D,0xB2,0xEF,0xD9,0x3C,0x84,0xC1, - 0xE3,0x18,0xE3,0xDC,0xB9,0xAB,0xFA,0x87,0x81,0x4C,0x29, - 0x7E,0x47,0x27,0x6F,0xE9,0xE4,0xAA,0xD5,0xF2,0x83,0x8F, - 0x1B,0xC8,0x37,0xF2,0xFC,0x53,0xEE,0x48,0x33,0x4F,0xC5, - 0xC2,0x2C,0xC0,0x92,0x21,0x7B,0x27,0x9D,0xB2,0xA8,0xDE, - 0x5B,0xD9,0xA3,0x9F,0x75,0x22,0xF3,0x8A,0x8A,0x42,0xE7, - 0x44,0xF3,0x5A,0x36,0xF1,0x10,0xC4,0x55,0x74,0x00,0x86, - 0x5F,0x13,0xB1,0x8A,0xCA,0x7D,0xD4,0x6C,0x96,0xDB,0xF5, - 0x04,0x8B,0x18,0x87,0x12,0x74,0xFE,0xF9,0xB8,0x4B,0xDD, - 0xC8,0x92,0xA7,0x07,0x3F,0xD3,0x6D,0xA5,0xC1,0x5F,0xF9, - 0xED,0x3B,0x4E,0xD0,0x4C,0x56,0x89,0xDB,0x0D,0x78,0x72, - 0x97,0xFD,0x6A,0xF3,0x41,0xBA,0x79,0x9E,0xA0,0xF5,0xCF, - 0x20,0xF8,0xCB,0xA4,0xB9,0x91,0x29,0x05,0xF7,0x39,0x28, - 0x74,0xCE,0xD7,0xBE,0xA6,0x7A,0xC6,0xCE,0x0A,0x64,0x03, - 0xB5,0x90,0xE2,0x48,0xB7,0x72,0x90,0x4A,0xFB,0x57,0x65, - 0x7D,0xF3,0xF2,0xB6,0x72,0x2A,0x96,0xBC,0x98,0x24,0x0E, - 0xF9,0x11,0xAF,0x86,0xFE,0x51,0xEC,0x4A,0x77,0x5C,0x79, - 0x0B,0x88,0xC7,0xE8,0x95,0x93,0x62,0x7C,0xA5,0x55,0x6A, - 0x57,0x31,0xAC,0x52,0x86,0xF0,0x75,0x06,0x0B,0x45,0xE4, - 0x4C,0x2F,0x38,0x61,0xF2,0xAC,0x15,0xB5,0xAC,0x46,0x11, - 0x28,0xDC,0xFF,0x88,0x81,0x2E,0x8C,0xB7,0xD4,0x31,0x03, - 0xE0,0x37,0xA6,0x21,0xA0,0x24,0x1A,0xEE,0xA8,0x05,0x0F, - 0x06,0x4E,0xEA,0xD6,0x98,0x39,0x8D,0x60,0x30,0x80,0xA0, - 0x1E,0x76,0xE2,0xF4,0x70,0x66,0xB3,0x49,0xC3,0x70,0xDF, - 0x62,0x1C,0x3A,0xC7,0x01,0x2D,0xE6,0x0D,0xD6,0xBF,0x7A, - 0x98,0xC3,0x37,0xD7,0x8F,0x33,0xEA,0xD1,0xB2,0xA5,0x93, - 0x65,0x20,0x02,0xEF,0x6F,0x67,0xA3,0x9A,0x68,0x2B,0x0C, - 0x79,0x6B,0xB8,0x47,0x68,0x1B,0x14,0x59,0x77,0x94,0x43, - 0xBA,0x38,0x0E,0xEB,0x39,0xC4,0x82,0x2F,0x91,0x27,0x81, - 0xBC,0xDA,0xFF,0x39,0x54,0x4A,0x4D,0x09,0xA7,0x96,0xDD, - 0xD9,0x17,0x76,0x1F,0x50,0x7D,0x03,0x49,0x91,0xED,0x67, - 0x81,0x7F,0x36,0x1E,0xA4,0x6D,0x85,0xD1,0x59,0xC7,0xDE, - 0x8E,0xC0,0x1A,0x65,0x60,0xF1,0xC6,0xAF,0xB7,0x90,0x0F, - 0x9A,0x00,0x00,0xDF,0x2A,0xE0,0xD1,0x6A,0xC9,0x7E,0x65, - 0x8E,0x55,0xA6,0x5B,0x8B,0xFB,0x7B,0x9D,0x9A,0xDB,0xFF, - 0x19,0x84,0x12,0x07,0x99,0x02,0x91,0x0E,0x32,0x69,0x5A, - 0x35,0x08,0xF4,0xBE,0x19,0x43,0xF6,0x5C,0x6B,0x17,0x7B, - 0xE9,0xFA,0x9C,0xBC,0x44,0x08,0xB7,0x51,0x0C,0x3A,0x34, - 0xBD,0x35,0x31,0x16,0x5D,0x76,0x0D,0x45,0x22,0x33,0x6F, - 0x42,0xD0,0xC3,0x9C,0x2F,0xAA,0x28,0x23,0x13,0xE3,0xA3, - 0x0B,0x4E,0x63,0x1D,0x94,0xF7,0x12,0xC0,0xB3,0x82,0x15, - 0x8C,0x1C,0xD9,0x41,0x5D,0x87,0xC5,0xA4,0xB0,0x66,0x6E, - 0xCF,0x7B,0x5D,0x0B,0x9E,0x04,0x1B,0x8A,0x3E,0x18,0xE5, - 0xB9,0xAE,0xF7,0xC7,0x3B,0x64,0x51,0x3B,0x02,0x93,0x0F, - 0x15,0x10,0x89,0x19,0x09,0x92,0x43,0xBF,0xF5,0xAF,0x2C, - 0xAB,0x2A,0x07,0x2D,0xDA,0x13,0xE8,0x9D,0x97,0x50,0x6C, - 0x83,0x5E,0xA8,0x80,0x59,0xA9,0xE9,0x66,0xE4,0xEF,0xA4, - 0x18,0xA2,0x8D,0xF0,0x6B,0x71,0xAE,0x5B,0x7F,0xBF,0xD7, - 0x43,0xE2,0xFA,0x26,0x5C,0x5A,0xAD,0x64,0x8C,0x3A,0x42, - 0xCE,0xCC,0xF4,0x78,0x7A,0xB1,0xFD,0x75,0x71,0xBF,0x28, - 0x58,0xD8,0xD0,0x7A,0x01,0x02,0x45,0x8E,0xA6,0x52,0x14, - 0xDF,0x95,0x32,0x83,0x53,0xA0,0x6F,0x82,0xA2,0xB9,0xEA, - 0xD5,0xE0,0xB6,0x03,0xA9,0x30,0x25,0x7F,0xC0,0x87,0xAB, - 0x59,0x1A,0xAB,0xB4,0xE1,0xDB,0x9F,0xD6,0xFE,0x0A,0xD8, - 0x67,0xC2,0x70,0xAA,0x92,0x7E,0x2C,0x69,0x3D,0x8B,0xAE, - 0x8D,0xCC,0xE8,0x16,0xF0,0xE0,0x30,0x40,0xE5,0x08,0xD6, - 0xAF,0xE9,0xBB,0x08,0xA7,0x64,0xA8,0xCA,0x51,0x2A,0x14, - 0xFD,0x25,0x50,0xCA,0xD5,0x80,0x21,0x55,0xD3,0xDE,0xD3, - 0x26,0xEC,0x8B,0xCD,0x8F,0x24,0x9F,0xEC,0x05,0xDD,0xA1, - 0x63,0x5A,0x3A,0xA2,0xAE,0x0A,0x34,0xDD,0xB4,0x3B,0xB6, - 0x38,0x23,0x19,0xF6,0x2B,0x61,0x16,0x1F,0x57,0x46,0x48, - 0x89,0x6D,0x67,0xC2,0x70,0x53,0x94,0x97,0xD0,0xF1,0xC1, - 0x3C,0xFA,0x97,0x20,0x73,0x4C,0x29,0xDA,0x2B,0xE7,0x85, - 0x44,0x04,0xAC,0x98,0xC9,0x17,0x6E,0x6E,0xCC,0xA9,0xBB, - 0x68,0x3C,0x96,0xA1,0xC8,0xB5,0x1D,0x29,0xCF,0x01,0xF9, - 0xB5,0x17,0x85,0xE7,0x7C,0xEF,0x22,0x3F,0x69,0xDC,0x3F, - 0xFC,0x1B,0xCA,0x40,0x9C,0xE6,0x69,0x83,0x33,0x13,0xEB, - 0x56,0x1E,0xBA,0x84,0x8C,0xEA,0x77,0xE1,0xE6,0x62,0x6C, - 0xAD,0xA5,0x4B,0x1A,0x26,0x0C,0x6C,0xF4,0xE8,0xFE,0x1F, - 0xCB,0xBD,0x76,0xB2,0xDC,0x4D,0x86,0x8D,0xC6,0xED,0xA9, - 0xF8,0xC4,0x2E,0xBD,0x36,0xBD,0x36,0x26,0xA7,0x23,0x2D, - 0xBC,0x10,0x22,0xC1,0xBB,0xE2,0xD2,0x32,0x57,0x38,0x25, - 0x73,0x9B,0x4E,0xB4,0xFB,0x89,0x54,0xA2,0xE7,0xBE,0x5C, - 0x07,0x34,0x1D,0x1C,0x58,0xF6,0xF5,0x5E,0xE5,0x46,0xD4, - 0xD4,0x1C,0x78,0x88,0x72,0x3D,0x10,0x54,0x52,0x9F,0x71, - 0xF6,0x34,0x5F,0x44,0xB3,0xC9,0x46,0xCB,0x8F,0x80,0xCD, - 0xE3,0xC8,0x31,0xF1,0x99,0x73,0x0C,0x09,0x4B,0x35,0x9B, - 0xAA,0xC6,0x7C,0xD5,0x6D,0x41,0x47,0x6E,0x16,0x9A,0x95, - 0xB1,0x4F,0x06,0x9E,0xF0,0x61,0xFD,0x12,0xC5,0x3C,0xFC, - 0x7E,0x99,0x48,0xB4,0xC2,0x56,0x40,0x95,0x09,0xD2,0x21, - 0xEE,0xCF,0xC3,0x01,0x6A,0xCE,0xE5,0x9E,0x9D,0xB8,0x88, - 0x68,0x30,0xE1,0x90,0x9C,0x5E,0x0A,0xB8,0x9B,0xEC,0xB0, - 0xA3,0xFC,0xC9,0x78,0x4D,0x27,0xB0,0x05,0x61,0xFF,0xE6, - 0x5E,0x35,0x2E,0x7D,0xCB,0x5B,0x4B,0x9B,0xEB,0xF7,0x2D, - 0x52,0x0D,0x4A,0x6B,0x1F,0xDE,0xB3,0xAD,0x74,0xEE,0x49, - 0xF8,0x54,0xE4,0x2E,0x49,0x58,0x24,0xEB,0x06,0xD8,0x5D, - 0x5F,0x94,0x7F,0xB6,0x77,0x93,0xCD,0x71,0x40,0x2C,0xBE, - 0x3D,0xB0,0x3E,0x3F,0xBA,0xC4,0x4D,0xC5,0x04,0x47,0x60, - 0x11,0xFB,0xA1,0x1E,0xBB,0x25,0xCD,0x99,0x2F,0x14,0x11, - 0x53,0xF8,0xB1,0x85,0x63,0x3E,0x15,0x37,0xCC,0x0F,0xAD, - 0x60,0x8E,0xDF,0x4F,0x45,0x82,0x63,0xD2,0x00,0x73,0x7C, - 0x2B,0x32,0x62,0xD2,0x75,0xD8,0x66,0x4F,0xA1,0xD3,0x50, - 0xD7, -}; - -const uint8_t blk_stuff1_p6[] = { - 0xAD,0xF7,0x97,0x29,0xCB,0xCC,0x5C,0xC0,0x48,0xB6,0x56, - 0x6A,0x72,0x01,0x26,0x0B,0x93,0x0D,0xD4,0x6E,0x70,0xC5, - 0x16,0x6F,0xD3,0x68,0xA6,0xA0,0x27,0x3C,0x08,0x2B,0x8B, - 0xA5,0x49,0xEE,0x7D,0x18,0xFA,0xE5,0x39,0x9A,0x40,0xDF, - 0x91,0x28,0x12,0x9E,0xC7,0xE0,0x6C,0xAA,0xE3,0x13,0xED, - 0x7A,0xB1,0x9D,0x67,0x8D,0xAE,0x49,0x10,0xE5,0xCD,0x46, - 0x4B,0xD8,0x3D,0xD2,0x21,0xAE,0x63,0x12,0xE9,0x78,0xEE, - 0xD7,0x07,0x22,0xC3,0xDE,0xE5,0xFC,0x56,0x47,0x10,0x72, - 0xF9,0xB3,0xE3,0xF3,0x04,0x2F,0x3C,0x24,0x0F,0x46,0x36, - 0x9C,0x17,0x26,0x4A,0x92,0x60,0x72,0xCD,0x91,0x2B,0x21, - 0xD4,0x96,0x5F,0xA2,0x93,0x03,0x41,0xB5,0x86,0x8A,0x46, - 0x29,0x38,0x87,0x82,0x91,0x0B,0xEB,0x45,0xEF,0x6C,0x3D, - 0x34,0x1D,0xA5,0x92,0xE0,0x84,0xBA,0xBA,0x83,0xC6,0x97, - 0x03,0xF9,0xC2,0x19,0x4E,0x8C,0xC7,0x5C,0xED,0x85,0x9F, - 0x52,0x8C,0x7F,0x17,0xBE,0x0E,0x18,0xAF,0x47,0x2D,0x46, - 0x73,0x9C,0xD1,0x38,0xE1,0x37,0x5A,0xF9,0x4A,0xEF,0x4B, - 0xB3,0x18,0x73,0x07,0x8D,0x98,0x30,0x68,0xDD,0x9D,0x85, - 0xBA,0x3B,0x8F,0x1B,0xB4,0x20,0xE3,0x95,0x0F,0xB3,0x3D, - 0xFE,0x09,0x86,0x24,0x25,0x6D,0x14,0xB2,0xDD,0x6F,0x4F, - 0x7F,0x52,0x85,0x32,0x9F,0x63,0x25,0x0A,0xC3,0x5F,0xBB, - 0xB0,0xEB,0xBD,0xCF,0xBF,0xFE,0x26,0x51,0xB5,0x30,0xEC, - 0xA8,0xDF,0xFD,0xAE,0x28,0x90,0x41,0x88,0x71,0x18,0x25, - 0x09,0x72,0xB1,0x7D,0xDF,0x2E,0xE6,0x6F,0x11,0x67,0x56, - 0x23,0x0D,0x7D, -}; +//}; -const uint8_t blk_stuff1_p7[] = { +//const uint8_t blk_stuff1_p7[] = { 0x97,0x73,0x5B,0xB2,0xBA,0xE2,0x63,0xF2,0x70,0x89,0xF0, 0x62,0x06,0x08,0xE3,0x25,0xD2,0x97,0xAF,0xB5,0x2B,0x11, 0xAD,0x88,0x76,0x84,0x55,0xAE,0xF9,0x44,0xBC,0xDC,0xB9, diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 7f198f0..39ad998 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -20,15 +20,6 @@ void key_scramble1(uint8_t* key) { key[i] = key_scramble_table1[((i & 3) << 8) | key[i]]; } -uint8_t xor_combine(uint8_t* input) { - // xors an array of 16 bytes into a single byte - //hexdump(input, 0x10); - uint8_t ret = 0; - for (int i = 0; i < 16; i++) - ret ^= input[i]; - return ret; -} - void create_decrypt_vector(uint8_t* key, uint8_t* encrypted_data, uint64_t encrypted_size, uint8_t* output, uint64_t output_size) { if (output_size != 4096) { cout << "create_decrypt_vector does not support an output_size other than 4096" << endl; @@ -52,13 +43,8 @@ void create_decrypt_vector(uint8_t* key, uint8_t* encrypted_data, uint64_t encry ((uint64_t*)output)[i] = mt_rand(); } -void add_round_key(uint8_t* data, const uint8_t* round_keys, int round) -{ - for (int i = 0; i < 16; i++) - data[i] ^= round_keys[round * 16 + i]; -} - -void try_expand_round_keys(uint8_t* round_keys, const uint8_t* seed) +#if 0 +void aes_expand_round_keys(uint8_t* round_keys, const uint8_t* seed) { int N = 4; @@ -101,7 +87,6 @@ void try_expand_round_keys(uint8_t* round_keys, const uint8_t* seed) 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; auto rot_word = [](uint32_t word) { - //return (word << 8) | ((word >> 24) & 0x000000FF); return (word >> 8) | ((word << 24) & 0xFF000000); }; @@ -133,23 +118,16 @@ void try_expand_round_keys(uint8_t* round_keys, const uint8_t* seed) hexdump("Derived round key: ", round_keys + round*16, 16); } } +#endif void kinda_expand_round_keys(uint8_t* round_keys) { - // First round key - int round = 0; - - for (int i = 0; i < 16; i++) - for (int j = 0; j < 16; j++) - { - uint64_t idx = (round << 8) + (i*16) + j; - round_keys[round * 16 + i] ^= blk_stuff1_p1[idx] ^ stack_stuff[idx]; - } - - // Round keys 1-9 - for (round = 1; round < 10; round++) + // There're eleven rounds... + for (int round = 0; round <= 10; round++) { + // ... and each key has 16 bytes = 128 bits ... for (int i = 0; i < 16; i++) + // ... and each byte is a sum modulo 2 of 16 bytes of data for (int j = 0; j < 16; j++) { uint64_t idx = (round << 8) + (i*16) + j; @@ -157,20 +135,12 @@ void kinda_expand_round_keys(uint8_t* round_keys) } } - // Round key 10 - round = 10; - - for (int i = 0; i < 16; i++) - for (int j = 0; j < 16; j++) - { - uint64_t idx = (round << 8) + (i*16) + j; - round_keys[round * 16 + i] ^= blk_stuff1_p7[i * 16 + j] ^ stack_stuff[idx]; // Note the different index for blk_stuff_p7 - } - + #if 0 for (int round = 0; round <= 10; round++) { hexdump("Round key: ", round_keys + round*16, 16); } + #endif } // This function is not exported, so hackaround it @@ -188,116 +158,6 @@ void key_scramble2(uint8_t* key) { memcpy(key, chip, 16); } -// Rewritten -void _key_scramble2(uint8_t* key) { - uint8_t round_keys[11*16] = {0}; - - kinda_expand_round_keys(round_keys); - - const uint8_t index_scramble[16] = { - 0, 13, 10, 7, - 4, 1, 14, 11, - 8, 5, 2, 15, - 12, 9, 6, 3 - }; - - hexdump("Initial data: ", key, 16); - - add_round_key(key, round_keys, 0); - - for (uint64_t round = 1; round < 10; round++) { - - // Here sub_bytes, shift_rows and mix_columns are fused together - uint32_t scratch[4] = {}; - for (uint64_t j = 0; j < 4; j++) { - uint8_t temp = 0; - - temp = key[index_scramble[4 * j + 0]]; - scratch[j] ^= ((uint32_t*)blk_stuff1_p2)[temp]; - - temp = key[index_scramble[4 * j + 1]]; - scratch[j] ^= ((uint32_t*)blk_stuff1_p3)[temp]; - - temp = key[index_scramble[4 * j + 2]]; - scratch[j] ^= ((uint32_t*)blk_stuff1_p4)[temp]; - - temp = key[index_scramble[4 * j + 3]]; - scratch[j] ^= ((uint32_t*)blk_stuff1_p5)[temp]; - } - memcpy(key, scratch, 16); - add_round_key(key, round_keys, round); - } - - uint8_t scratch[16] = {}; - // Last round don't have mix_columns step, only sub_bytes and shift_rows - for (int i = 0; i < 16; i++) { - uint8_t t = key[index_scramble[i]]; - scratch[i] = blk_stuff1_p6[t] ^ ~t; - } - memcpy(key, scratch, 16); - add_round_key(key, round_keys, 10); - - hexdump("Final data: ", key, 16); -} - -void __key_scramble2(uint8_t* key) { - // UnityPlayer:$26EA90 - uint8_t expanded_key[256] = {}; - - // usually this table gets xor'd against random data that's unique for every run - // obviously if the random data actually mattered, it would make decryption impossible - for (int i = 0; i < 16; i++) - expanded_key[i * 16] = key[i]; - for (int i = 0; i < sizeof(expanded_key); i++) - expanded_key[i] ^= blk_stuff1_p1[i] ^ stack_stuff[i]; - - // should probably be in magic_constants.h, but it's very small - // that's a lookup table for row shifts in AES, motherfucker - const uint8_t index_scramble[16] = { - 0, 13, 10, 7, - 4, 1, 14, 11, - 8, 5, 2, 15, - 12, 9, 6, 3 - }; - for (uint64_t i = 1; i < 10; i++) { - uint32_t scratch[4] = {}; - for (uint64_t j = 0; j < 4; j++) { - uint8_t temp = 0; - temp = xor_combine(&expanded_key[16 * index_scramble[4 * j]]); - scratch[j] ^= ((uint32_t*)blk_stuff1_p2)[temp]; - temp = xor_combine(&expanded_key[16 * index_scramble[4 * j + 1]]); - scratch[j] ^= ((uint32_t*)blk_stuff1_p3)[temp]; - temp = xor_combine(&expanded_key[16 * index_scramble[4 * j + 2]]); - scratch[j] ^= ((uint32_t*)blk_stuff1_p4)[temp]; - temp = xor_combine(&expanded_key[16 * index_scramble[4 * j + 3]]); - scratch[j] ^= ((uint32_t*)blk_stuff1_p5)[temp]; - } - // also usually xor'd - memset(expanded_key, 0, sizeof(expanded_key)); - for (uint64_t j = 0; j < 16; j++) - expanded_key[j * 16] = ((uint8_t*)scratch)[j]; - for (uint64_t j = 0; j < 256; j++) { - uint64_t v10 = j + (i << 8); - expanded_key[j] ^= blk_stuff1_p1[v10] ^ stack_stuff[v10]; - } - } - - uint8_t scratch[16] = {}; - for (int i = 0; i < 16; i++) { - uint8_t t = xor_combine(&expanded_key[16 * index_scramble[i]]); - scratch[i] = blk_stuff1_p6[t] ^ ~t; - } - // yes, also usually xor'd - memset(expanded_key, 0, sizeof(expanded_key)); - for (uint64_t i = 0; i < 16; i++) - expanded_key[i * 16] = scratch[i]; - for (int i = 0; i < sizeof(expanded_key); i++) - expanded_key[i] ^= blk_stuff1_p7[i] ^ stack_stuff[i + 0xA00]; - - for (int i = 0; i < 16; i++) - key[i] = xor_combine(&expanded_key[16 * i]); -} - void mhy0_header_scramble2(uint8_t* input) { // UnityPlayer:$152300 @@ -550,24 +410,11 @@ int extract_blk(char* in_filename, const char* out_format) { } int main(int argc, char** argv) { - #if 0 - uint32_t box[256] = {0}; - for (int i = 0; i < 256; i++) { - box[i] = - ((uint32_t*)blk_stuff1_p2)[i] ^ - ((uint32_t*)blk_stuff1_p3)[i] ^ - ((uint32_t*)blk_stuff1_p4)[i] ^ - ((uint32_t*)blk_stuff1_p5)[i] ; - } - hexdump("Box: ", (uint8_t*)box, 256*4); - exit(0); - #endif - #if 0 uint8_t round_keys[11*16] = {0}; uint8_t seed[] = {0x54, 0x2f, 0xed, 0x67, 0x5d, 0xdd, 0x11, 0x2e, 0xb7, 0x40, 0x13, 0xe3, 0x29, 0xab, 0x6d, 0x28}; - try_expand_round_keys(round_keys, seed); + aes_expand_round_keys(round_keys, seed); memset(round_keys, 0, 11*16); kinda_expand_round_keys(round_keys); exit(0); From 06da1c1d4fff6dfb6021977730acf394dba524a1 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 18:49:15 +0500 Subject: [PATCH 14/15] Use struct for BLK header --- blkstuff/magic_constants.h | 11 +++++++ blkstuff/main.cpp | 66 +++++++++++++++----------------------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/blkstuff/magic_constants.h b/blkstuff/magic_constants.h index 029c76e..476c9c0 100644 --- a/blkstuff/magic_constants.h +++ b/blkstuff/magic_constants.h @@ -692,3 +692,14 @@ static inline uint8_t gf256_mul(uint8_t a, uint8_t b) return gf256_exp[(gf256_log[a] + gf256_log[b]) % 255]; } + +#pragma pack(1) +struct blk_header +{ + uint32_t magic; // "blk\0" + uint32_t version; // 0x10 + uint8_t key1[16]; // Decryption key + uint8_t key2[16]; // Some other key + uint16_t block_size; +}; +#pragma pack() diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index 39ad998..c286f1a 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -318,68 +318,56 @@ void mhy0_extract(const char* out_format, int block_index, uint8_t* input, size_ } int extract_blk(char* in_filename, const char* out_format) { - //auto* blk_file = fopen("D:\\genshinimpactre\\1.5-dev\\YuanShen_Data\\StreamingAssets\\20527480.blk", "rb"); - //auto* blk_file = fopen("D:\\Games\\Genshin Impact\\Genshin Impact game\\GenshinImpact_Data\\StreamingAssets\\VideoAssets\\26236578.blk", "rb"); auto* blk_file = fopen(in_filename, "rb"); + if (!blk_file) { cout << "failed to open blk" << endl; return 1; } - { - uint32_t magic = 0; - fread(&magic, 4, 1, blk_file); - if (magic != 0x6B6C62) { // blk\x00 - cout << "bad file magic" << endl; - return 1; - } + blk_header hdr; + bool fail = false; + + if (fread(&hdr, sizeof(blk_header), 1, blk_file) < 1) { + cout << "Failed to read BLK header!" << endl; + fail = true; } - { - uint32_t unk1 = 0; - fread(&unk1, 4, 1, blk_file); - if (unk1 != 0x10) { - cout << "unk1 is not 0x10" << endl; - return 1; - } + if (!fail && hdr.magic != 0x6B6C62) { // blk\x00 + cout << "bad file magic" << endl; + fail = true; + } + + if (!fail && hdr.version != 0x10) { + cout << "version is not 0x10" << endl; + fail = true; + } + + if (fail) { + fclose(blk_file); + return 1; } - uint8_t key[16] = {}; - fread(key, sizeof(key), 1, blk_file); - fseek(blk_file, 16, SEEK_CUR); // skip the useless half of the key //hexdump("encrypted blk key:", key, sizeof(key)); - key_scramble1(key); - key_scramble2(key); + key_scramble1(hdr.key1); + key_scramble2(hdr.key1); // this should also go into magic_constants.h, but it's small // this value goes through a lot of computation to get generated, but is always the same uint8_t hard_key[] = { 0xE3, 0xFC, 0x2D, 0x26, 0x9C, 0xC5, 0xA2, 0xEC, 0xD3, 0xF8, 0xC6, 0xD3, 0x77, 0xC2, 0x49, 0xB9 }; for (int i = 0; i < 16; i++) - key[i] ^= hard_key[i]; + hdr.key1[i] ^= hard_key[i]; //hexdump("decrypted blk key:", key, sizeof(key)); - uint16_t block_size = 0; - fread(&block_size, sizeof(block_size), 1, blk_file); - //cout << "0x" << hex << block_size << endl; - fseek(blk_file, 0, SEEK_END); - size_t size = ftell(blk_file); - fseek(blk_file, 0x2A, SEEK_SET); // skip xorpad size + size_t size = ftell(blk_file) - sizeof(blk_header); + fseek(blk_file, sizeof(blk_header), SEEK_SET); // skip header auto* data = new uint8_t[size]; fread(data, size, 1, blk_file); fclose(blk_file); - /* uint8_t xorpad[4096] = {}; - create_decrypt_vector(key, data, size, xorpad, sizeof(xorpad)); - - auto len = std::min((uint64_t)size, sizeof(xorpad)); - for (int i = 0; i < len; i++) - data[i] ^= xorpad[i]; - */ - - uint8_t xorpad[4096] = {}; - create_decrypt_vector(key, data, std::min((uint64_t)block_size, sizeof(xorpad)), xorpad, sizeof(xorpad)); + create_decrypt_vector(hdr.key1, data, std::min((uint64_t)hdr.block_size, sizeof(xorpad)), xorpad, sizeof(xorpad)); for (int i = 0; i < size; i++) data[i] ^= xorpad[i & 0xFFF]; //dump_to_file("decrypted.bin", data, size); @@ -402,8 +390,6 @@ int extract_blk(char* in_filename, const char* out_format) { } } - //mhy0_extract(data, size); - delete[] data; return 0; From b4480d005bc1b56fe10c6ffde48cd92a6fe19f7e Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Aug 2021 20:03:30 +0500 Subject: [PATCH 15/15] Rewrite expression to be the same as in key_scramble1 --- blkstuff/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blkstuff/main.cpp b/blkstuff/main.cpp index c286f1a..b3b10b8 100644 --- a/blkstuff/main.cpp +++ b/blkstuff/main.cpp @@ -185,7 +185,7 @@ void mhy0_header_scramble2(uint8_t* input) int idx = j % 8; - tmp[j] = smol_key[idx] ^ key_scramble_table1[j % 4 * 256 | gf256_mul(v25[idx], input[i])]; + tmp[j] = smol_key[idx] ^ key_scramble_table1[((j & 3) << 8) | gf256_mul(v25[idx], input[i])]; } memcpy(input, tmp, 16); }