Coverage Report

Created: 2024-02-25 06:16

/src/botan/src/lib/mac/mac.cpp
Line
Count
Source (jump to first uncovered line)
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/mem_ops.h>
12
#include <botan/internal/ct_utils.h>
13
#include <botan/internal/scan_name.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
5.64k
                                                                             std::string_view provider) {
53
5.64k
   const SCAN_Name req(algo_spec);
54
55
5.64k
#if defined(BOTAN_HAS_BLAKE2BMAC)
56
5.64k
   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") {
57
61
      return std::make_unique<BLAKE2bMAC>(req.arg_as_integer(0, 512));
58
61
   }
59
5.58k
#endif
60
61
5.58k
#if defined(BOTAN_HAS_GMAC)
62
5.58k
   if(req.algo_name() == "GMAC" && req.arg_count() == 1) {
63
0
      if(provider.empty() || provider == "base") {
64
0
         if(auto bc = BlockCipher::create(req.arg(0))) {
65
0
            return std::make_unique<GMAC>(std::move(bc));
66
0
         }
67
0
      }
68
0
   }
69
5.58k
#endif
70
71
5.58k
#if defined(BOTAN_HAS_HMAC)
72
5.58k
   if(req.algo_name() == "HMAC" && req.arg_count() == 1) {
73
4.48k
      if(provider.empty() || provider == "base") {
74
4.48k
         if(auto hash = HashFunction::create(req.arg(0))) {
75
3.76k
            return std::make_unique<HMAC>(std::move(hash));
76
3.76k
         }
77
4.48k
      }
78
4.48k
   }
79
1.81k
#endif
80
81
1.81k
#if defined(BOTAN_HAS_POLY1305)
82
1.81k
   if(req.algo_name() == "Poly1305" && req.arg_count() == 0) {
83
0
      if(provider.empty() || provider == "base") {
84
0
         return std::make_unique<Poly1305>();
85
0
      }
86
0
   }
87
1.81k
#endif
88
89
1.81k
#if defined(BOTAN_HAS_SIPHASH)
90
1.81k
   if(req.algo_name() == "SipHash") {
91
230
      if(provider.empty() || provider == "base") {
92
230
         return std::make_unique<SipHash>(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4));
93
230
      }
94
230
   }
95
1.58k
#endif
96
97
1.58k
#if defined(BOTAN_HAS_CMAC)
98
1.58k
   if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1) {
99
869
      if(provider.empty() || provider == "base") {
100
869
         if(auto bc = BlockCipher::create(req.arg(0))) {
101
869
            return std::make_unique<CMAC>(std::move(bc));
102
869
         }
103
869
      }
104
869
   }
105
719
#endif
106
107
719
#if defined(BOTAN_HAS_ANSI_X919_MAC)
108
719
   if(req.algo_name() == "X9.19-MAC") {
109
0
      if(provider.empty() || provider == "base") {
110
0
         return std::make_unique<ANSI_X919_MAC>();
111
0
      }
112
0
   }
113
719
#endif
114
115
719
#if defined(BOTAN_HAS_KMAC)
116
719
   if(req.algo_name() == "KMAC-128") {
117
0
      if(provider.empty() || provider == "base") {
118
0
         if(req.arg_count() != 1) {
119
0
            throw Invalid_Argument(
120
0
               "invalid algorithm specification for KMAC-128: need exactly one argument for output bit length");
121
0
         }
122
0
         return std::make_unique<KMAC128>(req.arg_as_integer(0));
123
0
      }
124
0
   }
125
126
719
   if(req.algo_name() == "KMAC-256") {
127
0
      if(provider.empty() || provider == "base") {
128
0
         if(req.arg_count() != 1) {
129
0
            throw Invalid_Argument(
130
0
               "invalid algorithm specification for KMAC-256: need exactly one argument for output bit length");
131
0
         }
132
0
         return std::make_unique<KMAC256>(req.arg_as_integer(0));
133
0
      }
134
0
   }
135
719
#endif
136
137
719
   BOTAN_UNUSED(req);
138
719
   BOTAN_UNUSED(provider);
139
140
719
   return nullptr;
141
719
}
142
143
0
std::vector<std::string> MessageAuthenticationCode::providers(std::string_view algo_spec) {
144
0
   return probe_providers_of<MessageAuthenticationCode>(algo_spec);
145
0
}
146
147
//static
148
std::unique_ptr<MessageAuthenticationCode> MessageAuthenticationCode::create_or_throw(std::string_view algo,
149
390
                                                                                      std::string_view provider) {
150
390
   if(auto mac = MessageAuthenticationCode::create(algo, provider)) {
151
390
      return mac;
152
390
   }
153
0
   throw Lookup_Error("MAC", algo, provider);
154
390
}
155
156
0
void MessageAuthenticationCode::start_msg(std::span<const uint8_t> nonce) {
157
0
   BOTAN_UNUSED(nonce);
158
0
   if(!nonce.empty()) {
159
0
      throw Invalid_IV_Length(name(), nonce.size());
160
0
   }
161
0
}
162
163
/*
164
* Default (deterministic) MAC verification operation
165
*/
166
0
bool MessageAuthenticationCode::verify_mac_result(std::span<const uint8_t> mac) {
167
0
   secure_vector<uint8_t> our_mac = final();
168
169
0
   if(our_mac.size() != mac.size()) {
170
0
      return false;
171
0
   }
172
173
0
   return CT::is_equal(our_mac.data(), mac.data(), mac.size()).as_bool();
174
0
}
175
176
}  // namespace Botan