Coverage Report

Created: 2023-02-13 06:21

/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
#include <botan/exceptn.h>
10
#include <botan/internal/scan_name.h>
11
#include <botan/mem_ops.h>
12
13
#if defined(BOTAN_HAS_CMAC)
14
  #include <botan/internal/cmac.h>
15
#endif
16
17
#if defined(BOTAN_HAS_GMAC)
18
  #include <botan/internal/gmac.h>
19
  #include <botan/block_cipher.h>
20
#endif
21
22
#if defined(BOTAN_HAS_HMAC)
23
  #include <botan/internal/hmac.h>
24
  #include <botan/hash.h>
25
#endif
26
27
#if defined(BOTAN_HAS_POLY1305)
28
  #include <botan/internal/poly1305.h>
29
#endif
30
31
#if defined(BOTAN_HAS_SIPHASH)
32
  #include <botan/internal/siphash.h>
33
#endif
34
35
#if defined(BOTAN_HAS_ANSI_X919_MAC)
36
  #include <botan/internal/x919_mac.h>
37
#endif
38
39
#if defined(BOTAN_HAS_BLAKE2BMAC)
40
  #include <botan/internal/blake2bmac.h>
41
#endif
42
43
namespace Botan {
44
45
std::unique_ptr<MessageAuthenticationCode>
46
MessageAuthenticationCode::create(const std::string& algo_spec,
47
                                  const std::string& provider)
48
16.9k
   {
49
16.9k
   const SCAN_Name req(algo_spec);
50
51
16.9k
#if defined(BOTAN_HAS_BLAKE2BMAC)
52
16.9k
   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
53
0
      {
54
0
      return std::make_unique<BLAKE2bMAC>(req.arg_as_integer(0, 512));
55
0
      }
56
16.9k
#endif
57
58
16.9k
#if defined(BOTAN_HAS_GMAC)
59
16.9k
   if(req.algo_name() == "GMAC" && req.arg_count() == 1)
60
0
      {
61
0
      if(provider.empty() || provider == "base")
62
0
         {
63
0
         if(auto bc = BlockCipher::create(req.arg(0)))
64
0
            return std::make_unique<GMAC>(std::move(bc));
65
0
         }
66
0
      }
67
16.9k
#endif
68
69
16.9k
#if defined(BOTAN_HAS_HMAC)
70
16.9k
   if(req.algo_name() == "HMAC" && req.arg_count() == 1)
71
16.8k
      {
72
16.8k
      if(provider.empty() || provider == "base")
73
16.8k
         {
74
16.8k
         if(auto hash = HashFunction::create(req.arg(0)))
75
16.8k
            return std::make_unique<HMAC>(std::move(hash));
76
16.8k
         }
77
16.8k
      }
78
124
#endif
79
80
124
#if defined(BOTAN_HAS_POLY1305)
81
124
   if(req.algo_name() == "Poly1305" && req.arg_count() == 0)
82
124
      {
83
124
      if(provider.empty() || provider == "base")
84
124
         return std::make_unique<Poly1305>();
85
124
      }
86
0
#endif
87
88
0
#if defined(BOTAN_HAS_SIPHASH)
89
0
   if(req.algo_name() == "SipHash")
90
0
      {
91
0
      if(provider.empty() || provider == "base")
92
0
         {
93
0
         return std::make_unique<SipHash>(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4));
94
0
         }
95
0
      }
96
0
#endif
97
98
0
#if defined(BOTAN_HAS_CMAC)
99
0
   if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1)
100
0
      {
101
0
      if(provider.empty() || provider == "base")
102
0
         {
103
0
         if(auto bc = BlockCipher::create(req.arg(0)))
104
0
            return std::make_unique<CMAC>(std::move(bc));
105
0
         }
106
0
      }
107
0
#endif
108
109
110
0
#if defined(BOTAN_HAS_ANSI_X919_MAC)
111
0
   if(req.algo_name() == "X9.19-MAC")
112
0
      {
113
0
      if(provider.empty() || provider == "base")
114
0
         {
115
0
         return std::make_unique<ANSI_X919_MAC>();
116
0
         }
117
0
      }
118
0
#endif
119
120
0
   BOTAN_UNUSED(req);
121
0
   BOTAN_UNUSED(provider);
122
123
0
   return nullptr;
124
0
   }
125
126
std::vector<std::string>
127
MessageAuthenticationCode::providers(const std::string& algo_spec)
128
0
   {
129
0
   return probe_providers_of<MessageAuthenticationCode>(algo_spec);
130
0
   }
131
132
//static
133
std::unique_ptr<MessageAuthenticationCode>
134
MessageAuthenticationCode::create_or_throw(const std::string& algo,
135
                                           const std::string& provider)
136
2.65k
   {
137
2.65k
   if(auto mac = MessageAuthenticationCode::create(algo, provider))
138
2.65k
      {
139
2.65k
      return mac;
140
2.65k
      }
141
0
   throw Lookup_Error("MAC", algo, provider);
142
2.65k
   }
143
144
void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len)
145
0
   {
146
0
   BOTAN_UNUSED(nonce);
147
0
   if(nonce_len > 0)
148
0
      throw Invalid_IV_Length(name(), nonce_len);
149
0
   }
150
151
/*
152
* Default (deterministic) MAC verification operation
153
*/
154
bool MessageAuthenticationCode::verify_mac(const uint8_t mac[], size_t length)
155
0
   {
156
0
   secure_vector<uint8_t> our_mac = final();
157
158
0
   if(our_mac.size() != length)
159
0
      return false;
160
161
0
   return constant_time_compare(our_mac.data(), mac, length);
162
0
   }
163
164
}