Skip to content

Commit

Permalink
Increase buffer for release
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdcvlsc committed May 26, 2023
1 parent 986fa08 commit 36b0962
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 43 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ android {
// arguments "-DANDROID_STL=c++_shared"

// Set C++ version
cppFlags '-std=c++14'
cppFlags '-std=c++17'
}
}
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppBethela"
android:largeHeap="true"
tools:targetApi="31"
>
<activity
Expand Down
82 changes: 43 additions & 39 deletions app/src/main/cpp/native-lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using namespace Jpp;
constexpr static jsize MB = 1;

/// release buffer size.
constexpr static jsize BUFFER_SIZE = MB * 1024 * 1024;
constexpr static jsize BUFFER_SIZE = (MB * 1024 * 1024) + ((MB * 1024 * 1024) / 8);

/// debug buffer size.
//constexpr static jsize BUFFER_SIZE = 32;
Expand Down Expand Up @@ -77,25 +77,26 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
) {
ArrayList<Uri> file_queue(env, target_files);

jbyte *aeskey = env->GetByteArrayElements(key_file, nullptr);
auto *aeskey = (jbyte *) env->GetPrimitiveArrayCritical(key_file, nullptr);
jint aeskey_size = env->GetArrayLength(key_file);

Mode::CBC<BlockCipher::AES, Padding::PKCS_5_7> aes_scheme(
reinterpret_cast<Bytes *>(aeskey),
aeskey_size
);

env->ReleaseByteArrayElements(key_file, aeskey, 0);
env->ReleasePrimitiveArrayCritical(key_file, aeskey, JNI_ABORT);

std::atomic<jint> cnt(0);
std::mutex vector_mtx;

if (BUFFER_SIZE % AES_BLOCK_SIZE != 0 || BUFFER_SIZE <= AES_BLOCK_SIZE) {
if constexpr (BUFFER_SIZE % AES_BLOCK_SIZE != 0 || BUFFER_SIZE <= AES_BLOCK_SIZE) {
return RESULT_CODE::INVALID_INTERNAL_BUFFER_SIZE;
}

JavaVM* javaVM;
env->GetJavaVM((_JavaVM**) &javaVM);

jobject DocumentFileClass = env->NewGlobalRef((jobject) env->FindClass("androidx/documentfile/provider/DocumentFile"));
jobject globalThis = env->NewGlobalRef(thiz);
jobject globalOutputPath = env->NewGlobalRef(output_path);
Expand All @@ -106,7 +107,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
jint isDifferentThread = javaVM->GetEnv((void **) &threadEnv, JNI_VERSION_1_6);

if (isDifferentThread == JNI_EDETACHED) {
javaVM->AttachCurrentThread((_JNIEnv**) &threadEnv, NULL);
javaVM->AttachCurrentThread((_JNIEnv**) &threadEnv, nullptr);
} else if (isDifferentThread == JNI_OK) {
threadEnv = env;
} else {
Expand All @@ -116,7 +117,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e

bool run_thread = true;

Bytes *encryptedBuffer = new Bytes[BUFFER_SIZE];
auto *encryptedBuffer = new Bytes[BUFFER_SIZE];

std::string target_file;

Expand All @@ -131,7 +132,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
target_uri._thiz = file_queue.remove(threadEnv, file_queue.size(threadEnv) - 1)._thiz;
target_uri._Jclass = threadEnv->GetObjectClass(target_uri._thiz);
jstring filename = getFileName(threadEnv, globalThis, target_uri._thiz);
const char *c_filename_buffer = threadEnv->GetStringUTFChars(filename, NULL);
const char *c_filename_buffer = threadEnv->GetStringUTFChars(filename, nullptr);
target_file = std::string(c_filename_buffer);
threadEnv->ReleaseStringUTFChars(filename, c_filename_buffer);
} else {
Expand Down Expand Up @@ -211,7 +212,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
break;
}

prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, NULL);
prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, nullptr);
for (size_t index = 0; index < prevBufferSize; index += AES_BLOCK_SIZE) {
aes_scheme.blockEncrypt(
reinterpret_cast<unsigned char *>(prevBuffer + index),
Expand Down Expand Up @@ -239,7 +240,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
bool excludeLastBlock = (remainingBlocks && remainingBytes == 0);

if (remainingBlocks) {
prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, NULL);
prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, nullptr);

for (; index < remainingBlocks - excludeLastBlock; ++index) {
aes_scheme.blockEncrypt(
Expand All @@ -258,7 +259,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e

Krypt::ByteArray cipher;

prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, NULL);
prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, nullptr);
if (excludeLastBlock) {
cipher = aes_scheme.encrypt(
reinterpret_cast<unsigned char *>(prevBuffer + (index * AES_BLOCK_SIZE)), AES_BLOCK_SIZE, iv
Expand All @@ -272,7 +273,9 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e

threadEnv->SetByteArrayRegion(
prevJniBuffer, 0, cipher.length,
reinterpret_cast<jbyte *>(cipher.array));
reinterpret_cast<jbyte *>(cipher.array)
);

outgoing_bytes.write(prevJniBuffer, 0, cipher.length);

if (threadEnv->ExceptionCheck()) {
Expand Down Expand Up @@ -300,7 +303,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
}
};

int physical_threads = std::thread::hardware_concurrency();
int physical_threads = (int) std::thread::hardware_concurrency();

std::vector<std::thread> threads;

Expand All @@ -310,7 +313,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
vector_mtx.unlock();

if (notEmpty) {
threads.push_back(std::thread(encrypt_lambda));
threads.emplace_back(encrypt_lambda);
}
}

Expand All @@ -322,8 +325,8 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_e
encrypt_lambda();
}

for (size_t i = 0; i < threads.size(); ++i) {
threads[i].join();
for (auto & thrd : threads) {
thrd.join();
}

env->DeleteGlobalRef(DocumentFileClass);
Expand All @@ -341,20 +344,20 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
) {
ArrayList<Uri> file_queue(env, target_files);

jbyte *aeskey = env->GetByteArrayElements(key_file, nullptr);
auto *aeskey = (jbyte *) env->GetPrimitiveArrayCritical(key_file, nullptr);
jint aeskey_size = env->GetArrayLength(key_file);

Mode::CBC<BlockCipher::AES, Padding::PKCS_5_7> aes_scheme(
reinterpret_cast<Bytes *>(aeskey),
aeskey_size
);

env->ReleaseByteArrayElements(key_file, aeskey, 0);
env->ReleasePrimitiveArrayCritical(key_file, aeskey, JNI_ABORT);

std::atomic<jint> cnt(0);
std::mutex vector_mtx;

if (BUFFER_SIZE % AES_BLOCK_SIZE != 0 || BUFFER_SIZE <= AES_BLOCK_SIZE) {
if constexpr (BUFFER_SIZE % AES_BLOCK_SIZE != 0 || BUFFER_SIZE <= AES_BLOCK_SIZE) {
return RESULT_CODE::INVALID_INTERNAL_BUFFER_SIZE;
}

Expand All @@ -370,7 +373,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
jint isDifferentThread = javaVM->GetEnv((void **) &threadEnv, JNI_VERSION_1_6);

if (isDifferentThread == JNI_EDETACHED) {
javaVM->AttachCurrentThread((_JNIEnv**) &threadEnv, NULL);
javaVM->AttachCurrentThread((_JNIEnv**) &threadEnv, nullptr);
} else if (isDifferentThread == JNI_OK) {
threadEnv = env;
} else {
Expand All @@ -380,7 +383,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d

bool run_thread = true;

Bytes *decryptedBuffer = new Bytes[BUFFER_SIZE];
auto *decryptedBuffer = new Bytes[BUFFER_SIZE];

std::string target_file;

Expand All @@ -395,7 +398,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
target_uri._thiz = file_queue.remove(threadEnv, 0)._thiz;
target_uri._Jclass = threadEnv->GetObjectClass(target_uri._thiz);
jstring filename = getFileName(threadEnv, globalThis, target_uri._thiz);
const char *c_filename_buffer = threadEnv->GetStringUTFChars(filename, NULL);
const char *c_filename_buffer = threadEnv->GetStringUTFChars(filename, nullptr);
target_file = std::string(c_filename_buffer);
threadEnv->ReleaseStringUTFChars(filename, c_filename_buffer);
} else {
Expand All @@ -416,7 +419,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
);

std::string outfname(target_file);
std::string fileExtension = "";
std::string fileExtension;

if (outfname.size() > FILE_EXTENSION_SIZE) {
fileExtension = outfname.substr(outfname.size() - FILE_EXTENSION_SIZE, FILE_EXTENSION_SIZE);
Expand Down Expand Up @@ -452,7 +455,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
}

const jbyte fileSig[FILE_SIGNATURE_SIZE] = {0x42, 0x45, 0x54, 0x48, 0x45, 0x4c, 0x41};
jbyte *fileSigRead = threadEnv->GetByteArrayElements(fileSignature, NULL);
auto *fileSigRead = (jbyte *) threadEnv->GetPrimitiveArrayCritical(fileSignature, nullptr);

bool fileSignatureIncorrect = false;
for (int i = 0; i < FILE_SIGNATURE_SIZE; ++i) {
Expand All @@ -462,6 +465,9 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
}
}

jboolean signFailed = std::memcmp(fileSigRead, fileSig, FILE_SIGNATURE_SIZE);
threadEnv->ReleasePrimitiveArrayCritical(fileSignature, fileSigRead, JNI_ABORT);

if (fileSignatureIncorrect) {
incoming_bytes.close();
outgoing_bytes.close();
Expand All @@ -473,16 +479,13 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
jbyteArray jniBuffer = threadEnv->NewByteArray(BUFFER_SIZE);
jbyteArray jniIV = threadEnv->NewByteArray(AES_BLOCK_SIZE);
incoming_bytes.read(jniIV);
jbyte *iv = threadEnv->GetByteArrayElements(jniIV, NULL);
jbyte *iv = threadEnv->GetByteArrayElements(jniIV, nullptr);

std::string properFileExtension = ".bthl";

jboolean signFailed = std::memcmp(fileSigRead, fileSig, FILE_SIGNATURE_SIZE);
jboolean wrongFileExtension = fileExtension != properFileExtension;
jboolean JNIException = threadEnv->ExceptionCheck();

threadEnv->ReleaseByteArrayElements(fileSignature, fileSigRead, 0);

if (signFailed || wrongFileExtension || JNIException) {
if (JNIException) {
threadEnv->ExceptionDescribe();
Expand All @@ -506,7 +509,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
break;
}

prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, NULL);
prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, nullptr);
for (size_t index = 0; index < prevBufferSize; index += AES_BLOCK_SIZE) {
aes_scheme.blockDecrypt(
reinterpret_cast<unsigned char *>(prevBuffer + index),
Expand All @@ -518,7 +521,9 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d

threadEnv->SetByteArrayRegion(
prevJniBuffer, 0, prevBufferSize,
reinterpret_cast<jbyte *>(decryptedBuffer));
reinterpret_cast<jbyte *>(decryptedBuffer)
);

outgoing_bytes.write(prevJniBuffer, 0, prevBufferSize);

std::swap(prevJniBuffer, nextJniBuffer);
Expand All @@ -534,17 +539,17 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
bool excludeLastBlock = (remainingBlocks && remainingBytes == 0);

if (remainingBlocks) {
prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, NULL);

prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, nullptr);
for (; index < remainingBlocks - excludeLastBlock; ++index) {
aes_scheme.blockDecrypt(
reinterpret_cast<unsigned char *>(prevBuffer + (index * AES_BLOCK_SIZE)),
reinterpret_cast<unsigned char *>(decryptedBuffer + (index * AES_BLOCK_SIZE)),
reinterpret_cast<unsigned char *>(iv)
);
}

threadEnv->ReleasePrimitiveArrayCritical(prevJniBuffer, prevBuffer, JNI_ABORT);

threadEnv->SetByteArrayRegion(
prevJniBuffer, 0, (remainingBlocks - excludeLastBlock) * AES_BLOCK_SIZE,
reinterpret_cast<jbyte *>(decryptedBuffer)
Expand All @@ -555,8 +560,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d

Krypt::ByteArray recover;

prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, NULL);

prevBuffer = (jbyte *) threadEnv->GetPrimitiveArrayCritical(prevJniBuffer, nullptr);
if (excludeLastBlock) {
recover = aes_scheme.decrypt(
reinterpret_cast<unsigned char *>(prevBuffer + (index * AES_BLOCK_SIZE)),
Expand All @@ -570,9 +574,9 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
reinterpret_cast<unsigned char *>(iv)
);
}

threadEnv->ReleasePrimitiveArrayCritical(prevJniBuffer, prevBuffer, JNI_ABORT);
threadEnv->ReleaseByteArrayElements(jniIV, iv, 0);

threadEnv->ReleaseByteArrayElements(jniIV, iv, JNI_ABORT);

threadEnv->SetByteArrayRegion(
prevJniBuffer, 0, recover.length,
Expand Down Expand Up @@ -604,7 +608,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
}
};

int physical_threads = std::thread::hardware_concurrency();
int physical_threads = (int) std::thread::hardware_concurrency();

std::vector<std::thread> threads;

Expand All @@ -614,7 +618,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
vector_mtx.unlock();

if (notEmpty) {
threads.push_back(std::thread(decrypt_lambda));
threads.emplace_back(decrypt_lambda);
}
}

Expand All @@ -626,8 +630,8 @@ extern "C" JNIEXPORT jint JNICALL Java_com_application_bethela_BethelaActivity_d
decrypt_lambda();
}

for (size_t i = 0; i < threads.size(); ++i) {
threads[i].join();
for (auto & thrd : threads) {
thrd.join();
}

env->DeleteGlobalRef(DocumentFileClass);
Expand Down
16 changes: 13 additions & 3 deletions app/src/main/java/com/application/bethela/BethelaActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public void onActivityResult(ActivityResult result) {
for (int i = 0; i < urisFiles.size(); ++i) {
displayTargetFiles
.append(getFileName(getApplicationContext(), urisFiles.get(i)))
.append("\n\n");
.append("\n");
}

tvFiles.setText(displayTargetFiles.toString());
Expand Down Expand Up @@ -466,19 +466,24 @@ public void btnEncryptFiles (View v) {
@Override
public void run() {
int res = 0;
long totalTime = 0;

synchronized (this) {
long startTime = System.nanoTime();
res = encryptFiles(AES256_KEY, urisFiles, uriOutputFolder);
long endTime = System.nanoTime();
totalTime = (endTime - startTime) / 1000000000L;
}

int finalRes = res;
long finalTotalTime = totalTime;
handler.post(new Runnable() {
@Override
public void run() {
if (finalRes < 0) {
Toast.makeText(BethelaActivity.this, "Encrypt Error, Invalid Internal Buffer", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(BethelaActivity.this, "Encrypted " + finalRes + "/" + totalFiles, Toast.LENGTH_SHORT).show();
Toast.makeText(BethelaActivity.this, "Encrypted " + finalRes + "/" + totalFiles + " | " + finalTotalTime + "s", Toast.LENGTH_SHORT).show();
}
btnClearFiles(null);

Expand Down Expand Up @@ -515,19 +520,24 @@ public void btnDecryptFiles (View v) {
@Override
public void run() {
int res = 0;
long totalTime = 0;

synchronized (this) {
long startTime = System.nanoTime();
res = decryptFiles(AES256_KEY, urisFiles, uriOutputFolder);
long endTime = System.nanoTime();
totalTime = (endTime - startTime) / 1000000000L;
}

int finalRes = res;
long finalTotalTime = totalTime;
handler.post(new Runnable() {
@Override
public void run() {
if (finalRes < 0) {
Toast.makeText(BethelaActivity.this, "Decrypt Error, Invalid Internal Buffer", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(BethelaActivity.this, "Decrypted " + finalRes + "/" + totalFiles, Toast.LENGTH_SHORT).show();
Toast.makeText(BethelaActivity.this, "Decrypted " + finalRes + "/" + totalFiles + " | " + finalTotalTime + "s", Toast.LENGTH_SHORT).show();
}

btnClearFiles(null);
Expand Down

0 comments on commit 36b0962

Please sign in to comment.