Coverage Report

Created: 2020-03-26 13:53

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