Coverage Report

Created: 2021-04-07 06:07

/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
19.1k
   {
49
19.1k
   const SCAN_Name req(algo_spec);
50
51
19.1k
#if defined(BOTAN_HAS_BLAKE2BMAC)
52
19.1k
   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
19.1k
#endif
57
58
19.1k
#if defined(BOTAN_HAS_GMAC)
59
19.1k
   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
19.1k
         }
66
0
      }
67
19.1k
#endif
68
69
19.1k
#if defined(BOTAN_HAS_HMAC)
70
19.1k
   if(req.algo_name() == "HMAC" && req.arg_count() == 1)
71
19.1k
      {
72
      // TODO OpenSSL
73
19.1k
      if(provider.empty() || provider == "base")
74
19.1k
         {
75
19.1k
         if(auto hash = HashFunction::create(req.arg(0)))
76
19.1k
            return std::make_unique<HMAC>(std::move(hash));
77
34
         }
78
19.1k
      }
79
34
#endif
80
81
34
#if defined(BOTAN_HAS_POLY1305)
82
34
   if(req.algo_name() == "Poly1305" && req.arg_count() == 0)
83
34
      {
84
34
      if(provider.empty() || provider == "base")
85
34
         return std::make_unique<Poly1305>();
86
0
      }
87
0
#endif
88
89
0
#if defined(BOTAN_HAS_SIPHASH)
90
0
   if(req.algo_name() == "SipHash")
91
0
      {
92
0
      if(provider.empty() || provider == "base")
93
0
         {
94
0
         return std::make_unique<SipHash>(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4));
95
0
         }
96
0
      }
97
0
#endif
98
99
0
#if defined(BOTAN_HAS_CMAC)
100
0
   if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1)
101
0
      {
102
      // TODO: OpenSSL CMAC
103
0
      if(provider.empty() || provider == "base")
104
0
         {
105
0
         if(auto bc = BlockCipher::create(req.arg(0)))
106
0
            return std::make_unique<CMAC>(std::move(bc));
107
0
         }
108
0
      }
109
0
#endif
110
111
112
0
#if defined(BOTAN_HAS_ANSI_X919_MAC)
113
0
   if(req.algo_name() == "X9.19-MAC")
114
0
      {
115
0
      if(provider.empty() || provider == "base")
116
0
         {
117
0
         return std::make_unique<ANSI_X919_MAC>();
118
0
         }
119
0
      }
120
0
#endif
121
122
0
   BOTAN_UNUSED(req);
123
0
   BOTAN_UNUSED(provider);
124
125
0
   return nullptr;
126
0
   }
127
128
std::vector<std::string>
129
MessageAuthenticationCode::providers(const std::string& algo_spec)
130
0
   {
131
0
   return probe_providers_of<MessageAuthenticationCode>(algo_spec, {"base", "openssl"});
132
0
   }
133
134
//static
135
std::unique_ptr<MessageAuthenticationCode>
136
MessageAuthenticationCode::create_or_throw(const std::string& algo,
137
                                           const std::string& provider)
138
8.15k
   {
139
8.15k
   if(auto mac = MessageAuthenticationCode::create(algo, provider))
140
8.15k
      {
141
8.15k
      return mac;
142
8.15k
      }
143
0
   throw Lookup_Error("MAC", algo, provider);
144
0
   }
145
146
void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len)
147
0
   {
148
0
   BOTAN_UNUSED(nonce);
149
0
   if(nonce_len > 0)
150
0
      throw Invalid_IV_Length(name(), nonce_len);
151
0
   }
152
153
/*
154
* Default (deterministic) MAC verification operation
155
*/
156
bool MessageAuthenticationCode::verify_mac(const uint8_t mac[], size_t length)
157
0
   {
158
0
   secure_vector<uint8_t> our_mac = final();
159
160
0
   if(our_mac.size() != length)
161
0
      return false;
162
163
0
   return constant_time_compare(our_mac.data(), mac, length);
164
0
   }
165
166
}