aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/aesxx/utils
diff options
context:
space:
mode:
authorEgor Tensin <egor@tensin.name>2026-07-22 18:31:50 +0200
committerEgor Tensin <egor@tensin.name>2026-07-22 21:07:53 +0200
commit4720b5ac21163936fb47f524037a6f12ce6e6ce2 (patch)
tree7b1f3f7f0e4047134048bb9b9967498b6f8ead12 /aesxx/utils
parentminor refactoring (diff)
downloadaes-tools-4720b5ac21163936fb47f524037a6f12ce6e6ce2.tar.gz
aes-tools-4720b5ac21163936fb47f524037a6f12ce6e6ce2.zip
rewrite: the beginning
This a giant fuck-you to myself while I have nothing (actually, tons of things) to do in a hospital. * The giant screens of preprocessor code are gone, they always sucked, fuck them. * Switched everything to the "boxes" interface as the only one remaining. * Restuctured things in aes/ so that the files they're in make at least a little bit of sense. * Removed a bunch of cruft and prematurely generic code. * This is half-baked at best: I just made sure that the tests pass. A lot of cleanup awaits.
Diffstat (limited to 'aesxx/utils')
-rw-r--r--aesxx/utils/README.md2
-rw-r--r--aesxx/utils/decrypt_block.cpp133
-rw-r--r--aesxx/utils/decrypt_bmp.cpp12
-rw-r--r--aesxx/utils/decrypt_file.cpp12
-rw-r--r--aesxx/utils/encrypt_block.cpp136
-rw-r--r--aesxx/utils/encrypt_bmp.cpp12
-rw-r--r--aesxx/utils/encrypt_file.cpp12
-rw-r--r--aesxx/utils/helpers/block_dumper.hpp85
-rw-r--r--aesxx/utils/helpers/cmd_parser_block.hpp53
-rw-r--r--aesxx/utils/helpers/cmd_parser_file.hpp22
-rw-r--r--aesxx/utils/helpers/data_parsers.hpp10
11 files changed, 58 insertions, 431 deletions
diff --git a/aesxx/utils/README.md b/aesxx/utils/README.md
index c133c92..a24bd15 100644
--- a/aesxx/utils/README.md
+++ b/aesxx/utils/README.md
@@ -12,8 +12,6 @@ Block encryption utilities can produce verbose human-readable output, including
round keys, intermediate initialization vector values, etc.
They are primarily intended for debugging purposes.
Enable verbose output by passing the `--verbose` flag.
-Please note that verbose output can only be produced when *not* using the
-"boxes" interface (the `--use-boxes` flag).
### encrypt_block
diff --git a/aesxx/utils/decrypt_block.cpp b/aesxx/utils/decrypt_block.cpp
index c8edb34..7a296ff 100644
--- a/aesxx/utils/decrypt_block.cpp
+++ b/aesxx/utils/decrypt_block.cpp
@@ -3,7 +3,6 @@
// For details, see https://github.com/egor-tensin/aes-tools.
// Distributed under the MIT License.
-#include "helpers/block_dumper.hpp"
#include "helpers/cmd_parser_block.hpp"
#include <aesxx/all.hpp>
@@ -18,128 +17,16 @@
namespace {
-template <aes::Algorithm algorithm, aes::Mode mode>
-void decrypt_with_mode(const BlockSettings::Input& input, bool verbose = false) {
- typename aes::Types<algorithm>::Block iv;
- aes::make_block(iv, 0, 0, 0, 0);
-
- if (input.has_iv()) {
- aes::from_string<algorithm>(iv, input.get_iv());
- if (verbose)
- dump_iv<algorithm>(iv);
- }
-
- typename aes::Types<algorithm>::Key key;
- aes::from_string<algorithm>(key, input.get_key());
- if (verbose)
- dump_key<algorithm>(key);
-
- aes::DecryptWrapper<algorithm, mode> decrypt{key, iv};
- if (verbose)
- dump_wrapper<algorithm, mode>(decrypt);
-
- for (const auto& block : input.get_blocks()) {
- typename aes::Types<algorithm>::Block ciphertext, plaintext;
- aes::from_string<algorithm>(ciphertext, block);
-
- decrypt.decrypt_block(ciphertext, plaintext);
-
- if (verbose) {
- dump_ciphertext<algorithm>(ciphertext);
- dump_plaintext<algorithm>(plaintext);
- dump_next_iv<algorithm, mode>(decrypt);
- } else {
- std::cout << std::format("{}\n", aes::to_string<algorithm>(plaintext));
- }
- }
-}
-
-template <aes::Algorithm algorithm>
-void decrypt_with_algorithm(
- aes::Mode mode,
- const BlockSettings::Input& input,
- bool verbose = false
-) {
- switch (mode) {
- case AES_ECB:
- decrypt_with_mode<algorithm, AES_ECB>(input, verbose);
- break;
-
- case AES_CBC:
- decrypt_with_mode<algorithm, AES_CBC>(input, verbose);
- break;
-
- case AES_CFB:
- decrypt_with_mode<algorithm, AES_CFB>(input, verbose);
- break;
-
- case AES_OFB:
- decrypt_with_mode<algorithm, AES_OFB>(input, verbose);
- break;
-
- case AES_CTR:
- decrypt_with_mode<algorithm, AES_CTR>(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 BlockSettings::Input& input,
- bool verbose = false
-) {
- switch (algorithm) {
- case AES_AES128:
- decrypt_with_algorithm<AES_AES128>(mode, input, verbose);
- break;
-
- case AES_AES192:
- decrypt_with_algorithm<AES_AES192>(mode, input, verbose);
- break;
-
- case AES_AES256:
- decrypt_with_algorithm<AES_AES256>(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<std::string>& blocks) {
- for (const auto& block : blocks) {
- aes::Box::Block ciphertext;
- box.parse_block(ciphertext, block);
-
- aes::Box::Block plaintext;
- box.decrypt_block(ciphertext, plaintext);
- std::cout << std::format("{}\n", box.format_block(plaintext));
- }
-}
-
-void decrypt_using_boxes(
- aes::Algorithm algorithm,
- aes::Mode mode,
- const BlockSettings::Input& input
-) {
+void decrypt_blocks(aes::Algorithm algorithm, aes::Mode mode, const BlockSettings::Input& input) {
aes::Box::Key key;
aes::Box::parse_key(key, algorithm, input.get_key());
- if (input.has_iv()) {
- aes::Box::Block iv;
- aes::Box::parse_block(iv, input.get_iv());
- aes::Box box{algorithm, key, mode, iv};
+ aes::Box box{algorithm, key, mode, input.get_iv()};
- decrypt_using_particular_box(box, input.get_blocks());
- } else {
- aes::Box box{algorithm, key};
- decrypt_using_particular_box(box, input.get_blocks());
+ for (const auto& ciphertext : input.get_blocks()) {
+ aes::Block plaintext;
+ box.decrypt_block(ciphertext, plaintext);
+ std::cout << std::format("{}\n", plaintext.to_string());
}
}
@@ -162,13 +49,7 @@ int main(int argc, char** argv) {
}
for (const auto& input : settings.get_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()
- );
- }
+ decrypt_blocks(settings.get_algorithm(), settings.get_mode(), input);
}
} catch (const aes::Error& e) {
std::cerr << e;
diff --git a/aesxx/utils/decrypt_bmp.cpp b/aesxx/utils/decrypt_bmp.cpp
index 51a2572..cf5ac31 100644
--- a/aesxx/utils/decrypt_bmp.cpp
+++ b/aesxx/utils/decrypt_bmp.cpp
@@ -37,16 +37,8 @@ void decrypt_bmp(const FileSettings& settings) {
aes::Box::Key key;
aes::Box::parse_key(key, algorithm, settings.get_key());
- if (settings.has_iv()) {
- aes::Box::Block iv;
- aes::Box::parse_block(iv, settings.get_iv());
-
- aes::Box box{algorithm, key, mode, iv};
- decrypt_bmp(box, settings.get_input_path(), settings.get_output_path());
- } else {
- aes::Box box{algorithm, key};
- decrypt_bmp(box, settings.get_input_path(), settings.get_output_path());
- }
+ aes::Box box{algorithm, key, mode, settings.get_iv()};
+ decrypt_bmp(box, settings.get_input_path(), settings.get_output_path());
}
} // namespace
diff --git a/aesxx/utils/decrypt_file.cpp b/aesxx/utils/decrypt_file.cpp
index 6c915b5..9eb764f 100644
--- a/aesxx/utils/decrypt_file.cpp
+++ b/aesxx/utils/decrypt_file.cpp
@@ -35,16 +35,8 @@ void decrypt_file(const FileSettings& settings) {
aes::Box::Key key;
aes::Box::parse_key(key, algorithm, settings.get_key());
- if (settings.has_iv()) {
- aes::Box::Block iv;
- aes::Box::parse_block(iv, settings.get_iv());
-
- aes::Box box{algorithm, key, mode, iv};
- decrypt_file(box, settings.get_input_path(), settings.get_output_path());
- } else {
- aes::Box box{algorithm, key};
- decrypt_file(box, settings.get_input_path(), settings.get_output_path());
- }
+ aes::Box box{algorithm, key, mode, settings.get_iv()};
+ decrypt_file(box, settings.get_input_path(), settings.get_output_path());
}
} // namespace
diff --git a/aesxx/utils/encrypt_block.cpp b/aesxx/utils/encrypt_block.cpp
index a796483..40d9f1a 100644
--- a/aesxx/utils/encrypt_block.cpp
+++ b/aesxx/utils/encrypt_block.cpp
@@ -3,7 +3,6 @@
// For details, see https://github.com/egor-tensin/aes-tools.
// Distributed under the MIT License.
-#include "helpers/block_dumper.hpp"
#include "helpers/cmd_parser_block.hpp"
#include <aesxx/all.hpp>
@@ -18,131 +17,16 @@
namespace {
-template <aes::Algorithm algorithm, aes::Mode mode>
-void encrypt_with_mode(const BlockSettings::Input& input, bool verbose = false) {
- typename aes::Types<algorithm>::Block iv;
- aes::make_block(iv, 0, 0, 0, 0);
-
- if (input.has_iv()) {
- aes::from_string<algorithm>(iv, input.get_iv());
- if (verbose)
- dump_iv<algorithm>(iv);
- }
-
- typename aes::Types<algorithm>::Key key;
- aes::from_string<algorithm>(key, input.get_key());
- if (verbose)
- dump_key<algorithm>(key);
-
- aes::EncryptWrapper<algorithm, mode> encrypt{key, iv};
- if (verbose)
- dump_wrapper<algorithm, mode>(encrypt);
-
- for (const auto& input_block_string : input.get_blocks()) {
- typename aes::Types<algorithm>::Block plaintext, ciphertext;
- aes::from_string<algorithm>(plaintext, input_block_string);
-
- encrypt.encrypt_block(plaintext, ciphertext);
-
- if (verbose) {
- dump_plaintext<algorithm>(plaintext);
- dump_ciphertext<algorithm>(ciphertext);
- dump_next_iv<algorithm, mode>(encrypt);
- } else {
- std::cout << std::format("{}\n", aes::to_string<algorithm>(ciphertext));
- }
- }
-}
-
-template <aes::Algorithm algorithm>
-void encrypt_with_algorithm(
- aes::Mode mode,
- const BlockSettings::Input& input,
- bool verbose = false
-) {
- switch (mode) {
- case AES_ECB:
- encrypt_with_mode<algorithm, AES_ECB>(input, verbose);
- break;
-
- case AES_CBC:
- encrypt_with_mode<algorithm, AES_CBC>(input, verbose);
- break;
-
- case AES_CFB:
- encrypt_with_mode<algorithm, AES_CFB>(input, verbose);
- break;
-
- case AES_OFB:
- encrypt_with_mode<algorithm, AES_OFB>(input, verbose);
- break;
-
- case AES_CTR:
- encrypt_with_mode<algorithm, AES_CTR>(input, verbose);
- break;
-
- default:
- throw std::runtime_error("the selected mode of operation is not implemented");
- break;
- }
-}
-
-void encrypt_using_cxx_api(
- aes::Algorithm algorithm,
- aes::Mode mode,
- const BlockSettings::Input& input,
- bool verbose = false
-) {
- switch (algorithm) {
- case AES_AES128:
- encrypt_with_algorithm<AES_AES128>(mode, input, verbose);
- break;
-
- case AES_AES192:
- encrypt_with_algorithm<AES_AES192>(mode, input, verbose);
- break;
-
- case AES_AES256:
- encrypt_with_algorithm<AES_AES256>(mode, input, verbose);
- break;
-
- default:
- throw std::runtime_error("the selected algorithm is not implemented");
- break;
- }
-}
-
-void encrypt_using_particular_box(
- aes::Box& box,
- const std::vector<std::string>& input_block_strings
-) {
- for (const auto& input_block_string : input_block_strings) {
- aes::Box::Block plaintext;
- box.parse_block(plaintext, input_block_string);
-
- aes::Box::Block ciphertext;
- box.encrypt_block(plaintext, ciphertext);
- std::cout << std::format("{}\n", box.format_block(ciphertext));
- }
-}
-
-void encrypt_using_boxes(
- aes::Algorithm algorithm,
- aes::Mode mode,
- const BlockSettings::Input& input
-) {
+void encrypt_blocks(aes::Algorithm algorithm, aes::Mode mode, const BlockSettings::Input& input) {
aes::Box::Key key;
aes::Box::parse_key(key, algorithm, input.get_key());
- if (input.has_iv()) {
- aes::Box::Block iv;
- aes::Box::parse_block(iv, input.get_iv());
- aes::Box box{algorithm, key, mode, iv};
+ aes::Box box{algorithm, key, mode, input.get_iv()};
- encrypt_using_particular_box(box, input.get_blocks());
- } else {
- aes::Box box{algorithm, key};
- encrypt_using_particular_box(box, input.get_blocks());
+ for (const auto& plaintext : input.get_blocks()) {
+ aes::Block ciphertext;
+ box.encrypt_block(plaintext, ciphertext);
+ std::cout << std::format("{}\n", ciphertext.to_string());
}
}
@@ -165,13 +49,7 @@ int main(int argc, char** argv) {
}
for (const auto& input : settings.get_inputs()) {
- if (settings.use_boxes()) {
- encrypt_using_boxes(settings.get_algorithm(), settings.get_mode(), input);
- } else {
- encrypt_using_cxx_api(
- settings.get_algorithm(), settings.get_mode(), input, settings.verbose()
- );
- }
+ encrypt_blocks(settings.get_algorithm(), settings.get_mode(), input);
}
} catch (const aes::Error& e) {
std::cerr << e;
diff --git a/aesxx/utils/encrypt_bmp.cpp b/aesxx/utils/encrypt_bmp.cpp
index 19caee4..2fcde46 100644
--- a/aesxx/utils/encrypt_bmp.cpp
+++ b/aesxx/utils/encrypt_bmp.cpp
@@ -35,16 +35,8 @@ void encrypt_bmp(const FileSettings& settings) {
aes::Box::Key key;
aes::Box::parse_key(key, algorithm, settings.get_key());
- if (settings.has_iv()) {
- aes::Box::Block iv;
- aes::Box::parse_block(iv, settings.get_iv());
-
- aes::Box box{algorithm, key, mode, iv};
- encrypt_bmp(box, settings.get_input_path(), settings.get_output_path());
- } else {
- aes::Box box{algorithm, key};
- encrypt_bmp(box, settings.get_input_path(), settings.get_output_path());
- }
+ aes::Box box{algorithm, key, mode, settings.get_iv()};
+ encrypt_bmp(box, settings.get_input_path(), settings.get_output_path());
}
} // namespace
diff --git a/aesxx/utils/encrypt_file.cpp b/aesxx/utils/encrypt_file.cpp
index 1b7217c..4a2557f 100644
--- a/aesxx/utils/encrypt_file.cpp
+++ b/aesxx/utils/encrypt_file.cpp
@@ -35,16 +35,8 @@ void encrypt_file(const FileSettings& settings) {
aes::Box::Key key;
aes::Box::parse_key(key, algorithm, settings.get_key());
- if (settings.has_iv()) {
- aes::Box::Block iv;
- aes::Box::parse_block(iv, settings.get_iv());
-
- aes::Box box{algorithm, key, mode, iv};
- encrypt_file(box, settings.get_input_path(), settings.get_output_path());
- } else {
- aes::Box box{algorithm, key};
- encrypt_file(box, settings.get_input_path(), settings.get_output_path());
- }
+ aes::Box box{algorithm, key, mode, settings.get_iv()};
+ encrypt_file(box, settings.get_input_path(), settings.get_output_path());
}
} // namespace
diff --git a/aesxx/utils/helpers/block_dumper.hpp b/aesxx/utils/helpers/block_dumper.hpp
deleted file mode 100644
index 8284b67..0000000
--- a/aesxx/utils/helpers/block_dumper.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com>
-// This file is part of the "AES tools" project.
-// For details, see https://github.com/egor-tensin/aes-tools.
-// Distributed under the MIT License.
-
-#pragma once
-
-#include <aesxx/all.hpp>
-
-#include <cstdlib>
-#include <format>
-#include <iostream>
-#include <string_view>
-#include <type_traits>
-
-template <aes::Algorithm algorithm>
-void dump_block(std::string_view header, const typename aes::Types<algorithm>::Block& block) {
- std::cout << std::format("{}: {}\n", header, aes::to_string<algorithm>(block));
- std::cout << std::format("{}\n", aes::to_matrix_string<algorithm>(block));
-}
-
-template <aes::Algorithm algorithm>
-void dump_plaintext(const typename aes::Types<algorithm>::Block& block) {
- dump_block<algorithm>("Plaintext", block);
-}
-
-template <aes::Algorithm algorithm>
-void dump_key(const typename aes::Types<algorithm>::Key& key) {
- std::cout << std::format("Key: {}\n\n", aes::to_string<algorithm>(key));
-}
-
-template <aes::Algorithm algorithm>
-void dump_ciphertext(const typename aes::Types<algorithm>::Block& ciphertext) {
- dump_block<algorithm>("Ciphertext", ciphertext);
-}
-
-template <aes::Algorithm algorithm>
-void dump_iv(const typename aes::Types<algorithm>::Block& iv) {
- dump_block<algorithm>("Initialization vector", iv);
-}
-
-template <aes::Algorithm algorithm>
-void dump_round_keys(
- const char* header,
- const typename aes::Types<algorithm>::RoundKeys& round_keys
-) {
- std::cout << std::format("{}:\n", header);
- for (std::size_t i = 0; i < aes::get_number_of_rounds<algorithm>(); ++i)
- std::cout << std::format("\t[{}]: {}\n", i, aes::to_string<algorithm>(round_keys.keys[i]));
- std::cout << "\n";
-}
-
-template <aes::Algorithm algorithm>
-void dump_encryption_keys(const typename aes::Types<algorithm>::RoundKeys& round_keys) {
- dump_round_keys<algorithm>("Encryption round keys", round_keys);
-}
-
-template <aes::Algorithm algorithm>
-void dump_decryption_keys(const typename aes::Types<algorithm>::RoundKeys& round_keys) {
- dump_round_keys<algorithm>("Decryption round keys", round_keys);
-}
-
-template <aes::Algorithm algorithm, aes::Mode mode>
-void dump_wrapper(const aes::EncryptWrapper<algorithm, mode>& wrapper) {
- dump_encryption_keys<algorithm>(wrapper.encryption_keys);
-}
-
-template <aes::Algorithm algorithm, aes::Mode mode>
-void dump_wrapper(const aes::DecryptWrapper<algorithm, mode>& wrapper) {
- dump_decryption_keys<algorithm>(wrapper.decryption_keys);
-}
-
-template <aes::Algorithm algorithm, aes::Mode mode>
-void dump_next_iv(const aes::EncryptWrapper<algorithm, mode>& wrapper) {
- if constexpr (aes::mode_requires_init_vector(mode)) {
- dump_block<algorithm>("Next initialization vector", wrapper.iv);
- }
-}
-
-template <aes::Algorithm algorithm, aes::Mode mode>
-void dump_next_iv(const aes::DecryptWrapper<algorithm, mode>& wrapper) {
- if constexpr (aes::mode_requires_init_vector(mode)) {
- dump_block<algorithm>("Next initialization vector", wrapper.iv);
- }
-}
diff --git a/aesxx/utils/helpers/cmd_parser_block.hpp b/aesxx/utils/helpers/cmd_parser_block.hpp
index 4226fb5..7e24874 100644
--- a/aesxx/utils/helpers/cmd_parser_block.hpp
+++ b/aesxx/utils/helpers/cmd_parser_block.hpp
@@ -14,6 +14,7 @@
#include <deque>
#include <iterator>
+#include <optional>
#include <string>
#include <string_view>
#include <utility>
@@ -23,32 +24,29 @@ class BlockSettings : public SettingsParser {
public:
class Input {
public:
- Input(std::string_view key, std::string_view iv, std::vector<std::string>&& blocks)
- : key{key}, iv{iv}, blocks{std::move(blocks)} {}
-
- Input(std::string key, std::vector<std::string>&& blocks)
- : key{key}, blocks{std::move(blocks)} {}
+ Input(
+ std::string_view key,
+ std::optional<aes::Block>&& iv,
+ std::vector<aes::Block>&& blocks
+ )
+ : key{key}, iv{std::move(iv)}, blocks{std::move(blocks)} {}
std::string get_key() const {
return key;
}
- bool has_iv() const {
- return !iv.empty();
- }
-
- std::string get_iv() const {
+ std::optional<aes::Block> get_iv() const {
return iv;
}
- std::vector<std::string> get_blocks() const {
+ std::vector<aes::Block> get_blocks() const {
return blocks;
}
private:
std::string key;
- std::string iv;
- std::vector<std::string> blocks;
+ std::optional<aes::Block> iv;
+ std::vector<aes::Block> blocks;
};
explicit BlockSettings(std::string_view argv0) : SettingsParser{argv0} {
@@ -67,11 +65,6 @@ public:
boost::program_options::value<aes::Mode>(&mode)->required()->value_name("MODE"),
"set mode of operation"
);
- visible.add_options()(
- "use-boxes,b",
- boost::program_options::bool_switch(&_use_boxes),
- "use the \"boxes\" interface"
- );
}
const char* get_short_description() const override {
@@ -111,10 +104,6 @@ public:
return inputs;
}
- bool use_boxes() const {
- return _use_boxes;
- }
-
bool verbose() const {
return _verbose;
}
@@ -129,35 +118,30 @@ private:
std::string key{std::move(src.front())};
src.pop_front();
- std::string iv;
+ std::optional<aes::Block> iv;
- if (aes::mode_requires_init_vector(mode)) {
+ if (aes_mode_requires_init_vector(mode)) {
if (src.empty()) {
throw boost::program_options::error{
"an initialization vector is required for the selected mode of operation"
};
}
- iv = std::move(src.front());
+ iv = aes::Block{std::move(src.front())};
src.pop_front();
}
- auto blocks = parse_blocks(src);
-
- if (aes::mode_requires_init_vector(mode))
- return {key, iv, std::move(blocks)};
- else
- return {key, std::move(blocks)};
+ return {key, std::move(iv), parse_blocks(src)};
}
- static std::vector<std::string> parse_blocks(std::deque<std::string>& src) {
- std::vector<std::string> blocks;
+ static std::vector<aes::Block> parse_blocks(std::deque<std::string>& src) {
+ std::vector<aes::Block> blocks;
while (!src.empty()) {
std::string block{std::move(src.front())};
src.pop_front();
if (block == "--")
break;
- blocks.emplace_back(std::move(block));
+ blocks.emplace_back(aes::Block{std::move(block)});
}
return blocks;
@@ -167,6 +151,5 @@ private:
aes::Mode mode;
std::vector<Input> inputs;
- bool _use_boxes = false;
bool _verbose = false;
};
diff --git a/aesxx/utils/helpers/cmd_parser_file.hpp b/aesxx/utils/helpers/cmd_parser_file.hpp
index 2e710b2..8adfb1d 100644
--- a/aesxx/utils/helpers/cmd_parser_file.hpp
+++ b/aesxx/utils/helpers/cmd_parser_file.hpp
@@ -10,8 +10,10 @@
#include <aesxx/all.hpp>
+#include <boost/optional.hpp>
#include <boost/program_options.hpp>
+#include <optional>
#include <ostream>
#include <string>
#include <string_view>
@@ -39,7 +41,7 @@ public:
);
visible.add_options()(
"iv,v",
- boost::program_options::value<std::string>(&iv)->value_name("BLOCK"),
+ boost::program_options::value(&iv)->value_name("BLOCK"),
"set initialization vector"
);
visible.add_options()(
@@ -66,12 +68,6 @@ public:
SettingsParser::parse(argc, argv);
if (exit_with_usage())
return;
-
- if (aes::mode_requires_init_vector(get_mode()) && iv.empty()) {
- throw boost::program_options::error{
- "an initialization vector is required for the selected mode of operation"
- };
- }
}
aes::Algorithm get_algorithm() const {
@@ -94,12 +90,10 @@ public:
return key;
}
- bool has_iv() const {
- return !iv.empty();
- }
-
- std::string get_iv() const {
- return iv;
+ std::optional<aes::Block> get_iv() const {
+ if (iv)
+ return {*iv};
+ return {};
}
private:
@@ -110,5 +104,5 @@ private:
std::string output_path;
std::string key;
- std::string iv;
+ boost::optional<aes::Block> iv;
};
diff --git a/aesxx/utils/helpers/data_parsers.hpp b/aesxx/utils/helpers/data_parsers.hpp
index a08f1bf..a66a433 100644
--- a/aesxx/utils/helpers/data_parsers.hpp
+++ b/aesxx/utils/helpers/data_parsers.hpp
@@ -8,6 +8,7 @@
#include <aesxx/all.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/optional.hpp>
#include <boost/program_options.hpp>
#include <istream>
@@ -53,3 +54,12 @@ inline std::istream& operator>>(std::istream& is, aes::Algorithm& dest) {
dest = it->second;
return is;
}
+
+namespace boost {
+
+inline void validate(any& dest, const std::vector<std::string>& values, aes::Block*, int) {
+ const std::string& src = program_options::validators::get_single_string(values);
+ dest = aes::Block{src};
+}
+
+} // namespace boost