2
* (C) 2014,2015 Jack Lloyd
3
* (C) 2016 René Korthaus
5
* Botan is released under the Simplified BSD License (see license.txt)
10
#if defined(BOTAN_HAS_MAC)
11
#include <botan/mac.h>
14
namespace Botan_Tests {
18
#if defined(BOTAN_HAS_MAC)
20
class Message_Auth_Tests final : public Text_Based_Test
23
Message_Auth_Tests() : Text_Based_Test("mac", "Key,In,Out", "IV") {}
25
std::vector<std::string> possible_providers(const std::string& algo) override
27
return provider_filter(Botan::MessageAuthenticationCode::providers(algo));
30
Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
32
const std::vector<uint8_t> key = get_req_bin(vars, "Key");
33
const std::vector<uint8_t> input = get_req_bin(vars, "In");
34
const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
35
const std::vector<uint8_t> iv = get_opt_bin(vars, "IV");
37
Test::Result result(algo);
39
const std::vector<std::string> providers = possible_providers(algo);
43
result.note_missing("block cipher " + algo);
47
for(auto const& provider_ask : providers)
49
std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create(algo, provider_ask));
53
result.test_failure("MAC " + algo + " supported by " + provider_ask + " but not found");
57
const std::string provider(mac->provider());
59
result.test_is_nonempty("provider", provider);
60
result.test_eq(provider, mac->name(), algo);
64
std::vector<uint8_t> buf(128);
65
mac->update(buf.data(), buf.size());
66
result.test_failure("Was able to MAC without a key being set");
68
catch(Botan::Invalid_State&)
70
result.test_success("Trying to MAC with no key set fails");
78
result.test_eq(provider, "correct mac", mac->final(), expected);
80
// Test to make sure clear() resets what we need it to
83
mac->update("some discarded input");
86
// do the same to test verify_mac()
91
// Test that clone works and does not affect parent object
92
std::unique_ptr<Botan::MessageAuthenticationCode> clone(mac->clone());
93
result.confirm("Clone has different pointer", mac.get() != clone.get());
94
result.test_eq("Clone has same name", mac->name(), clone->name());
97
clone->update(Test::rng().random_vec(32));
99
result.test_eq(provider + " verify mac", mac->verify_mac(expected.data(), expected.size()), true);
103
mac->set_key(key); // Poly1305 requires the re-key
106
mac->update(input[0]);
107
mac->update(&input[1], input.size() - 2);
108
mac->update(input[input.size() - 1]);
110
result.test_eq(provider, "split mac", mac->final(), expected);
112
// do the same to test verify_mac()
116
mac->update(input[ 0 ]);
117
mac->update(&input[ 1 ], input.size() - 2);
118
mac->update(input[ input.size() - 1 ]);
120
result.test_eq(provider + " split mac", mac->verify_mac(expected.data(), expected.size()), true);
127
std::vector<uint8_t> buf(128);
128
mac->update(buf.data(), buf.size());
129
result.test_failure("Was able to MAC without a key being set");
131
catch(Botan::Invalid_State&)
133
result.test_success("Trying to MAC with no key set (after clear) fails");
138
std::vector<uint8_t> buf(mac->output_length());
139
mac->final(buf.data());
140
result.test_failure("Was able to MAC without a key being set");
142
catch(Botan::Invalid_State&)
144
result.test_success("Trying to MAC with no key set (after clear) fails");
152
BOTAN_REGISTER_TEST("mac", Message_Auth_Tests);