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