diff --git a/Android.mk b/Android.mk
index 1a5782b2..71b2b55e 100755
--- a/Android.mk
+++ b/Android.mk
@@ -866,6 +866,11 @@ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 24; echo $$?),0)
include $(commands_TWRP_local_path)/libmincrypt/Android.mk
endif
+ifneq ($(TW_OZIP_DECRYPT_KEY),)
+ TWRP_REQUIRED_MODULES += ozip_decrypt
+ include $(commands_TWRP_local_path)/ozip_decrypt/Android.mk
+endif
+
ifeq ($(TW_INCLUDE_CRYPTO), true)
include $(commands_TWRP_local_path)/crypto/fde/Android.mk
include $(commands_TWRP_local_path)/crypto/scrypt/Android.mk
diff --git a/gui/Android.mk b/gui/Android.mk
index 0f743f5b..0c7a02c4 100755
--- a/gui/Android.mk
+++ b/gui/Android.mk
@@ -76,7 +76,11 @@ endif
ifneq ($(TW_USE_KEY_CODE_TOUCH_SYNC),)
LOCAL_CFLAGS += -DTW_USE_KEY_CODE_TOUCH_SYNC=$(TW_USE_KEY_CODE_TOUCH_SYNC)
endif
-
+ifneq ($(TW_OZIP_DECRYPT_KEY),)
+ LOCAL_CFLAGS += -DTW_OZIP_DECRYPT_KEY=\"$(TW_OZIP_DECRYPT_KEY)\"
+else
+ LOCAL_CFLAGS += -DTW_OZIP_DECRYPT_KEY=0
+endif
ifneq ($(TW_NO_SCREEN_BLANK),)
LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK
endif
diff --git a/gui/action.cpp b/gui/action.cpp
index 350b6301..3432f477 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -1029,6 +1029,17 @@ void GUIAction::reinject_after_flash()
}
}
+int GUIAction::ozip_decrypt(string zip_path)
+{
+ if (!TWFunc::Path_Exists("/sbin/ozip_decrypt")) {
+ return 1;
+ }
+ gui_msg("ozip_decrypt_decryption=Starting Ozip Decryption...");
+ TWFunc::Exec_Cmd("ozip_decrypt " + (string)TW_OZIP_DECRYPT_KEY + " '" + zip_path + "'");
+ gui_msg("ozip_decrypt_finish=Ozip Decryption Finished!");
+ return 0;
+}
+
int GUIAction::flash(std::string arg)
{
int i, ret_val = 0, wipe_cache = 0;
@@ -1039,6 +1050,20 @@ int GUIAction::flash(std::string arg)
size_t slashpos = zip_path.find_last_of('/');
string zip_filename = (slashpos == string::npos) ? zip_path : zip_path.substr(slashpos + 1);
operation_start("Flashing");
+ if((zip_path.substr(zip_path.size() - 4, 4)) == "ozip")
+ {
+ if((ozip_decrypt(zip_path)) != 0)
+ {
+ LOGERR("Unable to find ozip_decrypt!");
+ break;
+ }
+ zip_filename = (zip_filename.substr(0, zip_filename.size() - 4)).append("zip");
+ zip_path = (zip_path.substr(0, zip_path.size() - 4)).append("zip");
+ if (!TWFunc::Path_Exists(zip_path)) {
+ LOGERR("Unable to find decrypted zip");
+ break;
+ }
+ }
DataManager::SetValue("tw_filename", zip_path);
DataManager::SetValue("tw_file", zip_filename);
DataManager::SetValue(TW_ZIP_INDEX, (i + 1));
diff --git a/gui/objects.hpp b/gui/objects.hpp
index 3f724183..24e9d247 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -288,6 +288,7 @@ protected:
ThreadType getThreadType(const Action& action);
void simulate_progress_bar(void);
int flash_zip(std::string filename, int* wipe_cache);
+ int ozip_decrypt(std::string zip_path);
void reinject_after_flash();
void operation_start(const string operation_name);
void operation_end(const int operation_status);
diff --git a/gui/theme/common/landscape.xml b/gui/theme/common/landscape.xml
index 85b65b84..67c8f911 100755
--- a/gui/theme/common/landscape.xml
+++ b/gui/theme/common/landscape.xml
@@ -310,7 +310,7 @@
%tw_zip_location%
-
+
diff --git a/gui/theme/common/languages/en.xml b/gui/theme/common/languages/en.xml
index ac9472ea..478f88d6 100755
--- a/gui/theme/common/languages/en.xml
+++ b/gui/theme/common/languages/en.xml
@@ -724,5 +724,7 @@
Failed unmounting System
Flashing A/B zip to inactive slot: {1}
To flash additional zips, please reboot recovery to switch to the updated slot.
+ Starting Ozip Decryption...
+ Ozip Decryption Finished!
diff --git a/gui/theme/common/portrait.xml b/gui/theme/common/portrait.xml
index b3b43127..31aef466 100755
--- a/gui/theme/common/portrait.xml
+++ b/gui/theme/common/portrait.xml
@@ -267,7 +267,7 @@
%tw_zip_location%
-
+
diff --git a/gui/theme/common/watch.xml b/gui/theme/common/watch.xml
index 71cce197..5312cf53 100755
--- a/gui/theme/common/watch.xml
+++ b/gui/theme/common/watch.xml
@@ -398,7 +398,7 @@
%tw_zip_location%
-
+
diff --git a/ozip_decrypt/Android.mk b/ozip_decrypt/Android.mk
new file mode 100644
index 00000000..161cae88
--- /dev/null
+++ b/ozip_decrypt/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ozip_decrypt
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := ozip_decrypt.cpp
+LOCAL_C_INCLUDES := external/boringssl/src/include
+LOCAL_SHARED_LIBRARIES := libcrypto
+include $(BUILD_EXECUTABLE)
diff --git a/ozip_decrypt/ozip_decrypt.cpp b/ozip_decrypt/ozip_decrypt.cpp
new file mode 100644
index 00000000..97826ec1
--- /dev/null
+++ b/ozip_decrypt/ozip_decrypt.cpp
@@ -0,0 +1,152 @@
+/*
+ Copyright 2020 Mauronofrio
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ GNU General Public License .
+*/
+
+#include
+#include
+#include
+#include
+#define _FILE_OFFSET_BITS 64
+//extern "C" __int64 __cdecl _ftelli64(FILE*);
+
+using namespace std;
+typedef std::basic_string u_string;
+
+int decrypt(unsigned char* ciphertext, int ciphertext_len, unsigned char* key,
+ unsigned char* iv, unsigned char* plaintext)
+{
+ EVP_CIPHER_CTX* ctx;
+ int len;
+ int plaintext_len;
+ ctx = EVP_CIPHER_CTX_new();
+ EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv);
+ EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
+ plaintext_len = len;
+ EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
+ plaintext_len += len;
+ EVP_CIPHER_CTX_free(ctx);
+ return plaintext_len;
+}
+
+std::string hexToASCII(string hex)
+{
+ int len = hex.length();
+ std::string newString;
+ for (int i = 0; i < len; i += 2)
+ {
+ string byte = hex.substr(i, 2);
+ char chr = (char)(int)strtol(byte.c_str(), nullptr, 16);
+ newString.push_back(chr);
+ }
+ return newString;
+}
+
+bool testkey(const char* keyf, const char* path) {
+ u_string key = (unsigned char*)(hexToASCII(keyf)).c_str();
+ int data[17];
+ FILE* fps = fopen(path, "rb");
+ fseek(fps, 4176, SEEK_SET);
+ fread(data, sizeof(char), 16, fps);
+ fclose(fps);
+ u_string udata = (unsigned char*)data;
+ EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_init(ctx);
+ EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key.c_str(), NULL);
+ EVP_CIPHER_CTX_set_padding(ctx, false);
+ unsigned char buffer[1024], * pointer = buffer;
+ int outlen;
+ EVP_DecryptUpdate(ctx, pointer, &outlen, udata.c_str(), udata.length());
+ pointer += outlen;
+ EVP_DecryptFinal_ex(ctx, pointer, &outlen);
+ pointer += outlen;
+ EVP_CIPHER_CTX_free(ctx);
+ u_string test= u_string(buffer, pointer - buffer);
+ u_string checktest = test.substr(0, 4);
+ if (checktest == ((unsigned char*) "\x50\x4B\x03\x04") || checktest == ((unsigned char*) "\x41\x4E\x44\x52")) {
+ return true;
+ }
+ return false;
+}
+
+int main(int argc, char* argv[])
+{
+
+ if (argc != 3)
+ {
+ printf("Usage: ozipdecrypt key [*.ozip]\n");
+ return 0;
+ }
+ const char* key = argv[1];
+ const char* path = argv[2];
+ FILE* fp = fopen(path, "rb");
+ char magic[13];
+ fgets(magic, sizeof(magic), fp);
+ string temp(path);
+ temp = (temp.substr(0, temp.size() - 5)).append(".zip");
+ const char* destpath= temp.c_str();
+ if (strcmp(magic, "OPPOENCRYPT!") != 0)
+ {
+ printf("This is not an .ozip file!\n");
+ fclose(fp);
+ int rencheck = rename(path, destpath);
+ if (rencheck == 0) {
+ printf("Renamed .ozip file in .zip file\n");
+ }
+ else
+ {
+ printf("Unable to rename .ozip file in .zip file\n");
+ }
+ return 0;
+ }
+ if (testkey(key, path) == false)
+ {
+ printf("Key is not good!\n");
+ fclose(fp);
+ return 0;
+ }
+ else {
+ printf("Key is good!\n");
+ }
+ FILE* fp2 = fopen(destpath, "wb");
+ fseek(fp, 0L, SEEK_END);
+ unsigned long int sizetot = ftello(fp);
+ fseek(fp, 4176, SEEK_SET);
+ int bdata[16384];
+ unsigned long int sizeseek;
+ printf("Decrypting...\n");
+ while (true)
+ {
+ unsigned char data[17];
+ fread(data, sizeof(char), 16, fp);
+ decrypt(data, sizeof(data), (unsigned char*)(hexToASCII(key)).c_str(), NULL, data);
+ fwrite(data, sizeof(char), 16, fp2);
+ sizeseek = ftello(fp);
+ if ((sizetot - sizeseek) <= 16384) {
+ fread(bdata, sizeof(char), (sizetot - sizeseek), fp);
+ fwrite(bdata, sizeof(char), (sizetot - sizeseek), fp2);
+ break;
+ }
+ else
+ {
+ fread(bdata, sizeof(char), 16384, fp);
+ fwrite(bdata, sizeof(char), 16384, fp2);
+ }
+ }
+ printf("File succesfully decrypted, saved in %s\n", destpath);
+ fclose(fp2);
+ fclose(fp);
+ return 0;
+}
+
diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk
index f547139a..a092f54a 100755
--- a/prebuilt/Android.mk
+++ b/prebuilt/Android.mk
@@ -74,6 +74,9 @@ RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/mke2fs
RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/tune2fs
RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/resize2fs
RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/simg2img
+ifneq ($(TW_OZIP_DECRYPT_KEY),)
+ RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/ozip_decrypt
+endif
ifneq ($(TARGET_ARCH), x86_64)
RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/linker
endif