From 850b282b700109fdf50c173e29e461a2f17c285f Mon Sep 17 00:00:00 2001 From: ayy lmao Date: Wed, 6 Jul 2022 16:26:35 +0300 Subject: [PATCH] Build and link mhycrypto statically --- src-tauri/Cargo.toml | 1 + src-tauri/build.rs | 11 + src-tauri/mhycrypto/aes.c | 385 ++++++++++++++++++++++ src-tauri/mhycrypto/aes.h | 66 ++++ src-tauri/mhycrypto/memecrypto.cpp | 33 ++ src-tauri/mhycrypto/memecrypto.h | 12 + src-tauri/mhycrypto/metadata.cpp | 128 +++++++ src-tauri/mhycrypto/metadata.h | 10 + src-tauri/mhycrypto/metadatastringdec.cpp | 121 +++++++ src-tauri/mhycrypto/metadatastringdec.h | 13 + src-tauri/src/metadata_patcher.rs | 36 +- 11 files changed, 791 insertions(+), 25 deletions(-) create mode 100644 src-tauri/mhycrypto/aes.c create mode 100644 src-tauri/mhycrypto/aes.h create mode 100644 src-tauri/mhycrypto/memecrypto.cpp create mode 100644 src-tauri/mhycrypto/memecrypto.h create mode 100644 src-tauri/mhycrypto/metadata.cpp create mode 100644 src-tauri/mhycrypto/metadata.h create mode 100644 src-tauri/mhycrypto/metadatastringdec.cpp create mode 100644 src-tauri/mhycrypto/metadatastringdec.h diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index db254ba..70e31bc 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -13,6 +13,7 @@ rust-version = "1.57" [build-dependencies] tauri-build = { version = "1.0.0-rc.8", features = [] } +cc = "1.0" [target.'cfg(windows)'.dependencies] is_elevated = "0.1.2" diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 795b9b7..fdf6fd3 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,14 @@ fn main() { + cc::Build::new() + .include("mhycrypto") + .cpp(true) + + .file("mhycrypto/aes.c") + .file("mhycrypto/memecrypto.cpp") + .file("mhycrypto/metadata.cpp") + .file("mhycrypto/metadatastringdec.cpp") + + .compile("mhycrypto"); + tauri_build::build() } diff --git a/src-tauri/mhycrypto/aes.c b/src-tauri/mhycrypto/aes.c new file mode 100644 index 0000000..be36e85 --- /dev/null +++ b/src-tauri/mhycrypto/aes.c @@ -0,0 +1,385 @@ +// 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); +} + +// It's not enc nor dec, it's something in between +void oqs_mhy128_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_inv(ciphertext, 16); + shift_rows_inv(ciphertext); + mix_cols_inv(ciphertext); + xor_round_key(ciphertext, schedule, i + 1); + } + + // Final Round + sub_bytes_inv(ciphertext, 16); + shift_rows_inv(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); +} + +void oqs_mhy128_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(plaintext); + sub_bytes(plaintext, 16); + + // Reverse the middle rounds + for (i = 0; i < 9; i++) { + xor_round_key(plaintext, schedule, 9 - i); + mix_cols(plaintext); + shift_rows(plaintext); + sub_bytes(plaintext, 16); + } + + // Reverse the first Round + xor_round_key(plaintext, schedule, 0); +} diff --git a/src-tauri/mhycrypto/aes.h b/src-tauri/mhycrypto/aes.h new file mode 100644 index 0000000..f905742 --- /dev/null +++ b/src-tauri/mhycrypto/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/src-tauri/mhycrypto/memecrypto.cpp b/src-tauri/mhycrypto/memecrypto.cpp new file mode 100644 index 0000000..71ccfd4 --- /dev/null +++ b/src-tauri/mhycrypto/memecrypto.cpp @@ -0,0 +1,33 @@ +#include "memecrypto.h" + +#include +#include + +#include "aes.h" + +static uint8_t dexor16(const uint8_t *c) { + uint8_t ret = 0; + for (int i = 0; i < 16; i++) + ret ^= c[i]; + return ret; +} + +void memecrypto_prepare_key(const uint8_t *in, uint8_t *out) { + for (int i = 0; i < 0xB0; i++) + out[i] = dexor16(&in[0x10 * i]); +} + +extern "C" void oqs_mhy128_enc_c(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext); +extern "C" void oqs_mhy128_dec_c(const uint8_t *ciphertext, const void *_schedule, uint8_t *plaintext); + +void memecrypto_decrypt(const uint8_t *key, uint8_t *data) { + uint8_t plaintext[16]; + oqs_mhy128_enc_c(data, key, plaintext); + memcpy(data, plaintext, 16); +} + +void memecrypto_encrypt(const uint8_t *key, uint8_t *data) { + uint8_t ciphertext[16]; + oqs_mhy128_dec_c(data, key, ciphertext); + memcpy(data, ciphertext, 16); +} diff --git a/src-tauri/mhycrypto/memecrypto.h b/src-tauri/mhycrypto/memecrypto.h new file mode 100644 index 0000000..a3452cb --- /dev/null +++ b/src-tauri/mhycrypto/memecrypto.h @@ -0,0 +1,12 @@ +#ifndef MEMECRYPTO_H +#define MEMECRYPTO_H + +#include + +void memecrypto_prepare_key(const uint8_t *in, uint8_t *out); + +void memecrypto_decrypt(const uint8_t *key, uint8_t *data); + +void memecrypto_encrypt(const uint8_t *key, uint8_t *data); + +#endif //MEMECRYPTO_H diff --git a/src-tauri/mhycrypto/metadata.cpp b/src-tauri/mhycrypto/metadata.cpp new file mode 100644 index 0000000..b517b89 --- /dev/null +++ b/src-tauri/mhycrypto/metadata.cpp @@ -0,0 +1,128 @@ +#include "metadata.h" + +#include +#include +#include + +#include "memecrypto.h" +#include "metadatastringdec.h" + +unsigned char initial_prev_xor[] = { 0xad, 0x2f, 0x42, 0x30, 0x67, 0x04, 0xb0, 0x9c, 0x9d, 0x2a, 0xc0, 0xba, 0x0e, 0xbf, 0xa5, 0x68 }; + +bool get_global_metadata_keys(uint8_t *src, size_t srcn, uint8_t *longkey, uint8_t *shortkey) { + if (srcn != 0x4000) + return false; + + if (*(uint16_t *) (src + 0xc8) != 0xfc2e || *(uint16_t *) (src + 0xca) != 0x2cfe) + return true; + + auto offB00 = *(uint16_t *) (src + 0xd2); + + for (size_t i = 0; i < 16; i++) + shortkey[i] = src[offB00 + i] ^ src[0x3000 + i]; + + for (size_t i = 0; i < 0xb00; i++) + longkey[i] = src[offB00 + 0x10 + i] ^ src[0x3000 + 0x10 + i] ^ shortkey[i % 16]; + + return true; +} + +bool gen_global_metadata_key(uint8_t* src, size_t srcn) { + if (srcn != 0x4000) + return false; + + #if 0 + std::vector read_file(const char* n); + auto data = read_file("xorpad.bin"); + memcpy(src, data.data(), 0x4000); + + return false; + #endif + + std::mt19937_64 rand (0xDEADBEEF); + + uint64_t* key = (uint64_t*)src; + + for (int i = 0; i < srcn / sizeof(uint64_t); i++) + key[i] = rand(); + + *(uint16_t *) (src + 0xc8) = 0xfc2e; // Magic + *(uint16_t *) (src + 0xca) = 0x2cfe; // Magic + *(uint16_t *) (src + 0xd2) = rand() & 0x1FFFu; // Just some random value + + return true; +} + +extern "C" void decrypt_global_metadata(uint8_t *data, size_t size) { + uint8_t longkey[0xB00]; + uint8_t longkeyp[0xB0]; + uint8_t shortkey[16]; + get_global_metadata_keys(data + size - 0x4000, 0x4000, longkey, shortkey); + for (int i = 0; i < 16; i++) + shortkey[i] ^= initial_prev_xor[i]; + memecrypto_prepare_key(longkey, longkeyp); + + auto perentry = (uint32_t) (size / 0x100 / 0x40); + for (int i = 0; i < 0x100; i++) { + auto off = (0x40u * perentry) * i; + + uint8_t prev[16]; + memcpy(prev, shortkey, 16); + for (int j = 0; j < 4; j++) { + uint8_t curr[16]; + memcpy(curr, &data[off + j * 0x10], 16); + + memecrypto_decrypt(longkeyp, curr); + + for (int k = 0; k < 16; k++) + curr[k] ^= prev[k]; + + memcpy(prev, &data[off + j * 0x10], 16); + memcpy(&data[off + j * 0x10], curr, 16); + } + } + + uint8_t literal_dec_key[0x5000]; + recrypt_global_metadata_header_string_fields(data, size, literal_dec_key); + recrypt_global_metadata_header_string_literals(data, size, literal_dec_key); +} + +extern "C" void encrypt_global_metadata(uint8_t* data, size_t size) { + uint8_t literal_dec_key[0x5000]; + + gen_global_metadata_key(data + size - 0x4000, 0x4000); + + generate_key_for_global_metadata_header_string(data, size, literal_dec_key); + + recrypt_global_metadata_header_string_literals(data, size, literal_dec_key); + recrypt_global_metadata_header_string_fields(data, size, literal_dec_key); + + uint8_t longkey[0xB00]; + uint8_t longkeyp[0xB0]; + uint8_t shortkey[16]; + + get_global_metadata_keys(data + size - 0x4000, 0x4000, longkey, shortkey); + for (int i = 0; i < 16; i++) + shortkey[i] ^= initial_prev_xor[i]; + memecrypto_prepare_key(longkey, longkeyp); + + auto perentry = (uint32_t) (size / 0x100 / 0x40); + for (int i = 0; i < 0x100; i++) { + auto off = (0x40u * perentry) * i; + + uint8_t prev[16]; + memcpy(prev, shortkey, 16); + for (int j = 0; j < 4; j++) { + uint8_t curr[16]; + memcpy(curr, &data[off + j * 0x10], 16); + + for (int k = 0; k < 16; k++) + curr[k] ^= prev[k]; + + memecrypto_encrypt(longkeyp, curr); + + memcpy(prev, curr, 16); + memcpy(&data[off + j * 0x10], curr, 16); + } + } +} diff --git a/src-tauri/mhycrypto/metadata.h b/src-tauri/mhycrypto/metadata.h new file mode 100644 index 0000000..f2c8c5b --- /dev/null +++ b/src-tauri/mhycrypto/metadata.h @@ -0,0 +1,10 @@ +#ifndef METADATA_H +#define METADATA_H + +#include +#include + +extern "C" void decrypt_global_metadata(uint8_t *data, size_t size); +extern "C" void encrypt_global_metadata(uint8_t *data, size_t size); + +#endif //METADATA_H diff --git a/src-tauri/mhycrypto/metadatastringdec.cpp b/src-tauri/mhycrypto/metadatastringdec.cpp new file mode 100644 index 0000000..66b50ae --- /dev/null +++ b/src-tauri/mhycrypto/metadatastringdec.cpp @@ -0,0 +1,121 @@ +#include "metadatastringdec.h" + +#include +#include +#include + +struct m_header_fields { + char filler1[0x18]; + uint32_t stringLiteralDataOffset; // 18 + uint32_t stringLiteralDataCount; // 1c + uint32_t stringLiteralOffset; // 20 + uint32_t stringLiteralCount; // 24 + char filler2[0xd8 - 0x28]; + uint32_t stringOffset, stringCount; +}; + +struct m_literal { + uint32_t offset, length; +}; + +void generate_key_for_global_metadata_header_string(uint8_t* data, size_t len, uint8_t* literal_dec_key) { + if (len < sizeof(m_header_fields)) + throw std::out_of_range("data not big enough for global metadata header"); + + uint32_t values[0x12] = { + *(uint32_t *) (data + 0x60), + *(uint32_t *) (data + 0x64), + *(uint32_t *) (data + 0x68), + *(uint32_t *) (data + 0x6c), + *(uint32_t *) (data + 0x140), + *(uint32_t *) (data + 0x144), + *(uint32_t *) (data + 0x148), + *(uint32_t *) (data + 0x14c), + *(uint32_t *) (data + 0x100), + *(uint32_t *) (data + 0x104), + *(uint32_t *) (data + 0x108), + *(uint32_t *) (data + 0x10c), + *(uint32_t *) (data + 0xf0), + *(uint32_t *) (data + 0xf4), + *(uint32_t *) (data + 8), + *(uint32_t *) (data + 0xc), + *(uint32_t *) (data + 0x10), + *(uint32_t *) (data + 0x14) + }; + + uint64_t seed = ((uint64_t) values[values[0] & 0xfu] << 0x20u) | values[(values[0x11] & 0xf) + 2]; + + std::mt19937_64 rand (seed); + + for (int i = 0; i < 6; i++) // Skip + rand(); + + auto key64 = (uint64_t *) literal_dec_key; + for (int i = 0; i < 0xa00; i++) + key64[i] = rand(); +} + +void recrypt_global_metadata_header_string_fields(uint8_t *data, size_t len, uint8_t *literal_dec_key) { + if (len < sizeof(m_header_fields)) + throw std::out_of_range("data not big enough for global metadata header"); + + uint32_t values[0x12] = { + *(uint32_t *) (data + 0x60), + *(uint32_t *) (data + 0x64), + *(uint32_t *) (data + 0x68), + *(uint32_t *) (data + 0x6c), + *(uint32_t *) (data + 0x140), + *(uint32_t *) (data + 0x144), + *(uint32_t *) (data + 0x148), + *(uint32_t *) (data + 0x14c), + *(uint32_t *) (data + 0x100), + *(uint32_t *) (data + 0x104), + *(uint32_t *) (data + 0x108), + *(uint32_t *) (data + 0x10c), + *(uint32_t *) (data + 0xf0), + *(uint32_t *) (data + 0xf4), + *(uint32_t *) (data + 8), + *(uint32_t *) (data + 0xc), + *(uint32_t *) (data + 0x10), + *(uint32_t *) (data + 0x14) + }; + + uint64_t seed = ((uint64_t) values[values[0] & 0xfu] << 0x20u) | values[(values[0x11] & 0xf) + 2]; + + std::mt19937_64 rand (seed); + + auto header = (m_header_fields *) data; + header->stringCount ^= (uint32_t) rand(); + header->stringOffset ^= (uint32_t) rand(); + rand(); + header->stringLiteralOffset ^= (uint32_t) rand(); + header->stringLiteralDataCount ^= (uint32_t) rand(); + header->stringLiteralDataOffset ^= (uint32_t) rand(); + + auto key64 = (uint64_t *) literal_dec_key; + for (int i = 0; i < 0xa00; i++) + key64[i] = rand(); +} + +void recrypt_global_metadata_header_string_literals(uint8_t *data, size_t len, uint8_t *literal_dec_key) { + if (len < sizeof(m_header_fields)) + throw std::out_of_range("data not big enough for global metadata header"); + + auto header = (m_header_fields *) data; + if ((size_t) header->stringLiteralCount + header->stringLiteralOffset > len) + throw std::out_of_range("file trimmed or string literal offset/count field invalid"); + + auto literals = (m_literal *) (data + header->stringLiteralOffset); + auto count = header->stringLiteralCount / sizeof(m_literal); + for (size_t i = 0; i < count; i++) { + auto slen = literals[i].length; + uint8_t *str = data + header->stringLiteralDataOffset + literals[i].offset; + uint8_t *okey = literal_dec_key + (i % 0x2800); + + if ((size_t) header->stringLiteralDataOffset + literals[i].offset + slen > len) + throw std::out_of_range("file trimmed or contains invalid string entry"); + + for (size_t j = 0; j < slen; j++) + str[j] ^= literal_dec_key[(j + 0x1400u) % 0x5000u] ^ (okey[j % 0x2800u] + (uint8_t) j); + } +} diff --git a/src-tauri/mhycrypto/metadatastringdec.h b/src-tauri/mhycrypto/metadatastringdec.h new file mode 100644 index 0000000..cfaf826 --- /dev/null +++ b/src-tauri/mhycrypto/metadatastringdec.h @@ -0,0 +1,13 @@ +#ifndef METADATASTRINGDEC_H +#define METADATASTRINGDEC_H + +#include +#include + +void recrypt_global_metadata_header_string_fields(uint8_t *data, size_t len, uint8_t *literal_dec_key); + +void recrypt_global_metadata_header_string_literals(uint8_t *data, size_t len, uint8_t *literal_dec_key); + +void generate_key_for_global_metadata_header_string(uint8_t* data, size_t len, uint8_t* literal_dec_key); + +#endif //METADATASTRINGDEC_H diff --git a/src-tauri/src/metadata_patcher.rs b/src-tauri/src/metadata_patcher.rs index fd34eb3..278dafb 100644 --- a/src-tauri/src/metadata_patcher.rs +++ b/src-tauri/src/metadata_patcher.rs @@ -1,38 +1,24 @@ -use core::ffi::c_void; -use libloading::os::windows::Library; -use libloading::os::windows::Symbol; use regex::Regex; use std::fs::File; use std::io::Read; use std::io::Write; -fn dll_decrypt_global_metadata(data: *mut u8, size: u64) -> Result<*const c_void, Box> { +extern { + fn decrypt_global_metadata(data : *mut u8, size : u64); + fn encrypt_global_metadata(data : *mut u8, size : u64); +} + +fn dll_decrypt_global_metadata(data : *mut u8, size : u64) -> Result> { unsafe { - // Load DLL - let lib = Library::new("mhycrypto.dll")?; - - // Load function and call it - let func: Symbol *const c_void> = lib.get_ordinal(0x1)?; - let decrypted_data = func(data, size); - - // Close DLL and return result - lib.close()?; - Ok(decrypted_data) + decrypt_global_metadata(data, size); + Ok(true) } } -fn dll_encrypt_global_metadata(data: *mut u8, size: u64) -> Result<*const c_void, Box> { +fn dll_encrypt_global_metadata(data : *mut u8, size : u64) -> Result> { unsafe { - // Load DLL - let lib = Library::new("mhycrypto.dll")?; - - // Load function and call it - let func: Symbol *const c_void> = lib.get_ordinal(0x2)?; - let encrypted_data = func(data, size); - - // Close DLL and return result - lib.close()?; - Ok(encrypted_data) + encrypt_global_metadata(data, size); + Ok(true) } }