Coverage Report

Created: 2026-10-28 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/mac/mac.cpp
Line
Count
Source
1
/*
2
* Message Authentication Code base class
3
* (C) 1999-2008 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/mac.h>
9
10
#include <botan/exceptn.h>
11
#include <botan/internal/algorithm_spec.h>
12
#include <botan/internal/ct_utils.h>
13
#include <botan/internal/probe_providers.h>
14
15
#if defined(BOTAN_HAS_CMAC)
16
   #include <botan/internal/cmac.h>
17
#endif
18
19
#if defined(BOTAN_HAS_GMAC)
20
   #include <botan/block_cipher.h>
21
   #include <botan/internal/gmac.h>
22
#endif
23
24
#if defined(BOTAN_HAS_HMAC)
25
   #include <botan/hash.h>
26
   #include <botan/internal/hmac.h>
27
#endif
28
29
#if defined(BOTAN_HAS_POLY1305)
30
   #include <botan/internal/poly1305.h>
31
#endif
32
33
#if defined(BOTAN_HAS_SIPHASH)
34
   #include <botan/internal/siphash.h>
35
#endif
36
37
#if defined(BOTAN_HAS_ANSI_X919_MAC)
38
   #include <botan/internal/x919_mac.h>
39
#endif
40
41
#if defined(BOTAN_HAS_BLAKE2BMAC)
42
   #include <botan/internal/blake2bmac.h>
43
#endif
44
45
#if defined(BOTAN_HAS_KMAC)
46
   #include <botan/internal/kmac.h>
47
#endif
48
49
namespace Botan {
50
51
std::unique_ptr<MessageAuthenticationCode> MessageAuthenticationCode::create(std::string_view algo_spec,
52
3.26k
                                                                             std::string_view provider) {
53
3.26k
   const AlgorithmSpec req(algo_spec);
54
55
3.26k
#if defined(BOTAN_HAS_BLAKE2BMAC)
56
3.26k
   if(auto m = req.match("BLAKE2b|Blake2b({bits:int=512})")) {
57
0
      if(provider.empty() || provider == "base") {
58
0
         return std::make_unique<BLAKE2bMAC>(m->integer("bits"));
59
0
      }
60
0
   }
61
3.26k
#endif
62
63
3.26k
#if defined(BOTAN_HAS_GMAC)
64
3.26k
   if(auto m = req.match("GMAC({cipher})")) {
65
0
      if(provider.empty() || provider == "base") {
66
0
         if(auto bc = BlockCipher::create(m->str("cipher"))) {
67
0
            return std::make_unique<GMAC>(std::move(bc));
68
0
         }
69
0
      }
70
0
   }
71
3.26k
#endif
72
73
3.26k
#if defined(BOTAN_HAS_HMAC)
74
3.26k
   if(auto m = req.match("HMAC({hash})")) {
75
3.15k
      if(provider.empty() || provider == "base") {
76
3.15k
         if(auto hash = HashFunction::create(m->str("hash"))) {
77
3.15k
            return std::make_unique<HMAC>(std::move(hash));
78
3.15k
         }
79
3.15k
      }
80
3.15k
   }
81
115
#endif
82
83
115
#if defined(BOTAN_HAS_POLY1305)
84
115
   if(req.matches("Poly1305")) {
85
115
      if(provider.empty() || provider == "base") {
86
115
         return std::make_unique<Poly1305>();
87
115
      }
88
115
   }
89
0
#endif
90
91
0
#if defined(BOTAN_HAS_SIPHASH)
92
0
   if(auto m = req.match("SipHash({c:int=2},{d:int=4})")) {
93
0
      if(provider.empty() || provider == "base") {
94
0
         return std::make_unique<SipHash>(m->integer("c"), m->integer("d"));
95
0
      }
96
0
   }
97
0
#endif
98
99
0
#if defined(BOTAN_HAS_CMAC)
100
0
   if(auto m = req.match("CMAC|OMAC({cipher})")) {
101
0
      if(provider.empty() || provider == "base") {
102
0
         if(auto bc = BlockCipher::create(m->str("cipher"))) {
103
0
            return std::make_unique<CMAC>(std::move(bc));
104
0
         }
105
0
      }
106
0
   }
107
0
#endif
108
109
0
#if defined(BOTAN_HAS_ANSI_X919_MAC)
110
0
   if(req.matches("X9.19-MAC")) {
111
0
      if(provider.empty() || provider == "base") {
112
0
         return std::make_unique<ANSI_X919_MAC>();
113
0
      }
114
0
   }
115
0
#endif
116
117
0
#if defined(BOTAN_HAS_KMAC)
118
0
   if(auto m = req.match("KMAC-128({bits:int})")) {
119
0
      if(provider.empty() || provider == "base") {
120
0
         return std::make_unique<KMAC128>(m->integer("bits"));
121
0
      }
122
0
   }
123
124
0
   if(auto m = req.match("KMAC-256({bits:int})")) {
125
0
      if(provider.empty() || provider == "base") {
126
0
         return std::make_unique<KMAC256>(m->integer("bits"));
127
0
      }
128
0
   }
129
0
#endif
130
131
0
   BOTAN_UNUSED(req);
132
0
   BOTAN_UNUSED(provider);
133
134
0
   return nullptr;
135
0
}
136
137
0
std::vector<std::string> MessageAuthenticationCode::providers(std::string_view algo_spec) {
138
0
   return probe_providers_of<MessageAuthenticationCode>(algo_spec);
139
0
}
140
141
//static
142
std::unique_ptr<MessageAuthenticationCode> MessageAuthenticationCode::create_or_throw(std::string_view algo,
143
394
                                                                                      std::string_view provider) {
144
394
   if(auto mac = MessageAuthenticationCode::create(algo, provider)) {
145
394
      return mac;
146
394
   }
147
0
   throw Lookup_Error("MAC", algo, provider);
148
394
}
149
150
/*
151
* Default (deterministic) MAC verification operation
152
*/
153
0
bool MessageAuthenticationCode::verify_mac_result(std::span<const uint8_t> mac) {
154
0
   secure_vector<uint8_t> our_mac = final();
155
156
0
   if(our_mac.size() != mac.size()) {
157
0
      return false;
158
0
   }
159
160
0
   return CT::is_equal(our_mac.data(), mac.data(), mac.size()).as_bool();
161
0
}
162
163
}  // namespace Botan