Coverage Report

Created: 2021-02-21 07:20

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