// Copyright (c) 2015 Egor Tensin // This file is part of the "AES tools" project. // For details, see https://github.com/egor-tensin/aes-tools. // Distributed under the MIT License. #include "block_cmd_parser.hpp" #include "block_dumper.hpp" #include "block_input.hpp" #include #include #include #include #include #include namespace { template void decrypt_with_mode( const Input& input, bool verbose = false) { typename aes::Types::Block iv; if (aes::ModeRequiresInitializationVector()) { aes::from_string(iv, input.get_iv_string()); if (verbose) dump_iv(iv); } typename aes::Types::Key key; aes::from_string(key, input.get_key_string()); if (verbose) dump_key(key); aes::DecryptWrapper decrypt(key, iv); if (verbose) dump_wrapper(decrypt); for (const auto& input_block_string : input.get_input_block_strings()) { typename aes::Types::Block ciphertext, plaintext; aes::from_string(ciphertext, input_block_string); decrypt.decrypt_block(ciphertext, plaintext); if (verbose) { dump_ciphertext(ciphertext); dump_plaintext(plaintext); dump_next_iv(decrypt); } else { std::cout << aes::to_string(plaintext) << '\n'; } } } template void decrypt_with_algorithm( aes::Mode mode, const Input& input, bool verbose = false) { switch (mode) { case AES_ECB: decrypt_with_mode(input, verbose); break; case AES_CBC: decrypt_with_mode(input, verbose); break; case AES_CFB: decrypt_with_mode(input, verbose); break; case AES_OFB: decrypt_with_mode(input, verbose); break; case AES_CTR: decrypt_with_mode(input, verbose); break; default: throw std::runtime_error("the selected mode of operation is not implemented"); break; } } void decrypt_using_cxx_api( aes::Algorithm algorithm, aes::Mode mode, const Input& input, bool verbose = false) { switch (algorithm) { case AES_AES128: decrypt_with_algorithm(mode, input, verbose); break; case AES_AES192: decrypt_with_algorithm(mode, input, verbose); break; case AES_AES256: decrypt_with_algorithm(mode, input, verbose); break; default: throw std::runtime_error("the selected algorithm is not implemented"); break; } } void decrypt_using_particular_box( aes::Box& box, const std::vector& input_block_strings) { for (const auto& input_block_string : input_block_strings) { aes::Box::Block ciphertext; box.parse_block(ciphertext, input_block_string); aes::Box::Block plaintext; box.decrypt_block(ciphertext, plaintext); std::cout << box.format_block(plaintext) << '\n'; } } void decrypt_using_boxes( aes::Algorithm algorithm, aes::Mode mode, const Input& input) { aes::Box::Key key; aes::Box::parse_key(key, algorithm, input.get_key_string()); if (aes::mode_requires_initialization_vector(mode)) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, input.get_iv_string()); aes::Box box{ algorithm, key, mode, iv }; decrypt_using_particular_box(box, input.get_input_block_strings()); } else { aes::Box box{ algorithm, key }; decrypt_using_particular_box(box, input.get_input_block_strings()); } } } int main(int argc, char** argv) { try { CommandLineParser cmd_parser(argv[0]); try { Settings settings; std::vector inputs; cmd_parser.parse(settings, argc, argv, inputs); if (cmd_parser.exit_with_usage()) { std::cout << cmd_parser; return 0; } for (const auto& input : inputs) { if (settings.use_boxes()) { decrypt_using_boxes( settings.get_algorithm(), settings.get_mode(), input); } else { decrypt_using_cxx_api( settings.get_algorithm(), settings.get_mode(), input, settings.verbose()); } } } catch (const boost::program_options::error& e) { std::cerr << "Usage error: " << e.what() << "\n"; std::cerr << cmd_parser; return 1; } catch (const aes::Error& e) { std::cerr << e; return 1; } } catch (const std::exception& e) { std::cerr << e.what() << "\n"; return 1; } return 0; }