diff options
Diffstat (limited to 'aesxx')
| -rw-r--r-- | aesxx/include/aesxx/aes.hpp | 230 | ||||
| -rw-r--r-- | aesxx/include/aesxx/all.hpp | 2 | ||||
| -rw-r--r-- | aesxx/include/aesxx/api.hpp | 136 | ||||
| -rw-r--r-- | aesxx/include/aesxx/box.hpp | 71 | ||||
| -rw-r--r-- | aesxx/include/aesxx/data.hpp | 58 | ||||
| -rw-r--r-- | aesxx/include/aesxx/mode.hpp | 120 | ||||
| -rw-r--r-- | aesxx/utils/README.md | 2 | ||||
| -rw-r--r-- | aesxx/utils/decrypt_block.cpp | 133 | ||||
| -rw-r--r-- | aesxx/utils/decrypt_bmp.cpp | 12 | ||||
| -rw-r--r-- | aesxx/utils/decrypt_file.cpp | 12 | ||||
| -rw-r--r-- | aesxx/utils/encrypt_block.cpp | 136 | ||||
| -rw-r--r-- | aesxx/utils/encrypt_bmp.cpp | 12 | ||||
| -rw-r--r-- | aesxx/utils/encrypt_file.cpp | 12 | ||||
| -rw-r--r-- | aesxx/utils/helpers/block_dumper.hpp | 85 | ||||
| -rw-r--r-- | aesxx/utils/helpers/cmd_parser_block.hpp | 53 | ||||
| -rw-r--r-- | aesxx/utils/helpers/cmd_parser_file.hpp | 22 | ||||
| -rw-r--r-- | aesxx/utils/helpers/data_parsers.hpp | 10 |
17 files changed, 128 insertions, 978 deletions
diff --git a/aesxx/include/aesxx/aes.hpp b/aesxx/include/aesxx/aes.hpp deleted file mode 100644 index 38d98fa..0000000 --- a/aesxx/include/aesxx/aes.hpp +++ /dev/null @@ -1,230 +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 "algorithm.hpp" -#include "api.hpp" -#include "error.hpp" -#include "mode.hpp" - -#include <aes/all.h> - -#include <cstddef> -#include <string> -#include <string_view> - -namespace aes { -namespace aes128 { - -typedef AES_Block Block; -typedef AES128_RoundKeys RoundKeys; -typedef AES128_Key Key; - -} // namespace aes128 - -template <> -struct Types<AES_AES128> { - typedef aes128::Block Block; - typedef aes128::RoundKeys RoundKeys; - typedef aes128::Key Key; -}; - -template <> -inline void from_string<AES_AES128>(aes128::Block& dest, std::string_view src) { - aes_parse_block(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); -} - -template <> -inline std::string to_string<AES_AES128>(const aes128::Block& src) { - AES_BlockString str; - aes_format_block(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline std::string to_matrix_string<AES_AES128>(const aes128::Block& src) { - AES_BlockMatrixString str; - aes_format_block_as_matrix(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline void from_string<AES_AES128>(aes128::Key& dest, std::string_view src) { - aes128_parse_key(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); -} - -template <> -inline std::string to_string<AES_AES128>(const aes128::Key& src) { - AES128_KeyString str; - aes128_format_key(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline void expand_key<AES_AES128>(const aes128::Key& key, aes128::RoundKeys& encryption_keys) { - aes128_expand_key(&key, &encryption_keys); -} - -template <> -inline void derive_decryption_keys<AES_AES128>( - const aes128::RoundKeys& encryption_keys, - aes128::RoundKeys& decryption_keys -) { - aes128_derive_decryption_keys(&encryption_keys, &decryption_keys); -} - -AESXX_ENCRYPT_BLOCK_ECB(128); -AESXX_DECRYPT_BLOCK_ECB(128); -AESXX_ENCRYPT_BLOCK_CBC(128); -AESXX_DECRYPT_BLOCK_CBC(128); -AESXX_ENCRYPT_BLOCK_CFB(128); -AESXX_DECRYPT_BLOCK_CFB(128); -AESXX_ENCRYPT_BLOCK_OFB(128); -AESXX_DECRYPT_BLOCK_OFB(128); -AESXX_ENCRYPT_BLOCK_CTR(128); -AESXX_DECRYPT_BLOCK_CTR(128); - -namespace aes192 { - -typedef AES_Block Block; -typedef AES192_RoundKeys RoundKeys; -typedef AES192_Key Key; - -} // namespace aes192 - -template <> -struct Types<AES_AES192> { - typedef aes192::Block Block; - typedef aes192::RoundKeys RoundKeys; - typedef aes192::Key Key; -}; - -template <> -inline void from_string<AES_AES192>(aes192::Block& dest, std::string_view src) { - aes_parse_block(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); -} - -template <> -inline std::string to_string<AES_AES192>(const aes192::Block& src) { - AES_BlockString str; - aes_format_block(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline std::string to_matrix_string<AES_AES192>(const aes192::Block& src) { - AES_BlockMatrixString str; - aes_format_block_as_matrix(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline void from_string<AES_AES192>(aes192::Key& dest, std::string_view src) { - aes192_parse_key(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); -} - -template <> -inline std::string to_string<AES_AES192>(const aes192::Key& src) { - AES192_KeyString str; - aes192_format_key(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline void expand_key<AES_AES192>(const aes192::Key& key, aes192::RoundKeys& encryption_keys) { - aes192_expand_key(&key, &encryption_keys); -} - -template <> -inline void derive_decryption_keys<AES_AES192>( - const aes192::RoundKeys& encryption_keys, - aes192::RoundKeys& decryption_keys -) { - aes192_derive_decryption_keys(&encryption_keys, &decryption_keys); -} - -AESXX_ENCRYPT_BLOCK_ECB(192); -AESXX_DECRYPT_BLOCK_ECB(192); -AESXX_ENCRYPT_BLOCK_CBC(192); -AESXX_DECRYPT_BLOCK_CBC(192); -AESXX_ENCRYPT_BLOCK_CFB(192); -AESXX_DECRYPT_BLOCK_CFB(192); -AESXX_ENCRYPT_BLOCK_OFB(192); -AESXX_DECRYPT_BLOCK_OFB(192); -AESXX_ENCRYPT_BLOCK_CTR(192); -AESXX_DECRYPT_BLOCK_CTR(192); - -namespace aes256 { - -typedef AES_Block Block; -typedef AES256_RoundKeys RoundKeys; -typedef AES256_Key Key; - -} // namespace aes256 - -template <> -struct Types<AES_AES256> { - typedef aes256::Block Block; - typedef aes256::RoundKeys RoundKeys; - typedef aes256::Key Key; -}; - -template <> -inline void from_string<AES_AES256>(aes256::Block& dest, std::string_view src) { - aes_parse_block(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); -} - -template <> -inline std::string to_string<AES_AES256>(const aes256::Block& src) { - AES_BlockString str; - aes_format_block(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline std::string to_matrix_string<AES_AES256>(const aes256::Block& src) { - AES_BlockMatrixString str; - aes_format_block_as_matrix(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline void from_string<AES_AES256>(aes256::Key& dest, std::string_view src) { - aes256_parse_key(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); -} - -template <> -inline std::string to_string<AES_AES256>(const aes256::Key& src) { - AES256_KeyString str; - aes256_format_key(&str, &src, ErrorDetailsThrowsInDestructor{}); - return {str.str}; -} - -template <> -inline void expand_key<AES_AES256>(const aes256::Key& key, aes256::RoundKeys& encryption_keys) { - aes256_expand_key(&key, &encryption_keys); -} - -template <> -inline void derive_decryption_keys<AES_AES256>( - const aes256::RoundKeys& encryption_keys, - aes256::RoundKeys& decryption_keys -) { - aes256_derive_decryption_keys(&encryption_keys, &decryption_keys); -} - -AESXX_ENCRYPT_BLOCK_ECB(256); -AESXX_DECRYPT_BLOCK_ECB(256); -AESXX_ENCRYPT_BLOCK_CBC(256); -AESXX_DECRYPT_BLOCK_CBC(256); -AESXX_ENCRYPT_BLOCK_CFB(256); -AESXX_DECRYPT_BLOCK_CFB(256); -AESXX_ENCRYPT_BLOCK_OFB(256); -AESXX_DECRYPT_BLOCK_OFB(256); -AESXX_ENCRYPT_BLOCK_CTR(256); -AESXX_DECRYPT_BLOCK_CTR(256); - -} // namespace aes diff --git a/aesxx/include/aesxx/all.hpp b/aesxx/include/aesxx/all.hpp index 99202a7..acea406 100644 --- a/aesxx/include/aesxx/all.hpp +++ b/aesxx/include/aesxx/all.hpp @@ -5,9 +5,7 @@ #pragma once -#include "aes.hpp" #include "algorithm.hpp" -#include "api.hpp" #include "box.hpp" #include "data.hpp" #include "debug.hpp" diff --git a/aesxx/include/aesxx/api.hpp b/aesxx/include/aesxx/api.hpp deleted file mode 100644 index 131e5e5..0000000 --- a/aesxx/include/aesxx/api.hpp +++ /dev/null @@ -1,136 +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 "algorithm.hpp" -#include "mode.hpp" - -#include <cstddef> -#include <string> -#include <string_view> -#include <type_traits> - -namespace aes { - -template <Algorithm algorithm> -struct Types; - -template <Algorithm algorithm> -std::size_t get_number_of_rounds() { - if constexpr (algorithm == AES_AES128) - return 11; - if constexpr (algorithm == AES_AES192) - return 13; - if constexpr (algorithm == AES_AES256) - return 15; - static_assert("Unrecognized algorithm"); -} - -template <Algorithm algorithm> -void from_string(typename Types<algorithm>::Block&, std::string_view); - -template <Algorithm algorithm> -std::string to_string(const typename Types<algorithm>::Block&); - -template <Algorithm algorithm> -std::string to_matrix_string(const typename Types<algorithm>::Block&); - -template <Algorithm algorithm> -void from_string(typename Types<algorithm>::Key&, std::string_view); - -template <Algorithm algorithm> -std::string to_string(const typename Types<algorithm>::Key&); - -template <Algorithm algorithm> -void expand_key( - const typename Types<algorithm>::Key& key, - typename Types<algorithm>::RoundKeys& encryption_keys -); - -template <Algorithm algorithm> -void derive_decryption_keys( - const typename Types<algorithm>::RoundKeys& encryption_keys, - typename Types<algorithm>::RoundKeys& decryption_keys -); - -template <Algorithm algorithm, Mode mode> -void encrypt_block( - const typename Types<algorithm>::Block& plaintext, - const typename Types<algorithm>::RoundKeys& round_keys, - typename Types<algorithm>::Block& iv, - typename Types<algorithm>::Block& ciphertext -) { - if constexpr (mode_requires_init_vector(mode)) { - encrypt_block(plaintext, round_keys, iv, ciphertext); - } else { - encrypt_block(plaintext, round_keys, ciphertext); - } -} - -template <Algorithm algorithm, Mode mode> -void decrypt_block( - const typename Types<algorithm>::Block& ciphertext, - const typename Types<algorithm>::RoundKeys& round_keys, - typename Types<algorithm>::Block& iv, - typename Types<algorithm>::Block& plaintext -) { - if constexpr (mode_requires_init_vector(mode)) { - encrypt_block(plaintext, round_keys, iv, ciphertext); - } else { - encrypt_block(plaintext, round_keys, ciphertext); - } -} - -template <Algorithm algorithm, Mode mode> -struct EncryptWrapper { - EncryptWrapper( - const typename Types<algorithm>::Key& key, - const typename Types<algorithm>::Block& iv - ) - : iv{iv} { - expand_key<algorithm>(key, encryption_keys); - } - - void encrypt_block( - const typename Types<algorithm>::Block& plaintext, - typename Types<algorithm>::Block& ciphertext - ) { - aes::encrypt_block<algorithm, mode>(plaintext, encryption_keys, iv, ciphertext); - } - - typename Types<algorithm>::Block iv; - typename Types<algorithm>::RoundKeys encryption_keys; -}; - -template <Algorithm algorithm, Mode mode> -struct DecryptWrapper { - DecryptWrapper( - const typename Types<algorithm>::Key& key, - const typename Types<algorithm>::Block& iv - ) - : iv{iv} { - typename Types<algorithm>::RoundKeys encryption_keys; - expand_key<algorithm>(key, encryption_keys); - - if constexpr (mode_uses_encryption_keys_only(mode)) { - decryption_keys = encryption_keys; - } else { - derive_decryption_keys<algorithm>(encryption_keys, decryption_keys); - } - } - - void decrypt_block( - const typename Types<algorithm>::Block& ciphertext, - typename Types<algorithm>::Block& plaintext - ) { - aes::decrypt_block<algorithm, mode>(ciphertext, decryption_keys, iv, plaintext); - } - - typename Types<algorithm>::Block iv; - typename Types<algorithm>::RoundKeys decryption_keys; -}; - -} // namespace aes diff --git a/aesxx/include/aesxx/box.hpp b/aesxx/include/aesxx/box.hpp index 870b3a7..c2ea6c9 100644 --- a/aesxx/include/aesxx/box.hpp +++ b/aesxx/include/aesxx/box.hpp @@ -6,12 +6,14 @@ #pragma once #include "algorithm.hpp" +#include "data.hpp" #include "error.hpp" #include "mode.hpp" #include <aes/all.h> #include <cstddef> +#include <iostream> #include <string> #include <string_view> #include <vector> @@ -20,43 +22,48 @@ namespace aes { class Box { public: - typedef AES_Block Block; - typedef AES_BoxKey Key; + using Key = AES_Key; + /* static std::string format_key(const Key& src, Algorithm algorithm) { - AES_BoxKeyString str; - aes_box_format_key(&str, algorithm, &src, ErrorDetailsThrowsInDestructor{}); + AES_KeyString str; + aes_format_key(&str, algorithm, &src, ErrorDetailsThrowsInDestructor{}); return reinterpret_cast<const char*>(&str); } + */ - static std::string format_block(const Block& src) { - AES_BlockString str; - aes_format_block(&str, &src, ErrorDetailsThrowsInDestructor{}); - return reinterpret_cast<const char*>(&str); - } - - static void parse_block(Block& dest, std::string_view src) { - aes_parse_block(&dest, src.data(), ErrorDetailsThrowsInDestructor{}); + static void parse_key(Key& dest, Algorithm algorithm, std::string_view src) { + aes_parse_key(algorithm, &dest, src.data(), ErrorDetailsThrowsInDestructor{}); } - static void parse_key(Key& dest, Algorithm algorithm, std::string_view src) { - aes_box_parse_key(&dest, algorithm, src.data(), ErrorDetailsThrowsInDestructor{}); + Box(Algorithm algorithm, const Key& key, Mode mode, const std::optional<Block>& iv) { + aes_box_init( + &impl, algorithm, &key, mode, iv ? iv->ptr() : NULL, ErrorDetailsThrowsInDestructor{} + ); } - Box(Algorithm algorithm, const Key& key) { - aes_box_init(&impl, algorithm, &key, AES_ECB, nullptr, ErrorDetailsThrowsInDestructor{}); + Algorithm get_algorithm() const { + return impl.algorithm; } - Box(Algorithm algorithm, const Key& key, Mode mode, const Block& iv) { - aes_box_init(&impl, algorithm, &key, mode, &iv, ErrorDetailsThrowsInDestructor{}); + Mode get_mode() const { + return impl.mode; } void encrypt_block(const Block& plaintext, Block& ciphertext) { - aes_box_encrypt_block(&impl, &plaintext, &ciphertext, ErrorDetailsThrowsInDestructor{}); + dump_block("Plaintext", plaintext); + aes_box_encrypt_block( + &impl, plaintext.ptr(), ciphertext.ptr(), ErrorDetailsThrowsInDestructor{} + ); + dump_block("Ciphertext", ciphertext); } void decrypt_block(const Block& ciphertext, Block& plaintext) { - aes_box_decrypt_block(&impl, &ciphertext, &plaintext, ErrorDetailsThrowsInDestructor{}); + dump_block("Ciphertext", ciphertext); + aes_box_decrypt_block( + &impl, ciphertext.ptr(), plaintext.ptr(), ErrorDetailsThrowsInDestructor{} + ); + dump_block("Plaintext", plaintext); } std::vector<unsigned char> encrypt_buffer(const void* src_buf, std::size_t src_size) { @@ -105,26 +112,16 @@ public: return dest_buf; } - std::string format_key(const Key& src) { - return format_key(src, get_algorithm()); - } - - void parse_key(Key& dest, std::string_view src) { - parse_key(dest, get_algorithm(), src); - } - - Algorithm get_algorithm() const { - return impl.algorithm; - } - - Mode get_mode() const { - return impl.mode; - } - private: - Key key; + void dump_block(std::string_view header, const Block& block) { + if (verbose > 0) + std::cout << std::format("{}: {}\n", header, block.to_string()); + if (verbose > 1) + std::cout << std::format("{}\n", block.to_matrix_string()); + } AES_Box impl; + int verbose = 0; }; } // namespace aes diff --git a/aesxx/include/aesxx/data.hpp b/aesxx/include/aesxx/data.hpp index 8e4691d..7500913 100644 --- a/aesxx/include/aesxx/data.hpp +++ b/aesxx/include/aesxx/data.hpp @@ -5,40 +5,54 @@ #pragma once +#include "algorithm.hpp" #include "error.hpp" #include <aes/all.h> +#include <string> +#include <string_view> + namespace aes { -typedef AES_Block Block128; +class Block { +public: + static Block parse(std::string_view src) { + return Block{src}; + } + + explicit Block(AES_Block impl) : impl{impl} {} + + Block(int hi3, int hi2, int lo1, int lo0) : impl{aes_make_block(hi3, hi2, lo1, lo0)} {} -inline void make_block(Block128& dest, int hi3, int hi2, int lo1, int lo0) { - dest = aes_make_block(hi3, hi2, lo1, lo0); -} + Block() : Block{0, 0, 0, 0} {} -inline void load_block(Block128& dest, const void* src) { - dest = aes_load_block(src); -} + explicit Block(std::string_view src) { + aes_parse_block(&impl, src.data(), ErrorDetailsThrowsInDestructor{}); + } -inline void load_block_aligned(Block128& dest, const void* src) { - dest = aes_load_block_aligned(src); -} + AES_Block* ptr() { + return &impl; + } -inline void store_block(void* dest, Block128& src) { - aes_store_block(dest, src); -} + const AES_Block* ptr() const { + return &impl; + } -inline void store_block_aligned(void* dest, Block128& src) { - aes_store_block_aligned(dest, src); -} + std::string to_string() const { + AES_BlockString str; + aes_format_block(&str, &impl, ErrorDetailsThrowsInDestructor{}); + return str.str; + } -inline Block128 xor_blocks(Block128& a, Block128& b) { - return aes_xor_blocks(a, b); -} + std::string to_matrix_string() const { + AES_BlockMatrixString str; + aes_format_block_as_matrix(&str, &impl, ErrorDetailsThrowsInDestructor{}); + return str.str; + } -inline Block128 inc_block(Block128& block) { - return aes_inc_block(block); -} +private: + AES_Block impl; +}; } // namespace aes diff --git a/aesxx/include/aesxx/mode.hpp b/aesxx/include/aesxx/mode.hpp index d6f282a..a0b279f 100644 --- a/aesxx/include/aesxx/mode.hpp +++ b/aesxx/include/aesxx/mode.hpp @@ -7,128 +7,8 @@ #include <aes/all.h> -#include <type_traits> - namespace aes { typedef AES_Mode Mode; -inline constexpr bool mode_requires_init_vector(Mode mode) { - return mode != AES_ECB; -} - -inline constexpr bool mode_uses_encryption_keys_only(Mode mode) { - return mode != AES_ECB && mode != AES_CBC; -} - -#define AESXX_ENCRYPT_BLOCK_ECB(version) \ - template <> \ - inline void encrypt_block<AES_AES##version, AES_ECB>( \ - const typename Types<AES_AES##version>::Block& plaintext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block&, \ - typename Types<AES_AES##version>::Block& ciphertext \ - ) { \ - ciphertext = aes##version##_encrypt_block_ECB(plaintext, &encryption_keys); \ - } - -#define AESXX_DECRYPT_BLOCK_ECB(version) \ - template <> \ - inline void decrypt_block<AES_AES##version, AES_ECB>( \ - const typename Types<AES_AES##version>::Block& ciphertext, \ - const typename Types<AES_AES##version>::RoundKeys& decryption_keys, \ - typename Types<AES_AES##version>::Block&, \ - typename Types<AES_AES##version>::Block& plaintext \ - ) { \ - plaintext = aes##version##_decrypt_block_ECB(ciphertext, &decryption_keys); \ - } - -#define AESXX_ENCRYPT_BLOCK_CBC(version) \ - template <> \ - inline void encrypt_block<AES_AES##version, AES_CBC>( \ - const typename Types<AES_AES##version>::Block& plaintext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& ciphertext \ - ) { \ - ciphertext = aes##version##_encrypt_block_CBC(plaintext, &encryption_keys, iv, &iv); \ - } - -#define AESXX_DECRYPT_BLOCK_CBC(version) \ - template <> \ - inline void decrypt_block<AES_AES##version, AES_CBC>( \ - const typename Types<AES_AES##version>::Block& ciphertext, \ - const typename Types<AES_AES##version>::RoundKeys& decryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& plaintext \ - ) { \ - plaintext = aes##version##_decrypt_block_CBC(ciphertext, &decryption_keys, iv, &iv); \ - } - -#define AESXX_ENCRYPT_BLOCK_CFB(version) \ - template <> \ - inline void encrypt_block<AES_AES##version, AES_CFB>( \ - const typename Types<AES_AES##version>::Block& plaintext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& ciphertext \ - ) { \ - ciphertext = aes##version##_encrypt_block_CFB(plaintext, &encryption_keys, iv, &iv); \ - } - -#define AESXX_DECRYPT_BLOCK_CFB(version) \ - template <> \ - inline void decrypt_block<AES_AES##version, AES_CFB>( \ - const typename Types<AES_AES##version>::Block& ciphertext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& plaintext \ - ) { \ - plaintext = aes##version##_decrypt_block_CFB(ciphertext, &encryption_keys, iv, &iv); \ - } - -#define AESXX_ENCRYPT_BLOCK_OFB(version) \ - template <> \ - inline void encrypt_block<AES_AES##version, AES_OFB>( \ - const typename Types<AES_AES##version>::Block& plaintext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& ciphertext \ - ) { \ - ciphertext = aes##version##_encrypt_block_OFB(plaintext, &encryption_keys, iv, &iv); \ - } - -#define AESXX_DECRYPT_BLOCK_OFB(version) \ - template <> \ - inline void decrypt_block<AES_AES##version, AES_OFB>( \ - const typename Types<AES_AES##version>::Block& ciphertext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& plaintext \ - ) { \ - plaintext = aes##version##_decrypt_block_OFB(ciphertext, &encryption_keys, iv, &iv); \ - } - -#define AESXX_ENCRYPT_BLOCK_CTR(version) \ - template <> \ - inline void encrypt_block<AES_AES##version, AES_CTR>( \ - const typename Types<AES_AES##version>::Block& plaintext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& ciphertext \ - ) { \ - ciphertext = aes##version##_encrypt_block_CTR(plaintext, &encryption_keys, iv, &iv); \ - } - -#define AESXX_DECRYPT_BLOCK_CTR(version) \ - template <> \ - inline void decrypt_block<AES_AES##version, AES_CTR>( \ - const typename Types<AES_AES##version>::Block& ciphertext, \ - const typename Types<AES_AES##version>::RoundKeys& encryption_keys, \ - typename Types<AES_AES##version>::Block& iv, \ - typename Types<AES_AES##version>::Block& plaintext \ - ) { \ - plaintext = aes##version##_decrypt_block_CTR(ciphertext, &encryption_keys, iv, &iv); \ - } - } // namespace aes 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 |
