diff options
| author | Egor Tensin <egor@tensin.name> | 2026-06-23 02:22:15 +0200 |
|---|---|---|
| committer | Egor Tensin <egor@tensin.name> | 2026-06-23 02:22:30 +0200 |
| commit | 11b023f2be3ef9e563e244228daac917f917c29d (patch) | |
| tree | c7217597ba4a1ecb2cf8192d7de8b9c9ca62145a | |
| parent | aesxx/utils: some more basic refactoring (diff) | |
| download | aes-tools-11b023f2be3ef9e563e244228daac917f917c29d.tar.gz aes-tools-11b023f2be3ef9e563e244228daac917f917c29d.zip | |
aesxx/utils: add some basic usage tests
| -rw-r--r-- | aesxx/utils/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | aesxx/utils/decrypt_block.cpp | 4 | ||||
| -rw-r--r-- | aesxx/utils/decrypt_bmp.cpp | 2 | ||||
| -rw-r--r-- | aesxx/utils/decrypt_file.cpp | 2 | ||||
| -rw-r--r-- | aesxx/utils/encrypt_block.cpp | 4 | ||||
| -rw-r--r-- | aesxx/utils/encrypt_bmp.cpp | 2 | ||||
| -rw-r--r-- | aesxx/utils/encrypt_file.cpp | 2 | ||||
| -rw-r--r-- | aesxx/utils/helpers/cmd_parser_block.hpp | 6 | ||||
| -rw-r--r-- | aesxx/utils/helpers/cmd_parser_file.hpp | 8 | ||||
| -rw-r--r-- | aesxx/utils/test/basic.cmake | 66 | ||||
| -rw-r--r-- | aesxx/utils/test/block.cmake | 99 | ||||
| m--------- | cmake | 0 |
12 files changed, 191 insertions, 9 deletions
diff --git a/aesxx/utils/CMakeLists.txt b/aesxx/utils/CMakeLists.txt index 81bd818..114efa5 100644 --- a/aesxx/utils/CMakeLists.txt +++ b/aesxx/utils/CMakeLists.txt @@ -39,3 +39,8 @@ set(bmp_util_headers ${file_util_headers} helpers/bmp.hpp) add_util(encrypt_bmp encrypt_bmp.cpp ${bmp_util_headers}) add_util(decrypt_bmp decrypt_bmp.cpp ${bmp_util_headers}) + +find_package(Python3 REQUIRED COMPONENTS Interpreter) + +include(test/basic.cmake) +include(test/block.cmake) diff --git a/aesxx/utils/decrypt_block.cpp b/aesxx/utils/decrypt_block.cpp index cb14bef..ddca7ba 100644 --- a/aesxx/utils/decrypt_block.cpp +++ b/aesxx/utils/decrypt_block.cpp @@ -23,7 +23,7 @@ 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 constexpr (aes::mode_requires_init_vector(mode)) { + if (input.has_iv()) { aes::from_string<algorithm>(iv, input.get_iv()); if (verbose) dump_iv<algorithm>(iv); @@ -131,7 +131,7 @@ void decrypt_using_boxes( aes::Box::Key key; aes::Box::parse_key(key, algorithm, input.get_key()); - if (aes::mode_requires_init_vector(mode)) { + if (input.has_iv()) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, input.get_iv()); aes::Box box{algorithm, key, mode, iv}; diff --git a/aesxx/utils/decrypt_bmp.cpp b/aesxx/utils/decrypt_bmp.cpp index 84286ef..e181081 100644 --- a/aesxx/utils/decrypt_bmp.cpp +++ b/aesxx/utils/decrypt_bmp.cpp @@ -37,7 +37,7 @@ void decrypt_bmp(const FileSettings& settings) { aes::Box::Key key; aes::Box::parse_key(key, algorithm, settings.get_key()); - if (aes::mode_requires_init_vector(mode)) { + if (settings.has_iv()) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, settings.get_iv()); diff --git a/aesxx/utils/decrypt_file.cpp b/aesxx/utils/decrypt_file.cpp index 39084fd..4aa7d6b 100644 --- a/aesxx/utils/decrypt_file.cpp +++ b/aesxx/utils/decrypt_file.cpp @@ -35,7 +35,7 @@ void decrypt_file(const FileSettings& settings) { aes::Box::Key key; aes::Box::parse_key(key, algorithm, settings.get_key()); - if (aes::mode_requires_init_vector(mode)) { + if (settings.has_iv()) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, settings.get_iv()); diff --git a/aesxx/utils/encrypt_block.cpp b/aesxx/utils/encrypt_block.cpp index e1a4c1e..2bad94e 100644 --- a/aesxx/utils/encrypt_block.cpp +++ b/aesxx/utils/encrypt_block.cpp @@ -23,7 +23,7 @@ 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 constexpr (aes::mode_requires_init_vector(mode)) { + if (input.has_iv()) { aes::from_string<algorithm>(iv, input.get_iv()); if (verbose) dump_iv<algorithm>(iv); @@ -134,7 +134,7 @@ void encrypt_using_boxes( aes::Box::Key key; aes::Box::parse_key(key, algorithm, input.get_key()); - if (aes::mode_requires_init_vector(mode)) { + if (input.has_iv()) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, input.get_iv()); aes::Box box{algorithm, key, mode, iv}; diff --git a/aesxx/utils/encrypt_bmp.cpp b/aesxx/utils/encrypt_bmp.cpp index 2a22e73..6487a3a 100644 --- a/aesxx/utils/encrypt_bmp.cpp +++ b/aesxx/utils/encrypt_bmp.cpp @@ -35,7 +35,7 @@ void encrypt_bmp(const FileSettings& settings) { aes::Box::Key key; aes::Box::parse_key(key, algorithm, settings.get_key()); - if (aes::mode_requires_init_vector(mode)) { + if (settings.has_iv()) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, settings.get_iv()); diff --git a/aesxx/utils/encrypt_file.cpp b/aesxx/utils/encrypt_file.cpp index 9f08378..d2d0e51 100644 --- a/aesxx/utils/encrypt_file.cpp +++ b/aesxx/utils/encrypt_file.cpp @@ -35,7 +35,7 @@ void encrypt_file(const FileSettings& settings) { aes::Box::Key key; aes::Box::parse_key(key, algorithm, settings.get_key()); - if (aes::mode_requires_init_vector(mode)) { + if (settings.has_iv()) { aes::Box::Block iv; aes::Box::parse_block(iv, algorithm, settings.get_iv()); diff --git a/aesxx/utils/helpers/cmd_parser_block.hpp b/aesxx/utils/helpers/cmd_parser_block.hpp index 68177f5..4226fb5 100644 --- a/aesxx/utils/helpers/cmd_parser_block.hpp +++ b/aesxx/utils/helpers/cmd_parser_block.hpp @@ -33,6 +33,10 @@ public: return key; } + bool has_iv() const { + return !iv.empty(); + } + std::string get_iv() const { return iv; } @@ -85,6 +89,8 @@ public: positional.add("args", -1); SettingsParser::parse(argc, argv); + if (exit_with_usage()) + return; parse_inputs( std::deque<std::string>{ diff --git a/aesxx/utils/helpers/cmd_parser_file.hpp b/aesxx/utils/helpers/cmd_parser_file.hpp index 81562f5..2e710b2 100644 --- a/aesxx/utils/helpers/cmd_parser_file.hpp +++ b/aesxx/utils/helpers/cmd_parser_file.hpp @@ -64,8 +64,10 @@ public: void parse(int argc, char** argv) override { SettingsParser::parse(argc, argv); + if (exit_with_usage()) + return; - if (aes::mode_requires_init_vector(mode) && iv.empty()) { + 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" }; @@ -92,6 +94,10 @@ public: return key; } + bool has_iv() const { + return !iv.empty(); + } + std::string get_iv() const { return iv; } diff --git a/aesxx/utils/test/basic.cmake b/aesxx/utils/test/basic.cmake new file mode 100644 index 0000000..9e9bcc3 --- /dev/null +++ b/aesxx/utils/test/basic.cmake @@ -0,0 +1,66 @@ +foreach(action encrypt decrypt) + foreach(util block file bmp) + set(exe "${action}_${util}") + set(tgt "util_${exe}") + add_test(NAME "${tgt}_help" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --pass-regex "usage: ${exe}\\.exe" "set algorithm" + --fail-regex "usage error:" + -- + "$<TARGET_FILE:${tgt}>" -h + ) + add_test(NAME "${tgt}_no_args" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --exit-code 1 + --pass-regex + "usage error: the option '--algorithm' is required" + "usage: ${exe}\\.exe" + "set algorithm" + -- + "$<TARGET_FILE:${tgt}>" + ) + endforeach() + + set(exe "${action}_block") + set(tgt "util_${exe}") + add_test(NAME "${tgt}_no_input" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --fail-regex ".+" + -- + "$<TARGET_FILE:${tgt}>" -a aes256 -m ofb + ) + add_test(NAME "${tgt}_only_key" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --fail-regex ".+" + -- + "$<TARGET_FILE:${tgt}>" -a AES256 -m ECB 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + ) + add_test(NAME "${tgt}_invalid_algorithm" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --exit-code 1 + --pass-regex "usage error:" "for option '--algorithm' is invalid" + -- + "$<TARGET_FILE:${tgt}>" -a bar -m ecb + ) + add_test(NAME "${tgt}_invalid_mode" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --exit-code 1 + --pass-regex "usage error:" "for option '--mode' is invalid" + -- + "$<TARGET_FILE:${tgt}>" -a aes128 -m foo + ) + add_test(NAME "${tgt}_no_iv" COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --exit-code 1 + --pass-regex "usage error: an initialization vector is required" + -- + "$<TARGET_FILE:${tgt}>" -a aes192 -m cbc 000102030405060708090a0b0c0d0e0f1011121314151617 + ) +endforeach() diff --git a/aesxx/utils/test/block.cmake b/aesxx/utils/test/block.cmake new file mode 100644 index 0000000..c6aa196 --- /dev/null +++ b/aesxx/utils/test/block.cmake @@ -0,0 +1,99 @@ +set(algorithms + aes128 + aes192 +) +set(modes + ecb + cbc +) + +set(plaintexts + 00112233445566778899aabbccddeeff + 889b6b42db774ce1147a6659778c40e0 + 00000000000000000000000000000000 +) + +set(init_vectors_ecb "" "" "") +set(init_vectors_cbc + 00000000000000000000000000000000 + 11111111111111111111111111111111 + a1e6f520bade7165f07486a185c53de7 +) + +set(keys_aes128 + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000000 + 59713bfd33668d766c23a5dc8961f112 +) +set(ciphertexts_aes128_ecb + 69c4e0d86a7b0430d8cdb78070b4c55a + 69233b712f1c3429986f65725ef1d4e3 + ea3776a8de8c11dedfa228f185e0f639 +) +set(ciphertexts_aes128_cbc + 69c4e0d86a7b0430d8cdb78070b4c55a + d30635a430ec897ffa64539447ce219e + 2eef761f20842bb451799b56ac1b9731 +) + +set(keys_aes192 + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000000000000000000000000000000000000000000000000 + a07857432a0e045446509c1dde49d05ce91da019d1917b67 +) +set(ciphertexts_aes192_ecb + dda97ca4864cdfe06eaf70a0ec0d7191 + 5e4357a8e0f098948190fbd286641d9b + 183e763c8166fc52086a7b3e51bdd3d6 +) +set(ciphertexts_aes192_cbc + dda97ca4864cdfe06eaf70a0ec0d7191 + 188bf0d78406d7edf03111539f0e5fd7 + ab0f7f0470888795722b302c51b91883 +) + +# Skipping AES256... + +foreach(algorithm ${algorithms}) + foreach(mode ${modes}) + set(input "") + foreach(blocks IN ZIP_LISTS "keys_${algorithm}" "init_vectors_${mode}" plaintexts) + list(APPEND input -- "${blocks_0}") + if(NOT "${blocks_1}" STREQUAL "") + list(APPEND input "${blocks_1}") + endif() + list(APPEND input "${blocks_2}") + endforeach() + string(JOIN "\n" output ${ciphertexts_${algorithm}_${mode}}) + + message(STATUS "Adding test for encrypt_block (${algorithm}/${mode})") + add_test(NAME "util_encrypt_block_${algorithm}_${mode}" + COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --pass-regex "^${output}$" + -- + "$<TARGET_FILE:util_encrypt_block>" -a "${algorithm}" -m "${mode}" ${input} + ) + + set(input "") + foreach(blocks IN ZIP_LISTS "keys_${algorithm}" "init_vectors_${mode}" "ciphertexts_${algorithm}_${mode}") + list(APPEND input -- "${blocks_0}") + if(NOT "${blocks_1}" STREQUAL "") + list(APPEND input "${blocks_1}") + endif() + list(APPEND input "${blocks_2}") + endforeach() + string(JOIN "\n" output ${plaintexts}) + + message(STATUS "Adding test for decrypt_block (${algorithm}/${mode})") + add_test(NAME "util_decrypt_block_${algorithm}_${mode}" + COMMAND Python3::Interpreter + "${CMAKE_SOURCE_DIR}/cmake/tools/ctest-driver.py" + run + --pass-regex "^${output}$" + -- + "$<TARGET_FILE:util_decrypt_block>" -a "${algorithm}" -m "${mode}" ${input} + ) + endforeach() +endforeach() diff --git a/cmake b/cmake -Subproject 8c555846f9c354ce2c56cc3ef9a1ce1fe34dffd +Subproject 88a20a8b36ded8137c5bedb6851c3974926e68d |
