• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 21780928802

07 Feb 2026 01:36PM UTC coverage: 90.068% (+0.003%) from 90.065%
21780928802

Pull #5295

github

web-flow
Merge cbabeb61a into ebf8f0044
Pull Request #5295: Reduce header dependencies in tests and cli

102234 of 113508 relevant lines covered (90.07%)

11464546.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.62
/src/tests/test_mac.cpp
1
/*
2
* (C) 2014,2015 Jack Lloyd
3
* (C) 2016 René Korthaus
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include "tests.h"
9

10
#if defined(BOTAN_HAS_MAC)
11
   #include <botan/exceptn.h>
12
   #include <botan/mac.h>
13
   #include <botan/rng.h>
14
   #include <botan/internal/fmt.h>
15
#endif
16

17
namespace Botan_Tests {
18

19
namespace {
20

21
#if defined(BOTAN_HAS_MAC)
22

23
class Message_Auth_Tests final : public Text_Based_Test {
×
24
   public:
25
      Message_Auth_Tests() : Text_Based_Test("mac", "Key,In,Out", "IV") {}
2✔
26

27
      std::vector<std::string> possible_providers(const std::string& algo) override {
1,199✔
28
         return provider_filter(Botan::MessageAuthenticationCode::providers(algo));
1,199✔
29
      }
30

31
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override {
1,199✔
32
         const std::vector<uint8_t> key = vars.get_req_bin("Key");
1,199✔
33
         const std::vector<uint8_t> input = vars.get_req_bin("In");
1,199✔
34
         const std::vector<uint8_t> expected = vars.get_req_bin("Out");
1,199✔
35
         const std::vector<uint8_t> iv = vars.get_opt_bin("IV");
1,199✔
36

37
         Test::Result result(algo);
2,398✔
38

39
         const std::vector<std::string> providers = possible_providers(algo);
1,199✔
40

41
         if(providers.empty()) {
1,199✔
42
            result.note_missing("MAC " + algo);
×
43
            return result;
×
44
         }
45

46
         for(const auto& provider_ask : providers) {
2,398✔
47
            auto mac = Botan::MessageAuthenticationCode::create(algo, provider_ask);
1,199✔
48

49
            if(!mac) {
1,199✔
50
               result.test_failure(Botan::fmt("MAC {} supported by {} but not found", algo, provider_ask));
×
51
               continue;
×
52
            }
53

54
            const std::string provider(mac->provider());
1,199✔
55

56
            result.test_is_nonempty("provider", provider);
1,199✔
57
            result.test_eq(provider, mac->name(), algo);
1,199✔
58

59
            try {
1,199✔
60
               std::vector<uint8_t> buf(128);
1,199✔
61
               mac->update(buf.data(), buf.size());
1,199✔
62
               result.test_failure("Was able to MAC without a key being set");
1,199✔
63
            } catch(Botan::Invalid_State&) {
1,199✔
64
               result.test_success("Trying to MAC with no key set fails");
1,199✔
65
            }
1,199✔
66

67
            result.test_eq("key not set", mac->has_keying_material(), false);
1,199✔
68
            mac->set_key(key);
1,199✔
69
            result.test_eq("key set", mac->has_keying_material(), true);
1,199✔
70
            mac->start(iv);
1,199✔
71
            mac->update(input);
1,199✔
72
            result.test_eq(provider, "correct mac", mac->final(), expected);
2,398✔
73

74
            mac->set_key(key);
1,199✔
75
            mac->start(iv);
1,199✔
76
            mac->update(input);
1,199✔
77
            result.test_eq(provider, "correct mac (try 2)", mac->final(), expected);
2,398✔
78

79
            if(iv.empty()) {
1,199✔
80
               mac->set_key(key);
624✔
81
               mac->update(input);
624✔
82
               result.test_eq(provider, "correct mac (no start call)", mac->final(), expected);
1,872✔
83
            }
84

85
            if(!mac->fresh_key_required_per_message()) {
1,199✔
86
               for(size_t i = 0; i != 3; ++i) {
4,108✔
87
                  mac->start(iv);
3,081✔
88
                  mac->update(input);
3,081✔
89
                  result.test_eq(provider, "correct mac (same key)", mac->final(), expected);
9,243✔
90
               }
91
            }
92

93
            // Test to make sure clear() resets what we need it to
94
            mac->set_key(key);
1,199✔
95
            mac->start(iv);
1,199✔
96
            mac->update("some discarded input");
1,199✔
97
            mac->clear();
1,199✔
98
            result.test_eq("key not set", mac->has_keying_material(), false);
1,199✔
99

100
            // do the same to test verify_mac()
101
            mac->set_key(key);
1,199✔
102
            mac->start(iv);
1,199✔
103
            mac->update(input);
1,199✔
104

105
            // Test that clone works and does not affect parent object
106
            auto clone = mac->new_object();
1,199✔
107
            result.confirm("Clone has different pointer", mac.get() != clone.get());
2,398✔
108
            result.test_eq("Clone has same name", mac->name(), clone->name());
2,398✔
109
            clone->set_key(key);
1,199✔
110
            clone->start(iv);
1,199✔
111
            clone->update(this->rng().random_vec(32));
1,199✔
112

113
            result.test_eq(provider + " verify mac", mac->verify_mac(expected.data(), expected.size()), true);
1,199✔
114

115
            if(input.size() > 2) {
1,199✔
116
               mac->set_key(key);  // Poly1305 requires the re-key
1,156✔
117
               mac->start(iv);
1,156✔
118

119
               mac->update(input[0]);
1,156✔
120
               mac->update(&input[1], input.size() - 2);
1,156✔
121
               mac->update(input[input.size() - 1]);
1,156✔
122

123
               result.test_eq(provider, "split mac", mac->final(), expected);
2,312✔
124

125
               // do the same to test verify_mac()
126
               mac->set_key(key);
1,156✔
127
               mac->start(iv);
1,156✔
128

129
               mac->update(input[0]);
1,156✔
130
               mac->update(&input[1], input.size() - 2);
1,156✔
131
               mac->update(input[input.size() - 1]);
1,156✔
132

133
               result.test_eq(provider + " split mac", mac->verify_mac(expected.data(), expected.size()), true);
2,312✔
134
            }
135

136
            mac->clear();
1,199✔
137

138
            try {
1,199✔
139
               std::vector<uint8_t> buf(128);
1,199✔
140
               mac->update(buf.data(), buf.size());
1,199✔
141
               result.test_failure("Was able to MAC without a key being set");
1,199✔
142
            } catch(Botan::Invalid_State&) {
1,199✔
143
               result.test_success("Trying to MAC with no key set (after clear) fails");
1,199✔
144
            }
1,199✔
145

146
            try {
1,199✔
147
               std::vector<uint8_t> buf(mac->output_length());
1,199✔
148
               mac->final(buf.data());
1,199✔
149
               result.test_failure("Was able to MAC without a key being set");
1,199✔
150
            } catch(Botan::Invalid_State&) {
1,199✔
151
               result.test_success("Trying to MAC with no key set (after clear) fails");
1,199✔
152
            }
1,199✔
153
         }
2,398✔
154

155
         return result;
156
      }
5,371✔
157
};
158

159
BOTAN_REGISTER_SERIALIZED_SMOKE_TEST("mac", "mac_algos", Message_Auth_Tests);
160

161
#endif
162

163
}  // namespace
164

165
}  // namespace Botan_Tests
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc