From f9665896e3deb6c449c764ba8b30f700abe36cd5 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Tue, 20 Oct 2015 03:11:50 +0300 Subject: cxx: implement "boxes" --- utils/CMakeLists.txt | 12 +-- utils/block_cmd_parser.hpp | 19 ++++ utils/decrypt_block.cpp | 224 +++++++++++++++++++++------------------------ utils/decrypt_bmp.cpp | 177 +++++++++++++---------------------- utils/decrypt_file.cpp | 172 ++++++++++++---------------------- utils/encrypt_block.cpp | 223 +++++++++++++++++++++----------------------- utils/encrypt_bmp.cpp | 174 +++++++++++++---------------------- utils/encrypt_file.cpp | 172 ++++++++++++---------------------- utils/file_cmd_parser.hpp | 25 +++++ 9 files changed, 511 insertions(+), 687 deletions(-) (limited to 'utils') diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index ca2c313..4643c5e 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -2,30 +2,30 @@ find_package(Boost REQUIRED COMPONENTS program_options) add_executable(util_encrypt_block encrypt_block.cpp block_cmd_parser.hpp block_dumper.hpp data_parsers.hpp) target_include_directories(util_encrypt_block PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(util_encrypt_block libaesni libaesnixx ${Boost_LIBRARIES}) +target_link_libraries(util_encrypt_block libaesnixx ${Boost_LIBRARIES}) set_target_properties(util_encrypt_block PROPERTIES OUTPUT_NAME encrypt_block) add_executable(util_decrypt_block decrypt_block.cpp block_cmd_parser.hpp block_dumper.hpp data_parsers.hpp) target_include_directories(util_decrypt_block PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(util_decrypt_block libaesni libaesnixx ${Boost_LIBRARIES}) +target_link_libraries(util_decrypt_block libaesnixx ${Boost_LIBRARIES}) set_target_properties(util_decrypt_block PROPERTIES OUTPUT_NAME decrypt_block) add_executable(util_encrypt_file encrypt_file.cpp file_cmd_parser.hpp data_parsers.hpp) target_include_directories(util_encrypt_file PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(util_encrypt_file libaesni libaesnixx ${Boost_LIBRARIES}) +target_link_libraries(util_encrypt_file libaesnixx ${Boost_LIBRARIES}) set_target_properties(util_encrypt_file PROPERTIES OUTPUT_NAME encrypt_file) add_executable(util_decrypt_file decrypt_file.cpp file_cmd_parser.hpp data_parsers.hpp) target_include_directories(util_decrypt_file PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(util_decrypt_file libaesni libaesnixx ${Boost_LIBRARIES}) +target_link_libraries(util_decrypt_file libaesnixx ${Boost_LIBRARIES}) set_target_properties(util_decrypt_file PROPERTIES OUTPUT_NAME decrypt_file) add_executable(util_encrypt_bmp encrypt_bmp.cpp file_cmd_parser.hpp data_parsers.hpp) target_include_directories(util_encrypt_bmp PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(util_encrypt_bmp libaesni libaesnixx ${Boost_LIBRARIES}) +target_link_libraries(util_encrypt_bmp libaesnixx ${Boost_LIBRARIES}) set_target_properties(util_encrypt_bmp PROPERTIES OUTPUT_NAME encrypt_bmp) add_executable(util_decrypt_bmp decrypt_bmp.cpp file_cmd_parser.hpp data_parsers.hpp) target_include_directories(util_decrypt_bmp PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(util_decrypt_bmp libaesni libaesnixx ${Boost_LIBRARIES}) +target_link_libraries(util_decrypt_bmp libaesnixx ${Boost_LIBRARIES}) set_target_properties(util_decrypt_bmp PROPERTIES OUTPUT_NAME decrypt_bmp) diff --git a/utils/block_cmd_parser.hpp b/utils/block_cmd_parser.hpp index c191154..50334e7 100644 --- a/utils/block_cmd_parser.hpp +++ b/utils/block_cmd_parser.hpp @@ -12,6 +12,7 @@ #include +#include #include #include @@ -20,6 +21,24 @@ namespace { + BOOST_NORETURN inline void throw_iv_required() + { + throw boost::program_options::error( + "initialization vector is required for the selected mode of operation"); + } + + BOOST_NORETURN inline void throw_not_implemented(aesni::Algorithm algorithm) + { + throw boost::program_options::error( + "the selected algorithm is not implemented"); + } + + BOOST_NORETURN inline void throw_not_implemented(aesni::Mode mode) + { + throw boost::program_options::error( + "the selected mode of operation is not implemented"); + } + class CommandLineParser { public: diff --git a/utils/decrypt_block.cpp b/utils/decrypt_block.cpp index 7c8e773..b9f9d19 100644 --- a/utils/decrypt_block.cpp +++ b/utils/decrypt_block.cpp @@ -9,8 +9,6 @@ #include "block_cmd_parser.hpp" #include "block_dumper.hpp" -#include - #include #include @@ -24,7 +22,7 @@ namespace { template - bool decrypt_with_mode( + void decrypt_with_mode( const std::string& key_str, std::deque& ciphertexts, bool verbose = false) @@ -34,7 +32,7 @@ namespace if (aesni::ModeRequiresInitializationVector()) { if (ciphertexts.empty()) - return false; + throw_iv_required(); aesni::from_string(iv, ciphertexts.front()); ciphertexts.pop_front(); @@ -73,12 +71,10 @@ namespace std::cout << aesni::to_string(plaintext) << "\n"; } } - - return true; } template - bool decrypt_with_algorithm( + void decrypt_with_algorithm( aesni::Mode mode, const std::string& key_str, std::deque& ciphertexts, @@ -87,126 +83,100 @@ namespace switch (mode) { case AESNI_ECB: - return decrypt_with_mode(key_str, ciphertexts, verbose); + decrypt_with_mode(key_str, ciphertexts, verbose); + break; case AESNI_CBC: - return decrypt_with_mode(key_str, ciphertexts, verbose); + decrypt_with_mode(key_str, ciphertexts, verbose); + break; case AESNI_CFB: - return decrypt_with_mode(key_str, ciphertexts, verbose); + decrypt_with_mode(key_str, ciphertexts, verbose); + break; case AESNI_OFB: - return decrypt_with_mode(key_str, ciphertexts, verbose); + decrypt_with_mode(key_str, ciphertexts, verbose); + break; case AESNI_CTR: - return decrypt_with_mode(key_str, ciphertexts, verbose); + decrypt_with_mode(key_str, ciphertexts, verbose); + break; default: - return false; + throw_not_implemented(mode); + break; } } - bool decrypt_using_cxx_api( + void decrypt_using_cxx_api( aesni::Algorithm algorithm, aesni::Mode mode, const std::string& key_str, - std::deque ciphertexts, + std::deque& ciphertexts, bool verbose = false) { switch (algorithm) { case AESNI_AES128: - return decrypt_with_algorithm(mode, key_str, ciphertexts, verbose); + decrypt_with_algorithm(mode, key_str, ciphertexts, verbose); + break; case AESNI_AES192: - return decrypt_with_algorithm(mode, key_str, ciphertexts, verbose); + decrypt_with_algorithm(mode, key_str, ciphertexts, verbose); + break; case AESNI_AES256: - return decrypt_with_algorithm(mode, key_str, ciphertexts, verbose); + decrypt_with_algorithm(mode, key_str, ciphertexts, verbose); + break; default: - return false; + throw_not_implemented(algorithm); + break; } } - template - bool decrypt_using_boxes_with_algorithm( - const AesNI_BoxKey& box_key, - aesni::Mode mode, - const std::string& key, - std::deque ciphertexts) + void decrypt_using_particular_box( + aesni::Box& box, + std::deque& ciphertexts) { - AesNI_BoxBlock iv; - AesNI_BoxBlock* iv_ptr = nullptr; - - if (aesni::mode_requires_initialization_vector(mode)) - { - if (ciphertexts.empty()) - return false; - - aesni::from_string(iv.aes_block, ciphertexts.front()); - iv_ptr = &iv; - ciphertexts.pop_front(); - } - - AesNI_Box box; - aesni_box_init( - &box, - algorithm, - &box_key, - mode, - iv_ptr, - aesni::ErrorDetailsThrowsInDestructor()); - while (!ciphertexts.empty()) { - AesNI_BoxBlock ciphertext; - aesni::from_string(ciphertext.aes_block, ciphertexts.front()); + aesni::Box::Block ciphertext; + box.parse_block(ciphertext, ciphertexts.front()); ciphertexts.pop_front(); - AesNI_BoxBlock plaintext; - aesni_box_decrypt_block( - &box, - &ciphertext, - &plaintext, - aesni::ErrorDetailsThrowsInDestructor()); + aesni::Box::Block plaintext; + box.decrypt_block(ciphertext, plaintext); - std::cout << aesni::to_string(plaintext.aes_block) << "\n"; + std::cout << box.format_block(plaintext) << "\n"; } - - return true; } - bool decrypt_using_boxes( + void decrypt_using_boxes( aesni::Algorithm algorithm, aesni::Mode mode, - const std::string& key, - std::deque ciphertexts) + const std::string& key_str, + std::deque& ciphertexts) { - AesNI_BoxKey box_key; + aesni::Box::Key key; + aesni::Box::parse_key(key, algorithm, key_str); - switch (algorithm) + if (aesni::mode_requires_initialization_vector(mode)) { - case AESNI_AES128: - aesni::from_string( - box_key.aes128_key, key); - return decrypt_using_boxes_with_algorithm( - box_key, mode, key, ciphertexts); - - case AESNI_AES192: - aesni::from_string( - box_key.aes192_key, key); - return decrypt_using_boxes_with_algorithm( - box_key, mode, key, ciphertexts); + if (ciphertexts.empty()) + throw_iv_required(); - case AESNI_AES256: - aesni::from_string( - box_key.aes256_key, key); - return decrypt_using_boxes_with_algorithm( - box_key, mode, key, ciphertexts); + aesni::Box::Block iv; + aesni::Box::parse_block(iv, algorithm, ciphertexts.front()); + ciphertexts.pop_front(); - default: - return false; + decrypt_using_particular_box( + aesni::Box(algorithm, key, mode, iv), ciphertexts); + } + else + { + decrypt_using_particular_box( + aesni::Box(algorithm, key), ciphertexts); } } } @@ -216,62 +186,76 @@ int main(int argc, char** argv) try { CommandLineParser cmd_parser("decrypt_block.exe"); - cmd_parser.parse(argc, argv); - - if (cmd_parser.requested_help()) + try { - std::cout << cmd_parser; - return 0; - } + cmd_parser.parse(argc, argv); - std::deque args{ std::make_move_iterator(cmd_parser.args.begin()), - std::make_move_iterator(cmd_parser.args.end()) }; - - while (!args.empty()) - { - const auto key = args.front(); - args.pop_front(); + if (cmd_parser.requested_help()) + { + std::cout << cmd_parser; + return 0; + } - std::deque ciphertexts; + std::deque args( + std::make_move_iterator(cmd_parser.args.begin()), + std::make_move_iterator(cmd_parser.args.end())); while (!args.empty()) { - if (args.front() == "--") + const auto key = args.front(); + args.pop_front(); + + std::deque ciphertexts; + + while (!args.empty()) { + if (args.front() == "--") + { + args.pop_front(); + break; + } + + ciphertexts.push_back(args.front()); args.pop_front(); - break; } - ciphertexts.push_back(args.front()); - args.pop_front(); + if (cmd_parser.use_boxes) + { + decrypt_using_boxes( + cmd_parser.algorithm, + cmd_parser.mode, + key, + ciphertexts); + } + else + { + decrypt_using_cxx_api( + cmd_parser.algorithm, + cmd_parser.mode, + key, + ciphertexts, + cmd_parser.verbose); + } } - const auto success = cmd_parser.use_boxes - ? decrypt_using_boxes(cmd_parser.algorithm, cmd_parser.mode, key, ciphertexts) - : decrypt_using_cxx_api(cmd_parser.algorithm, cmd_parser.mode, key, ciphertexts, cmd_parser.verbose); - - if (!success) - { - std::cout << cmd_parser; - return 1; - } + return 0; + } + catch (const boost::program_options::error& e) + { + std::cerr << "Usage error: " << e.what() << "\n"; + std::cerr << cmd_parser; + return 1; + } + catch (const aesni::Error& e) + { + std::cerr << e; + return 1; } - - return 0; - } - catch (const boost::program_options::error& e) - { - std::cerr << "Usage error: " << e.what() << "\n"; - return 1; - } - catch (const aesni::Error& e) - { - std::cerr << e; - return 1; } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } + return 0; } diff --git a/utils/decrypt_bmp.cpp b/utils/decrypt_bmp.cpp index 802283d..559b5d5 100644 --- a/utils/decrypt_bmp.cpp +++ b/utils/decrypt_bmp.cpp @@ -8,8 +8,6 @@ #include "file_cmd_parser.hpp" -#include - #include #include @@ -47,43 +45,35 @@ namespace std::vector src_buf; src_buf.reserve(size); - src_buf.assign(std::istreambuf_iterator(ifs), - std::istreambuf_iterator()); + src_buf.assign( + std::istreambuf_iterator(ifs), + std::istreambuf_iterator()); return src_buf; } - void write_file(const std::string& path, const std::vector& src) + void write_file( + const std::string& path, + const std::vector& src) { std::ofstream ofs; ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit); ofs.open(path, std::ofstream::binary); - ofs.write(src.data(), src.size()); + ofs.write(reinterpret_cast(src.data()), src.size()); } - template - bool decrypt_bmp_with_algorithm( - const AesNI_BoxKey& box_key, - aesni::Mode mode, + void decrypt_bmp( + aesni::Box& box, std::deque& args) { - AesNI_BoxBlock iv; - AesNI_BoxBlock* iv_ptr = nullptr; - - if (aesni::mode_requires_initialization_vector(mode)) - { - if (args.empty()) - return false; - - aesni::from_string(iv.aes_block, args.front()); - iv_ptr = &iv; - args.pop_front(); - } - - if (args.size() != 2) - return false; + if (args.empty()) + throw_src_path_required(); + const auto src_path = args.front(); + args.pop_front(); - const auto src_path = args[0]; - const auto dest_path = args[1]; + if (args.empty()) + throw_dest_path_required(); + const auto dest_path = args.front(); + args.pop_front(); const auto src_buf = read_file(src_path); @@ -93,79 +83,44 @@ namespace const auto cipherpixels = src_buf.data() + header_size; const auto cipherpixels_size = src_buf.size() - header_size; - AesNI_Box box; - - aesni_box_init( - &box, - algorithm, - &box_key, - mode, - iv_ptr, - aesni::ErrorDetailsThrowsInDestructor()); - - std::size_t pixels_size; - - aesni_box_decrypt_buffer( - &box, - cipherpixels, - cipherpixels_size, - nullptr, - &pixels_size, - aesni::ErrorDetailsThrowsInDestructor()); - - std::vector dest_buf; - dest_buf.resize(header_size + pixels_size); - std::memcpy(dest_buf.data(), src_buf.data(), header_size); - - aesni_box_decrypt_buffer( - &box, - cipherpixels, - cipherpixels_size, - dest_buf.data() + header_size, - &pixels_size, - aesni::ErrorDetailsThrowsInDestructor()); - - dest_buf.resize(header_size + pixels_size); - write_file(dest_path, dest_buf); + const auto pixels = box.decrypt_buffer( + cipherpixels, cipherpixels_size); + + std::vector dest_buf(header_size + pixels.size()); + std::memcpy(&dest_buf[0], bmp_header, header_size); + std::memcpy(&dest_buf[0] + header_size, pixels.data(), pixels.size()); - return true; + write_file(dest_path, dest_buf); } - bool decrypt_bmp( + void decrypt_bmp( aesni::Algorithm algorithm, aesni::Mode mode, std::deque& args) { if (args.empty()) - return false; + throw_key_required(); + + aesni::Box::Key key; + aesni::Box::parse_key(key, algorithm, args.front()); + args.pop_front(); + + if (aesni::mode_requires_initialization_vector(mode)) + { + if (args.empty()) + throw_iv_required(); - AesNI_BoxKey box_key; + aesni::Box::Block iv; + aesni::Box::parse_block(iv, algorithm, args.front()); + args.pop_front(); - switch (algorithm) + decrypt_bmp( + aesni::Box(algorithm, key, mode, iv), args); + } + else { - case AESNI_AES128: - aesni::from_string( - box_key.aes128_key, args.front()); - args.pop_front(); - return decrypt_bmp_with_algorithm( - box_key, mode, args); - - case AESNI_AES192: - aesni::from_string( - box_key.aes192_key, args.front()); - args.pop_front(); - return decrypt_bmp_with_algorithm( - box_key, mode, args); - - case AESNI_AES256: - aesni::from_string( - box_key.aes256_key, args.front()); - args.pop_front(); - return decrypt_bmp_with_algorithm( - box_key, mode, args); - - default: - return false; + decrypt_bmp( + aesni::Box(algorithm, key), args); } } } @@ -175,38 +130,38 @@ int main(int argc, char** argv) try { CommandLineParser cmd_parser("decrypt_bmp.exe"); - cmd_parser.parse(argc, argv); - - if (cmd_parser.requested_help()) + try { - std::cout << cmd_parser; - return 0; - } + cmd_parser.parse(argc, argv); + + if (cmd_parser.requested_help()) + { + std::cout << cmd_parser; + return 0; + } - std::deque args{ std::make_move_iterator(cmd_parser.args.begin()), - std::make_move_iterator(cmd_parser.args.end()) }; + std::deque args( + std::make_move_iterator(cmd_parser.args.begin()), + std::make_move_iterator(cmd_parser.args.end())); - if (!decrypt_bmp(cmd_parser.algorithm, cmd_parser.mode, args)) + decrypt_bmp(cmd_parser.algorithm, cmd_parser.mode, args); + } + catch (const boost::program_options::error& e) { - std::cout << cmd_parser; + std::cerr << "Usage error: " << e.what() << "\n"; + std::cerr << cmd_parser; + return 1; + } + catch (const aesni::Error& e) + { + std::cerr << e; return 1; } - - return 0; - } - catch (const boost::program_options::error& e) - { - std::cerr << "Usage error: " << e.what() << "\n"; - return 1; - } - catch (const aesni::Error& e) - { - std::cerr << e; - return 1; } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } + return 0; } diff --git a/utils/decrypt_file.cpp b/utils/decrypt_file.cpp index d8c42c4..092b249 100644 --- a/utils/decrypt_file.cpp +++ b/utils/decrypt_file.cpp @@ -8,8 +8,6 @@ #include "file_cmd_parser.hpp" -#include - #include #include @@ -44,118 +42,70 @@ namespace std::vector src_buf; src_buf.reserve(size); - src_buf.assign(std::istreambuf_iterator(ifs), - std::istreambuf_iterator()); + src_buf.assign( + std::istreambuf_iterator(ifs), + std::istreambuf_iterator()); return src_buf; } - void write_file(const std::string& path, const std::vector& src) + void write_file( + const std::string& path, + const std::vector& src) { std::ofstream ofs; ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit); ofs.open(path, std::ofstream::binary); - ofs.write(src.data(), src.size()); + ofs.write(reinterpret_cast(src.data()), src.size()); } - template - bool decrypt_file_with_algorithm( - const AesNI_BoxKey& box_key, - aesni::Mode mode, + void decrypt_file( + aesni::Box& box, std::deque& args) { - AesNI_BoxBlock iv; - AesNI_BoxBlock* iv_ptr = nullptr; - - if (aesni::mode_requires_initialization_vector(mode)) - { - if (args.empty()) - return false; - - aesni::from_string(iv.aes_block, args.front()); - iv_ptr = &iv; - args.pop_front(); - } - - if (args.size() != 2) - return false; + if (args.empty()) + throw_src_path_required(); + const auto src_path = args.front(); + args.pop_front(); - const auto src_path = args[0]; - const auto dest_path = args[1]; + if (args.empty()) + throw_dest_path_required(); + const auto dest_path = args.front(); + args.pop_front(); const auto src_buf = read_file(src_path); - - AesNI_Box box; - - aesni_box_init( - &box, - algorithm, - &box_key, - mode, - iv_ptr, - aesni::ErrorDetailsThrowsInDestructor()); - - std::size_t dest_size; - - aesni_box_decrypt_buffer( - &box, - src_buf.data(), - src_buf.size(), - nullptr, - &dest_size, - aesni::ErrorDetailsThrowsInDestructor()); - - std::vector dest_buf; - dest_buf.resize(dest_size); - - aesni_box_decrypt_buffer( - &box, - src_buf.data(), - src_buf.size(), - dest_buf.data(), - &dest_size, - aesni::ErrorDetailsThrowsInDestructor()); - - dest_buf.resize(dest_size); + const auto dest_buf = box.decrypt_buffer( + src_buf.data(), src_buf.size()); write_file(dest_path, dest_buf); - - return true; } - bool decrypt_file( + void decrypt_file( aesni::Algorithm algorithm, aesni::Mode mode, std::deque& args) { if (args.empty()) - return false; + throw_key_required(); - AesNI_BoxKey box_key; + aesni::Box::Key key; + aesni::Box::parse_key(key, algorithm, args.front()); + args.pop_front(); - switch (algorithm) + if (aesni::mode_requires_initialization_vector(mode)) { - case AESNI_AES128: - aesni::from_string( - box_key.aes128_key, args.front()); - args.pop_front(); - return decrypt_file_with_algorithm( - box_key, mode, args); - - case AESNI_AES192: - aesni::from_string( - box_key.aes192_key, args.front()); - args.pop_front(); - return decrypt_file_with_algorithm( - box_key, mode, args); - - case AESNI_AES256: - aesni::from_string( - box_key.aes256_key, args.front()); - args.pop_front(); - return decrypt_file_with_algorithm( - box_key, mode, args); - - default: - return false; + if (args.empty()) + throw_iv_required(); + + aesni::Box::Block iv; + aesni::Box::parse_block(iv, algorithm, args.front()); + args.pop_front(); + + decrypt_file( + aesni::Box(algorithm, key, mode, iv), args); + } + else + { + decrypt_file( + aesni::Box(algorithm, key), args); } } } @@ -165,38 +115,38 @@ int main(int argc, char** argv) try { CommandLineParser cmd_parser("decrypt_file.exe"); - cmd_parser.parse(argc, argv); - - if (cmd_parser.requested_help()) + try { - std::cout << cmd_parser; - return 0; - } + cmd_parser.parse(argc, argv); - std::deque args{ std::make_move_iterator(cmd_parser.args.begin()), - std::make_move_iterator(cmd_parser.args.end()) }; + if (cmd_parser.requested_help()) + { + std::cout << cmd_parser; + return 0; + } - if (!decrypt_file(cmd_parser.algorithm, cmd_parser.mode, args)) + std::deque args( + std::make_move_iterator(cmd_parser.args.begin()), + std::make_move_iterator(cmd_parser.args.end())); + + decrypt_file(cmd_parser.algorithm, cmd_parser.mode, args); + } + catch (const boost::program_options::error& e) { - std::cout << cmd_parser; + std::cerr << "Usage error: " << e.what() << "\n"; + std::cerr << cmd_parser; + return 1; + } + catch (const aesni::Error& e) + { + std::cerr << e; return 1; } - - return 0; - } - catch (const boost::program_options::error& e) - { - std::cerr << "Usage error: " << e.what() << "\n"; - return 1; - } - catch (const aesni::Error& e) - { - std::cerr << e; - return 1; } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } + return 0; } diff --git a/utils/encrypt_block.cpp b/utils/encrypt_block.cpp index 1a62bda..01ea745 100644 --- a/utils/encrypt_block.cpp +++ b/utils/encrypt_block.cpp @@ -9,8 +9,6 @@ #include "block_cmd_parser.hpp" #include "block_dumper.hpp" -#include - #include #include @@ -24,7 +22,7 @@ namespace { template - bool encrypt_with_mode( + void encrypt_with_mode( const std::string& key_str, std::deque& plaintexts, bool verbose = false) @@ -34,7 +32,7 @@ namespace if (aesni::ModeRequiresInitializationVector::value) { if (plaintexts.empty()) - return false; + throw_iv_required(); aesni::from_string(iv, plaintexts.front()); plaintexts.pop_front(); @@ -72,12 +70,10 @@ namespace std::cout << aesni::to_string(ciphertext) << "\n"; } } - - return true; } template - bool encrypt_with_algorithm( + void encrypt_with_algorithm( aesni::Mode mode, const std::string& key_str, std::deque& plaintexts, @@ -86,26 +82,32 @@ namespace switch (mode) { case AESNI_ECB: - return encrypt_with_mode(key_str, plaintexts, verbose); + encrypt_with_mode(key_str, plaintexts, verbose); + break; case AESNI_CBC: - return encrypt_with_mode(key_str, plaintexts, verbose); + encrypt_with_mode(key_str, plaintexts, verbose); + break; case AESNI_CFB: - return encrypt_with_mode(key_str, plaintexts, verbose); + encrypt_with_mode(key_str, plaintexts, verbose); + break; case AESNI_OFB: - return encrypt_with_mode(key_str, plaintexts, verbose); + encrypt_with_mode(key_str, plaintexts, verbose); + break; case AESNI_CTR: - return encrypt_with_mode(key_str, plaintexts, verbose); + encrypt_with_mode(key_str, plaintexts, verbose); + break; default: - return false; + throw_not_implemented(mode); + break; } } - bool encrypt_using_cxx_api( + void encrypt_using_cxx_api( aesni::Algorithm algorithm, aesni::Mode mode, const std::string& key_str, @@ -115,97 +117,66 @@ namespace switch (algorithm) { case AESNI_AES128: - return encrypt_with_algorithm(mode, key_str, plaintexts, verbose); + encrypt_with_algorithm(mode, key_str, plaintexts, verbose); + break; case AESNI_AES192: - return encrypt_with_algorithm(mode, key_str, plaintexts, verbose); + encrypt_with_algorithm(mode, key_str, plaintexts, verbose); + break; case AESNI_AES256: - return encrypt_with_algorithm(mode, key_str, plaintexts, verbose); + encrypt_with_algorithm(mode, key_str, plaintexts, verbose); + break; default: - return false; + throw_not_implemented(algorithm); + break; } } - template - bool encrypt_using_boxes_with_algorithm( - const AesNI_BoxKey& box_key, - aesni::Mode mode, - const std::string& key, - std::deque plaintexts) + void encrypt_using_particular_box( + aesni::Box& box, + std::deque& plaintexts) { - AesNI_BoxBlock iv; - AesNI_BoxBlock* iv_ptr = nullptr; - - if (aesni::mode_requires_initialization_vector(mode)) - { - if (plaintexts.empty()) - return false; - - aesni::from_string(iv.aes_block, plaintexts.front()); - iv_ptr = &iv; - plaintexts.pop_front(); - } - - AesNI_Box box; - aesni_box_init( - &box, - algorithm, - &box_key, - mode, - iv_ptr, - aesni::ErrorDetailsThrowsInDestructor()); - while (!plaintexts.empty()) { - AesNI_BoxBlock plaintext; - aesni::from_string(plaintext.aes_block, plaintexts.front()); + aesni::Box::Block plaintext; + box.parse_block( + plaintext, plaintexts.front()); plaintexts.pop_front(); - AesNI_BoxBlock ciphertext; - aesni_box_encrypt_block( - &box, - &plaintext, - &ciphertext, - aesni::ErrorDetailsThrowsInDestructor()); + aesni::Box::Block ciphertext; + box.encrypt_block(plaintext, ciphertext); - std::cout << aesni::to_string(ciphertext.aes_block) << "\n"; + std::cout << box.format_block(ciphertext) << "\n"; } - - return true; } - bool encrypt_using_boxes( + void encrypt_using_boxes( aesni::Algorithm algorithm, aesni::Mode mode, - const std::string& key, - std::deque plaintexts) + const std::string& key_str, + std::deque& plaintexts) { - AesNI_BoxKey box_key; + aesni::Box::Key key; + aesni::Box::parse_key(key, algorithm, key_str); - switch (algorithm) + if (aesni::mode_requires_initialization_vector(mode)) { - case AESNI_AES128: - aesni::from_string( - box_key.aes128_key, key); - return encrypt_using_boxes_with_algorithm( - box_key, mode, key, plaintexts); - - case AESNI_AES192: - aesni::from_string( - box_key.aes192_key, key); - return encrypt_using_boxes_with_algorithm( - box_key, mode, key, plaintexts); + if (plaintexts.empty()) + throw_iv_required(); - case AESNI_AES256: - aesni::from_string( - box_key.aes256_key, key); - return encrypt_using_boxes_with_algorithm( - box_key, mode, key, plaintexts); + aesni::Box::Block iv; + aesni::Box::parse_block(iv, algorithm, plaintexts.front()); + plaintexts.pop_front(); - default: - return false; + encrypt_using_particular_box( + aesni::Box(algorithm, key, mode, iv), plaintexts); + } + else + { + encrypt_using_particular_box( + aesni::Box(algorithm, key), plaintexts); } } } @@ -215,62 +186,76 @@ int main(int argc, char** argv) try { CommandLineParser cmd_parser("encrypt_block.exe"); - cmd_parser.parse(argc, argv); - - if (cmd_parser.requested_help()) + try { - std::cout << cmd_parser; - return 0; - } - - std::deque args{ std::make_move_iterator(cmd_parser.args.begin()), - std::make_move_iterator(cmd_parser.args.end()) }; + cmd_parser.parse(argc, argv); - while (!args.empty()) - { - const auto key = args.front(); - args.pop_front(); + if (cmd_parser.requested_help()) + { + std::cout << cmd_parser; + return 0; + } - std::deque plaintexts; + std::deque args( + std::make_move_iterator(cmd_parser.args.begin()), + std::make_move_iterator(cmd_parser.args.end())); while (!args.empty()) { - if (args.front() == "--") + const auto key = args.front(); + args.pop_front(); + + std::deque plaintexts; + + while (!args.empty()) { + if (args.front() == "--") + { + args.pop_front(); + break; + } + + plaintexts.push_back(args.front()); args.pop_front(); - break; } - plaintexts.push_back(args.front()); - args.pop_front(); + if (cmd_parser.use_boxes) + { + encrypt_using_boxes( + cmd_parser.algorithm, + cmd_parser.mode, + key, + plaintexts); + } + else + { + encrypt_using_cxx_api( + cmd_parser.algorithm, + cmd_parser.mode, + key, + plaintexts, + cmd_parser.verbose); + } } - const auto success = cmd_parser.use_boxes - ? encrypt_using_boxes(cmd_parser.algorithm, cmd_parser.mode, key, plaintexts) - : encrypt_using_cxx_api(cmd_parser.algorithm, cmd_parser.mode, key, plaintexts, cmd_parser.verbose); - - if (!success) - { - std::cout << cmd_parser; - return 1; - } + return 0; + } + catch (const boost::program_options::error& e) + { + std::cerr << "Usage error: " << e.what() << "\n"; + std::cerr << cmd_parser; + return 1; + } + catch (const aesni::Error& e) + { + std::cerr << e; + return 1; } - - return 0; - } - catch (const boost::program_options::error& e) - { - std::cerr << "Usage error: " << e.what() << "\n"; - return 1; - } - catch (const aesni::Error& e) - { - std::cerr << e; - return 1; } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } + return 0; } diff --git a/utils/encrypt_bmp.cpp b/utils/encrypt_bmp.cpp index 7e2ad21..978b954 100644 --- a/utils/encrypt_bmp.cpp +++ b/utils/encrypt_bmp.cpp @@ -8,8 +8,6 @@ #include "file_cmd_parser.hpp" -#include - #include #include @@ -47,43 +45,35 @@ namespace std::vector src_buf; src_buf.reserve(size); - src_buf.assign(std::istreambuf_iterator(ifs), - std::istreambuf_iterator()); + src_buf.assign( + std::istreambuf_iterator(ifs), + std::istreambuf_iterator()); return src_buf; } - void write_file(const std::string& path, const std::vector& src) + void write_file( + const std::string& path, + const std::vector& src) { std::ofstream ofs; ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit); ofs.open(path, std::ofstream::binary); - ofs.write(src.data(), src.size()); + ofs.write(reinterpret_cast(src.data()), src.size()); } - template - bool encrypt_bmp_with_algorithm( - const AesNI_BoxKey& box_key, - aesni::Mode mode, + void encrypt_bmp( + aesni::Box& box, std::deque& args) { - AesNI_BoxBlock iv; - AesNI_BoxBlock* iv_ptr = nullptr; - - if (aesni::mode_requires_initialization_vector(mode)) - { - if (args.empty()) - return false; - - aesni::from_string(iv.aes_block, args.front()); - iv_ptr = &iv; - args.pop_front(); - } - - if (args.size() != 2) - return false; + if (args.empty()) + throw_src_path_required(); + const auto src_path = args.front(); + args.pop_front(); - const auto src_path = args[0]; - const auto dest_path = args[1]; + if (args.empty()) + throw_dest_path_required(); + const auto dest_path = args.front(); + args.pop_front(); const auto src_buf = read_file(src_path); @@ -93,78 +83,44 @@ namespace const auto pixels = src_buf.data() + header_size; const auto pixels_size = src_buf.size() - header_size; - AesNI_Box box; - - aesni_box_init( - &box, - algorithm, - &box_key, - mode, - iv_ptr, - aesni::ErrorDetailsThrowsInDestructor()); - - std::size_t cipherpixels_size; - - aesni_box_encrypt_buffer( - &box, - pixels, - pixels_size, - nullptr, - &cipherpixels_size, - aesni::ErrorDetailsThrowsInDestructor()); - - std::vector dest_buf; - dest_buf.resize(header_size + cipherpixels_size); - std::memcpy(dest_buf.data(), src_buf.data(), header_size); - - aesni_box_encrypt_buffer( - &box, - pixels, - pixels_size, - dest_buf.data() + header_size, - &cipherpixels_size, - aesni::ErrorDetailsThrowsInDestructor()); + const auto cipherpixels = box.encrypt_buffer( + pixels, pixels_size); - write_file(dest_path, dest_buf); + std::vector dest_buf(header_size + cipherpixels.size()); + std::memcpy(&dest_buf[0], bmp_header, header_size); + std::memcpy(&dest_buf[0] + header_size, cipherpixels.data(), cipherpixels.size()); - return true; + write_file(dest_path, dest_buf); } - bool encrypt_bmp( + void encrypt_bmp( aesni::Algorithm algorithm, aesni::Mode mode, std::deque& args) { if (args.empty()) - return false; + throw_key_required(); - AesNI_BoxKey box_key; + aesni::Box::Key key; + aesni::Box::parse_key(key, algorithm, args.front()); + args.pop_front(); - switch (algorithm) + if (aesni::mode_requires_initialization_vector(mode)) { - case AESNI_AES128: - aesni::from_string( - box_key.aes128_key, args.front()); - args.pop_front(); - return encrypt_bmp_with_algorithm( - box_key, mode, args); - - case AESNI_AES192: - aesni::from_string( - box_key.aes192_key, args.front()); - args.pop_front(); - return encrypt_bmp_with_algorithm( - box_key, mode, args); - - case AESNI_AES256: - aesni::from_string( - box_key.aes256_key, args.front()); - args.pop_front(); - return encrypt_bmp_with_algorithm( - box_key, mode, args); - - default: - return false; + if (args.empty()) + throw_iv_required(); + + aesni::Box::Block iv; + aesni::Box::parse_block(iv, algorithm, args.front()); + args.pop_front(); + + encrypt_bmp( + aesni::Box(algorithm, key, mode, iv), args); + } + else + { + encrypt_bmp( + aesni::Box(algorithm, key), args); } } } @@ -174,38 +130,38 @@ int main(int argc, char** argv) try { CommandLineParser cmd_parser("encrypt_bmp.exe"); - cmd_parser.parse(argc, argv); - - if (cmd_parser.requested_help()) + try { - std::cout << cmd_parser; - return 0; - } + cmd_parser.parse(argc, argv); - std::deque args{ std::make_move_iterator(cmd_parser.args.begin()), - std::make_move_iterator(cmd_parser.args.end()) }; + if (cmd_parser.requested_help()) + { + std::cout << cmd_parser; + return 0; + } - if (!encrypt_bmp(cmd_parser.algorithm, cmd_parser.mode, args)) + std::deque args( + std::make_move_iterator(cmd_parser.args.begin()), + std::make_move_iterator(cmd_parser.args.end())); + + encrypt_bmp(cmd_parser.algorithm, cmd_parser.mode, args); + } + catch (const boost::program_options::error& e) { - std::cout << cmd_parser; + std::cerr << "Usage error: " << e.what() << "\n"; + std::cerr << cmd_parser; + return 1; + } + catch (const aesni::Error& e) + { + std::cerr << e; return 1; } - - return 0; - } - catch (const boost::program_options::error& e) - { - std::cerr << "Usage error: " << e.what() << "\n"; - return 1; - } - catch (const aesni::Error& e) - { - std::cerr << e; - return 1; } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } + return 0; } diff --git a/utils/encrypt_file.cpp b/utils/encrypt_file.cpp index 13f2ce1..9b5406c 100644 --- a/utils/encrypt_file.cpp +++ b/utils/encrypt_file.cpp @@ -8,8 +8,6 @@ #include "file_cmd_parser.hpp" -#include - #include #include @@ -44,118 +42,70 @@ namespace std::vector src_buf; src_buf.reserve(size); - src_buf.assign(std::istreambuf_iterator(ifs), - std::istreambuf_iterator()); + src_buf.assign( + std::istreambuf_iterator(ifs), + std::istreambuf_iterator()); return src_buf; } - void write_file(const std::string& path, const std::vector& src) + void write_file( + const std::string& path, + const std::vector& src) { std::ofstream ofs; ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit); ofs.open(path, std::ofstream::binary); - ofs.write(src.data(), src.size()); + ofs.write(reinterpret_cast(src.data()), src.size()); } - template - bool encrypt_file_with_algorithm( - const AesNI_BoxKey& box_key, - aesni::Mode mode, + void encrypt_file( + aesni::Box& box, std::deque& args) { - AesNI_BoxBlock iv; - AesNI_BoxBlock* iv_ptr = nullptr; - - if (aesni::mode_requires_initialization_vector(mode)) - { - if (args.empty()) - return false; - - aesni::from_string(iv.aes_block, args.front()); - iv_ptr = &iv; - args.pop_front(); - } - - if (args.size() != 2) - return false; + if (args.empty()) + throw_src_path_required(); + const auto src_path = args.front(); + args.pop_front(); - const auto src_path = args[0]; - const auto dest_path = args[1]; + if (args.empty()) + throw_dest_path_required(); + const auto dest_path = args.front(); + args.pop_front(); const auto src_buf = read_file(src_path); - - AesNI_Box box; - - aesni_box_init( - &box, - algorithm, - &box_key, - mode, - iv_ptr, - aesni::ErrorDetailsThrowsInDestructor()); - - std::size_t dest_size; - - aesni_box_encrypt_buffer( - &box, - src_buf.data(), - src_buf.size(), - nullptr, - &dest_size, - aesni::ErrorDetailsThrowsInDestructor()); - - std::vector dest_buf; - dest_buf.resize(dest_size); - - aesni_box_encrypt_buffer( - &box, - src_buf.data(), - src_buf.size(), - dest_buf.data(), - &dest_size, - aesni::ErrorDetailsThrowsInDestructor()); - - dest_buf.resize(dest_size); + const auto dest_buf = box.encrypt_buffer( + src_buf.data(), src_buf.size()); write_file(dest_path, dest_buf); - - return true; } - bool encrypt_file( + void encrypt_file( aesni::Algorithm algorithm, aesni::Mode mode, std::deque& args) { if (args.empty()) - return false; + throw_key_required(); - AesNI_BoxKey box_key; + aesni::Box::Key key; + aesni::Box::parse_key(key, algorithm, args.front()); + args.pop_front(); - switch (algorithm) + if (aesni::mode_requires_initialization_vector(mode)) { - case AESNI_AES128: - aesni::from_string( - box_key.aes128_key, args.front()); - args.pop_front(); - return encrypt_file_with_algorithm( - box_key, mode, args); - - case AESNI_AES192: - aesni::from_string( - box_key.aes192_key, args.front()); - args.pop_front(); - return encrypt_file_with_algorithm( - box_key, mode, args); - - case AESNI_AES256: - aesni::from_string( - box_key.aes256_key, args.front()); - args.pop_front(); - return encrypt_file_with_algorithm( - box_key, mode, args); - - default: - return false; + if (args.empty()) + throw_iv_required(); + + aesni::Box::Block iv; + aesni::Box::parse_block(iv, algorithm, args.front()); + args.pop_front(); + + encrypt_file( + aesni::Box(algorithm, key, mode, iv), args); + } + else + { + encrypt_file( + aesni::Box(algorithm, key), args); } } } @@ -165,38 +115,38 @@ int main(int argc, char** argv) try { CommandLineParser cmd_parser("encrypt_file.exe"); - cmd_parser.parse(argc, argv); - - if (cmd_parser.requested_help()) + try { - std::cout << cmd_parser; - return 0; - } + cmd_parser.parse(argc, argv); - std::deque args{ std::make_move_iterator(cmd_parser.args.begin()), - std::make_move_iterator(cmd_parser.args.end()) }; + if (cmd_parser.requested_help()) + { + std::cout << cmd_parser; + return 0; + } - if (!encrypt_file(cmd_parser.algorithm, cmd_parser.mode, args)) + std::deque args( + std::make_move_iterator(cmd_parser.args.begin()), + std::make_move_iterator(cmd_parser.args.end())); + + encrypt_file(cmd_parser.algorithm, cmd_parser.mode, args); + } + catch (const boost::program_options::error& e) { - std::cout << cmd_parser; + std::cerr << "Usage error: " << e.what() << "\n"; + std::cerr << cmd_parser; + return 1; + } + catch (const aesni::Error& e) + { + std::cerr << e; return 1; } - - return 0; - } - catch (const boost::program_options::error& e) - { - std::cerr << "Usage error: " << e.what() << "\n"; - return 1; - } - catch (const aesni::Error& e) - { - std::cerr << e; - return 1; } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } + return 0; } diff --git a/utils/file_cmd_parser.hpp b/utils/file_cmd_parser.hpp index f20d80f..78162a6 100644 --- a/utils/file_cmd_parser.hpp +++ b/utils/file_cmd_parser.hpp @@ -12,6 +12,7 @@ #include +#include #include #include @@ -20,6 +21,30 @@ namespace { + BOOST_NORETURN inline void throw_key_required() + { + throw boost::program_options::error( + "a key is required but not specified"); + } + + BOOST_NORETURN inline void throw_iv_required() + { + throw boost::program_options::error( + "initialization vector is required for the selected mode of operation"); + } + + BOOST_NORETURN inline void throw_src_path_required() + { + throw boost::program_options::error( + "please, specify source file path"); + } + + BOOST_NORETURN inline void throw_dest_path_required() + { + throw boost::program_options::error( + "please, specify destination file path"); + } + class CommandLineParser { public: -- cgit v1.2.3