Coverage Report

Created: 2021-05-04 09:02

/src/botan/src/lib/kdf/kdf.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* KDF Retrieval
3
* (C) 1999-2007 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/kdf.h>
9
#include <botan/mac.h>
10
#include <botan/hash.h>
11
#include <botan/internal/scan_name.h>
12
#include <botan/exceptn.h>
13
14
#if defined(BOTAN_HAS_HKDF)
15
#include <botan/internal/hkdf.h>
16
#endif
17
18
#if defined(BOTAN_HAS_KDF1)
19
#include <botan/internal/kdf1.h>
20
#endif
21
22
#if defined(BOTAN_HAS_KDF2)
23
#include <botan/internal/kdf2.h>
24
#endif
25
26
#if defined(BOTAN_HAS_KDF1_18033)
27
#include <botan/internal/kdf1_iso18033.h>
28
#endif
29
30
#if defined(BOTAN_HAS_TLS_V12_PRF)
31
#include <botan/internal/prf_tls.h>
32
#endif
33
34
#if defined(BOTAN_HAS_X942_PRF)
35
#include <botan/internal/prf_x942.h>
36
#endif
37
38
#if defined(BOTAN_HAS_SP800_108)
39
#include <botan/internal/sp800_108.h>
40
#endif
41
42
#if defined(BOTAN_HAS_SP800_56A)
43
#include <botan/internal/sp800_56a.h>
44
#endif
45
46
#if defined(BOTAN_HAS_SP800_56C)
47
#include <botan/internal/sp800_56c.h>
48
#endif
49
50
namespace Botan {
51
52
namespace {
53
54
template<typename KDF_Type>
55
std::unique_ptr<KDF>
56
kdf_create_mac_or_hash(const std::string& nm)
57
11.3k
   {
58
11.3k
   if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")"))
59
11.3k
      return std::make_unique<KDF_Type>(std::move(mac));
60
61
0
   if(auto mac = MessageAuthenticationCode::create(nm))
62
0
      return std::make_unique<KDF_Type>(std::move(mac));
63
64
0
   return nullptr;
65
0
   }
Unexecuted instantiation: kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::HKDF>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::HKDF_Extract>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::HKDF_Expand>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::TLS_12_PRF>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
57
11.3k
   {
58
11.3k
   if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")"))
59
11.3k
      return std::make_unique<KDF_Type>(std::move(mac));
60
61
0
   if(auto mac = MessageAuthenticationCode::create(nm))
62
0
      return std::make_unique<KDF_Type>(std::move(mac));
63
64
0
   return nullptr;
65
0
   }
Unexecuted instantiation: kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::SP800_108_Counter>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::SP800_108_Feedback>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: kdf.cpp:std::__1::unique_ptr<Botan::KDF, std::__1::default_delete<Botan::KDF> > Botan::(anonymous namespace)::kdf_create_mac_or_hash<Botan::SP800_108_Pipeline>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
66
67
}
68
69
std::unique_ptr<KDF> KDF::create(const std::string& algo_spec,
70
                                 const std::string& provider)
71
11.3k
   {
72
11.3k
   const SCAN_Name req(algo_spec);
73
74
11.3k
#if defined(BOTAN_HAS_HKDF)
75
11.3k
   if(req.algo_name() == "HKDF" && req.arg_count() == 1)
76
0
      {
77
0
      if(provider.empty() || provider == "base")
78
0
         {
79
0
         return kdf_create_mac_or_hash<HKDF>(req.arg(0));
80
0
         }
81
11.3k
      }
82
83
11.3k
   if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1)
84
0
      {
85
0
      if(provider.empty() || provider == "base")
86
0
         {
87
0
         return kdf_create_mac_or_hash<HKDF_Extract>(req.arg(0));
88
0
         }
89
11.3k
      }
90
91
11.3k
   if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1)
92
0
      {
93
0
      if(provider.empty() || provider == "base")
94
0
         {
95
0
         return kdf_create_mac_or_hash<HKDF_Expand>(req.arg(0));
96
0
         }
97
11.3k
      }
98
11.3k
#endif
99
100
11.3k
#if defined(BOTAN_HAS_KDF2)
101
11.3k
   if(req.algo_name() == "KDF2" && req.arg_count() == 1)
102
0
      {
103
0
      if(provider.empty() || provider == "base")
104
0
         {
105
0
         if(auto hash = HashFunction::create(req.arg(0)))
106
0
            return std::make_unique<KDF2>(std::move(hash));
107
11.3k
         }
108
0
      }
109
11.3k
#endif
110
111
11.3k
#if defined(BOTAN_HAS_KDF1_18033)
112
11.3k
   if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1)
113
0
      {
114
0
      if(provider.empty() || provider == "base")
115
0
         {
116
0
         if(auto hash = HashFunction::create(req.arg(0)))
117
0
            return std::make_unique<KDF1_18033>(std::move(hash));
118
11.3k
         }
119
0
      }
120
11.3k
#endif
121
122
11.3k
#if defined(BOTAN_HAS_KDF1)
123
11.3k
   if(req.algo_name() == "KDF1" && req.arg_count() == 1)
124
0
      {
125
0
      if(provider.empty() || provider == "base")
126
0
         {
127
0
         if(auto hash = HashFunction::create(req.arg(0)))
128
0
            return std::make_unique<KDF1>(std::move(hash));
129
11.3k
         }
130
0
      }
131
11.3k
#endif
132
133
11.3k
#if defined(BOTAN_HAS_TLS_V12_PRF)
134
11.3k
   if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1)
135
11.3k
      {
136
11.3k
      if(provider.empty() || provider == "base")
137
11.3k
         {
138
11.3k
         return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
139
11.3k
         }
140
0
      }
141
0
#endif
142
143
0
#if defined(BOTAN_HAS_X942_PRF)
144
0
   if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1)
145
0
      {
146
0
      if(provider.empty() || provider == "base")
147
0
         {
148
0
         return std::make_unique<X942_PRF>(req.arg(0));
149
0
         }
150
0
      }
151
0
#endif
152
153
0
#if defined(BOTAN_HAS_SP800_108)
154
0
   if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1)
155
0
      {
156
0
      if(provider.empty() || provider == "base")
157
0
         {
158
0
         return kdf_create_mac_or_hash<SP800_108_Counter>(req.arg(0));
159
0
         }
160
0
      }
161
162
0
   if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1)
163
0
      {
164
0
      if(provider.empty() || provider == "base")
165
0
         {
166
0
         return kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0));
167
0
         }
168
0
      }
169
170
0
   if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1)
171
0
      {
172
0
      if(provider.empty() || provider == "base")
173
0
         {
174
0
         return kdf_create_mac_or_hash<SP800_108_Pipeline>(req.arg(0));
175
0
         }
176
0
      }
177
0
#endif
178
179
0
#if defined(BOTAN_HAS_SP800_56A)
180
0
   if(req.algo_name() == "SP800-56A" && req.arg_count() == 1)
181
0
      {
182
0
      if(auto hash = HashFunction::create(req.arg(0)))
183
0
         return std::make_unique<SP800_56A_Hash>(std::move(hash));
184
0
      if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
185
0
         return std::make_unique<SP800_56A_HMAC>(std::move(mac));
186
0
      }
187
0
#endif
188
189
0
#if defined(BOTAN_HAS_SP800_56C)
190
0
   if(req.algo_name() == "SP800-56C" && req.arg_count() == 1)
191
0
      {
192
0
      std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0)));
193
0
      if(exp)
194
0
         {
195
0
         if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
196
0
            return std::make_unique<SP800_56C>(std::move(mac), std::move(exp));
197
198
0
         if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
199
0
            return std::make_unique<SP800_56C>(std::move(mac), std::move(exp));
200
0
         }
201
0
      }
202
0
#endif
203
204
0
   BOTAN_UNUSED(req);
205
0
   BOTAN_UNUSED(provider);
206
207
0
   return nullptr;
208
0
   }
209
210
//static
211
std::unique_ptr<KDF>
212
KDF::create_or_throw(const std::string& algo,
213
                             const std::string& provider)
214
11.3k
   {
215
11.3k
   if(auto kdf = KDF::create(algo, provider))
216
11.3k
      {
217
11.3k
      return kdf;
218
11.3k
      }
219
0
   throw Lookup_Error("KDF", algo, provider);
220
0
   }
221
222
std::vector<std::string> KDF::providers(const std::string& algo_spec)
223
0
   {
224
0
   return probe_providers_of<KDF>(algo_spec, { "base" });
225
0
   }
226
227
}