Skip to content

Commit 81b9545

Browse files
committed
optimized AES decryption's memory allocations
1 parent 828e313 commit 81b9545

File tree

2 files changed

+66
-62
lines changed

2 files changed

+66
-62
lines changed

main.cpp

Lines changed: 54 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define CRYPTOLIB "portable"
2525
#endif
2626

27-
#define BETHELA_VERSION "version 3.6.1"
27+
#define BETHELA_VERSION "version 3.7.0"
2828

2929
#define HELP_FLAG "--help"
3030
#define VERSION_FLAG "--version"
@@ -426,10 +426,7 @@ int main(int argc, char *args[]) {
426426

427427
bool run_thread = true;
428428

429-
char *next_buffer = new char[BUFFER_BYTESIZE];
430-
char *prev_buffer = new char[BUFFER_BYTESIZE];
431-
Krypt::Bytes *decryptedBuffer = new Krypt::Bytes[BUFFER_BYTESIZE];
432-
429+
char *read_buffer = new char[BUFFER_BYTESIZE];
433430
char *filesig = new char[bconst::FILESIGNATURE.size()];
434431

435432
while (run_thread) {
@@ -461,6 +458,7 @@ int main(int argc, char *args[]) {
461458
"it might be read protected, corrupted or non-existent...\n";
462459
output_mtx.unlock();
463460
} else {
461+
464462
output_mtx.lock();
465463
std::cout << "decrypting : " << target_file << "...\n";
466464
output_mtx.unlock();
@@ -478,90 +476,85 @@ int main(int argc, char *args[]) {
478476
output_file.close();
479477
output_file.open(outfname, std::ios::binary | std::ios::app);
480478

481-
unsigned char *iv = new unsigned char[AES_BLOCKSIZE];
479+
unsigned char iv[AES_BLOCKSIZE];
482480
curr_file.read(reinterpret_cast<char *>(iv), AES_BLOCKSIZE);
483481

484-
char *swap_buffer_ptr;
482+
// new decryption
485483

486-
curr_file.read(prev_buffer, BUFFER_BYTESIZE);
487-
size_t prev_buffer_size = curr_file.gcount();
488-
size_t next_buffer_size = 0;
484+
constexpr size_t BUFFER_SIZE_NOLAST = BUFFER_BYTESIZE - AES_BLOCKSIZE;
485+
char decrypted_block_holder[AES_BLOCKSIZE] = {};
486+
char last_block[AES_BLOCKSIZE] = {};
489487

490-
while (!curr_file.eof()) {
491-
curr_file.read(next_buffer, BUFFER_BYTESIZE);
492-
next_buffer_size = curr_file.gcount();
488+
bool lastblock_remains = false;
493489

494-
if (!next_buffer_size) {
495-
break;
496-
}
490+
while (!curr_file.eof()) {
491+
curr_file.read(read_buffer, BUFFER_BYTESIZE);
492+
size_t read_buffer_size = curr_file.gcount();
497493

498-
for (size_t index = 0; index < prev_buffer_size; index += AES_BLOCKSIZE) {
499-
aes_scheme.blockDecrypt(
500-
reinterpret_cast<unsigned char *>(prev_buffer + index),
501-
reinterpret_cast<unsigned char *>(decryptedBuffer + index), iv
502-
);
494+
if (lastblock_remains) {
495+
if (read_buffer_size) {
496+
aes_scheme.blockDecrypt(
497+
reinterpret_cast<unsigned char *>(last_block),
498+
reinterpret_cast<unsigned char *>(decrypted_block_holder), iv
499+
);
500+
output_file.write(reinterpret_cast<char *>(decrypted_block_holder), AES_BLOCKSIZE);
501+
lastblock_remains = false;
502+
} else {
503+
break;
504+
}
503505
}
504506

505-
output_file.write(reinterpret_cast<char *>(decryptedBuffer), prev_buffer_size);
506-
507-
swap_buffer_ptr = next_buffer;
508-
next_buffer = prev_buffer;
509-
prev_buffer = swap_buffer_ptr;
510-
swap_buffer_ptr = nullptr;
511-
std::swap(next_buffer_size, prev_buffer_size);
512-
}
513-
514-
size_t remaining_blocks = prev_buffer_size / AES_BLOCKSIZE;
515-
size_t remaining_bytes = prev_buffer_size % AES_BLOCKSIZE;
516-
size_t index = 0;
507+
if (read_buffer_size == BUFFER_BYTESIZE) {
508+
size_t index;
509+
for (index = 0; index < BUFFER_SIZE_NOLAST; index += AES_BLOCKSIZE) {
510+
aes_scheme.blockDecrypt(
511+
reinterpret_cast<unsigned char *>(read_buffer + index),
512+
reinterpret_cast<unsigned char *>(decrypted_block_holder), iv
513+
);
514+
std::memcpy(read_buffer + index, decrypted_block_holder, AES_BLOCKSIZE);
515+
}
517516

518-
bool excludeLastBlock = (remaining_blocks && remaining_bytes == 0);
517+
output_file.write(reinterpret_cast<char *>(read_buffer), BUFFER_SIZE_NOLAST);
518+
std::memcpy(last_block, read_buffer + index, AES_BLOCKSIZE);
519+
} else if (read_buffer_size % AES_BLOCKSIZE == 0) {
520+
size_t index;
521+
for (index = 0; index < read_buffer_size - AES_BLOCKSIZE; index += AES_BLOCKSIZE) {
522+
aes_scheme.blockDecrypt(
523+
reinterpret_cast<unsigned char *>(read_buffer + index),
524+
reinterpret_cast<unsigned char *>(decrypted_block_holder), iv
525+
);
526+
std::memcpy(read_buffer + index, decrypted_block_holder, AES_BLOCKSIZE);
527+
}
519528

520-
if (remaining_blocks) {
521-
for (index = 0; index < remaining_blocks - excludeLastBlock; ++index) {
522-
aes_scheme.blockDecrypt(
523-
reinterpret_cast<unsigned char *>(prev_buffer + (index * AES_BLOCKSIZE)),
524-
reinterpret_cast<unsigned char *>(decryptedBuffer + (index * AES_BLOCKSIZE)), iv
525-
);
529+
output_file.write(reinterpret_cast<char *>(read_buffer), read_buffer_size - AES_BLOCKSIZE);
530+
std::memcpy(last_block, read_buffer + index, AES_BLOCKSIZE);
526531
}
527532

528-
output_file.write(
529-
reinterpret_cast<char *>(decryptedBuffer), (remaining_blocks - excludeLastBlock) * AES_BLOCKSIZE
530-
);
533+
lastblock_remains = true;
531534
}
532535

533-
Krypt::ByteArray recover;
536+
if (lastblock_remains) {
537+
Krypt::ByteArray recover =
538+
aes_scheme.decrypt(reinterpret_cast<unsigned char *>(last_block), AES_BLOCKSIZE, iv);
534539

535-
if (excludeLastBlock) {
536-
recover = aes_scheme.decrypt(
537-
reinterpret_cast<unsigned char *>(prev_buffer + (index * AES_BLOCKSIZE)), AES_BLOCKSIZE, iv
538-
);
539-
} else {
540-
recover = aes_scheme.decrypt(
541-
reinterpret_cast<unsigned char *>(prev_buffer + (index * AES_BLOCKSIZE)), remaining_bytes, iv
542-
);
540+
output_file.write(reinterpret_cast<char *>(recover.array), recover.length);
541+
lastblock_remains = false;
543542
}
544543

545-
output_file.write(reinterpret_cast<char *>(recover.array), recover.length);
544+
// new decryption
546545

547546
cnt++;
548547

549548
std::memset((unsigned char *) iv, 0x00, AES_BLOCKSIZE);
550-
delete[] iv;
551-
552549
checkif_replace(args[COMMAND], target_file);
553550
}
554551
}
555552

556-
std::memset((char *) next_buffer, 0x00, BUFFER_BYTESIZE);
557-
std::memset((char *) prev_buffer, 0x00, BUFFER_BYTESIZE);
553+
std::memset((char *) read_buffer, 0x00, BUFFER_BYTESIZE);
558554
std::memset((char *) filesig, 0x00, bconst::FILESIGNATURE.size());
559-
std::memset((Krypt::Bytes *) decryptedBuffer, 0x00, BUFFER_BYTESIZE);
560555

561-
delete[] next_buffer;
562-
delete[] prev_buffer;
556+
delete[] read_buffer;
563557
delete[] filesig;
564-
delete[] decryptedBuffer;
565558
};
566559

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

tests/FileCompare.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,18 @@ bool ISEQUAL(const std::string &FileA, const std::string &FileB) {
1010
bconst::bytestream B = byteio::file_read(FileB);
1111

1212
if (A.size() != B.size()) {
13-
std::cout << "\n\t\tSize is not equal\n";
13+
std::cout << "\n\t\tSize is not equal (" << A.size() << ", " << B.size() << ")";
14+
15+
size_t not_equal = 0;
16+
for (size_t i = 0; i < A.size(); ++i) {
17+
if (A[i] != B[i]) {
18+
not_equal++;
19+
}
20+
}
21+
22+
float equality = ((float) A.size() - (float) not_equal) / (float) A.size();
23+
std::cout << "\n\t\tEqual by : " << equality * 100.0f << " percent\n";
24+
1425
return false;
1526
} else if (A.size() <= 0 || B.size() <= 0) {
1627
return false;

0 commit comments

Comments
 (0)