aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/test_aead.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/test_aead.cpp')
-rw-r--r--src/tests/test_aead.cpp208
1 files changed, 96 insertions, 112 deletions
diff --git a/src/tests/test_aead.cpp b/src/tests/test_aead.cpp
index 5fe4011fb..a9545a736 100644
--- a/src/tests/test_aead.cpp
+++ b/src/tests/test_aead.cpp
@@ -7,147 +7,131 @@
#include "tests.h"
#if defined(BOTAN_HAS_AEAD_MODES)
-
-#include <botan/hex.h>
#include <botan/aead.h>
-#include <iostream>
-#include <fstream>
-#include <memory>
+#endif
-using namespace Botan;
+namespace Botan_Tests {
namespace {
-size_t aead_test(const std::string& algo,
- const std::string& input,
- const std::string& expected,
- const std::string& nonce_hex,
- const std::string& ad_hex,
- const std::string& key_hex)
- {
- const auto nonce = hex_decode_locked(nonce_hex);
- const auto ad = hex_decode_locked(ad_hex);
- const auto key = hex_decode_locked(key_hex);
-
- std::unique_ptr<Cipher_Mode> enc(get_aead(algo, ENCRYPTION));
- std::unique_ptr<Cipher_Mode> dec(get_aead(algo, DECRYPTION));
-
- if(!enc || !dec)
- throw std::runtime_error("Unknown AEAD '" + algo + "'");
-
- enc->set_key(key);
- dec->set_key(key);
-
- if(auto aead_enc = dynamic_cast<AEAD_Mode*>(enc.get()))
- aead_enc->set_associated_data_vec(ad);
- if(auto aead_dec = dynamic_cast<AEAD_Mode*>(dec.get()))
- aead_dec->set_associated_data_vec(ad);
+#if defined(BOTAN_HAS_AEAD_MODES)
- size_t fail = 0;
+class AEAD_Tests : public Text_Based_Test
+ {
+ public:
+ AEAD_Tests() :
+ Text_Based_Test(Test::data_dir("aead"), {"Key", "Nonce", "In", "Out"}, {"AD"})
+ {}
- const auto pt = hex_decode_locked(input);
- const auto expected_ct = hex_decode_locked(expected);
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> nonce = get_opt_bin(vars, "Nonce");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
+ const std::vector<uint8_t> ad = get_opt_bin(vars, "AD");
- auto vec = pt;
- enc->start(nonce);
- // should first update if possible
- enc->finish(vec);
+ Test::Result result(algo);
- if(vec != expected_ct)
- {
- std::cout << algo << " got ct " << hex_encode(vec) << " expected " << expected << std::endl;
- ++fail;
- }
+ std::unique_ptr<Botan::AEAD_Mode> enc(Botan::get_aead(algo, Botan::ENCRYPTION));
+ std::unique_ptr<Botan::AEAD_Mode> dec(Botan::get_aead(algo, Botan::DECRYPTION));
- vec = expected_ct;
+ if(!enc || !dec)
+ {
+ result.note_missing(algo);
+ return result;
+ }
- dec->start(nonce);
- dec->finish(vec);
+ enc->set_key(key);
+ enc->set_associated_data_vec(ad);
+ enc->start(nonce);
- if(vec != pt)
- {
- std::cout << algo << " got pt " << hex_encode(vec) << " expected " << input << std::endl;
- ++fail;
- }
+ Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
+ // TODO: should first update if possible
+ enc->finish(buf);
- if(enc->authenticated())
- {
- vec = expected_ct;
- vec[0] ^= 1;
- dec->start(nonce);
- try
- {
- dec->finish(vec);
- std::cout << algo << " accepted message with modified message" << std::endl;
- ++fail;
- }
- catch(...) {}
+ result.test_eq("encrypt", buf, expected);
- if(nonce.size())
- {
- auto bad_nonce = nonce;
- bad_nonce[0] ^= 1;
- vec = expected_ct;
+ buf.assign(expected.begin(), expected.end());
- dec->start(bad_nonce);
+ dec->set_key(key);
+ dec->set_associated_data_vec(ad);
+ dec->start(nonce);
+ dec->finish(buf);
- try
+ if(enc->authenticated())
{
- dec->finish(vec);
- std::cout << algo << " accepted message with modified nonce" << std::endl;
- ++fail;
+ const std::vector<byte> mutated_input = mutate_vec(expected, true);
+ buf.assign(mutated_input.begin(), mutated_input.end());
+
+ dec->start(nonce);
+
+ try
+ {
+ dec->finish(buf);
+ result.test_failure("accepted modified message", mutated_input);
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("correctly rejected modified message");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("unexpected error while rejecting modified message", e.what());
+ }
}
- catch(...) {}
- }
- if(auto aead_dec = dynamic_cast<AEAD_Mode*>(dec.get()))
- {
- auto bad_ad = ad;
+ if(nonce.size() > 0)
+ {
+ buf.assign(expected.begin(), expected.end());
+ std::vector<byte> bad_nonce = mutate_vec(nonce);
+
+ dec->start(bad_nonce);
+
+ try
+ {
+ dec->finish(buf);
+ result.test_failure("accepted message with modified nonce", bad_nonce);
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("correctly rejected modified nonce");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("unexpected error while rejecting modified nonce", e.what());
+ }
+ }
- if(ad.size())
- bad_ad[0] ^= 1;
- else
- bad_ad.push_back(0);
+ const std::vector<byte> bad_ad = mutate_vec(ad, true);
- aead_dec->set_associated_data_vec(bad_ad);
+ dec->set_associated_data_vec(bad_ad);
- vec = expected_ct;
dec->start(nonce);
try
{
- dec->finish(vec);
- std::cout << algo << " accepted message with modified AD" << std::endl;
- ++fail;
+ buf.assign(expected.begin(), expected.end());
+ dec->finish(buf);
+ result.test_failure("accepted message with modified ad", bad_ad);
+ }
+ catch(Botan::Integrity_Failure& e)
+ {
+ result.test_note("correctly rejected modified ad");
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("unexpected error while rejecting modified nonce", e.what());
}
- catch(...) {}
- }
- }
-
- return fail;
- }
-
-}
-
-size_t test_aead()
- {
- auto test = [](const std::string& input)
- {
- std::ifstream vec(input);
- return run_tests_bb(vec, "AEAD", "Out", true,
- [](std::map<std::string, std::string> m)
- {
- return aead_test(m["AEAD"], m["In"], m["Out"],
- m["Nonce"], m["AD"], m["Key"]);
- });
- };
+ return result;
+ }
+ };
- return run_tests_in_dir(TEST_DATA_DIR "/aead", test);
- }
+BOTAN_REGISTER_TEST("aead", AEAD_Tests);
-#else
+#endif
-SKIP_TEST(aead);
+}
-#endif // BOTAN_HAS_AEAD_MODES
+}