Coverage Report

Created: 2020-11-21 08:34

/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/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_V10_PRF) || 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
17.6k
   {
58
17.6k
   if(auto mac = MessageAuthenticationCode::create(nm))
59
0
      return std::unique_ptr<KDF>(new KDF_Type(mac.release()));
60
61
17.6k
   if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")"))
62
17.6k
      return std::unique_ptr<KDF>(new KDF_Type(mac.release()));
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
17.6k
   {
58
17.6k
   if(auto mac = MessageAuthenticationCode::create(nm))
59
0
      return std::unique_ptr<KDF>(new KDF_Type(mac.release()));
60
61
17.6k
   if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")"))
62
17.6k
      return std::unique_ptr<KDF>(new KDF_Type(mac.release()));
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
17.6k
   {
72
17.6k
   const SCAN_Name req(algo_spec);
73
74
17.6k
#if defined(BOTAN_HAS_HKDF)
75
17.6k
   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
17.6k
      }
82
83
17.6k
   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
17.6k
      }
90
91
17.6k
   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
17.6k
      }
98
17.6k
#endif
99
100
17.6k
#if defined(BOTAN_HAS_KDF2)
101
17.6k
   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::unique_ptr<KDF>(new KDF2(hash.release()));
107
17.6k
         }
108
0
      }
109
17.6k
#endif
110
111
17.6k
#if defined(BOTAN_HAS_KDF1_18033)
112
17.6k
   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::unique_ptr<KDF>(new KDF1_18033(hash.release()));
118
17.6k
         }
119
0
      }
120
17.6k
#endif
121
122
17.6k
#if defined(BOTAN_HAS_KDF1)
123
17.6k
   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::unique_ptr<KDF>(new KDF1(hash.release()));
129
17.6k
         }
130
0
      }
131
17.6k
#endif
132
133
17.6k
#if defined(BOTAN_HAS_TLS_V10_PRF)
134
17.6k
   if(req.algo_name() == "TLS-PRF" && req.arg_count() == 0)
135
0
      {
136
0
      if(provider.empty() || provider == "base")
137
0
         {
138
0
         auto hmac_md5 = MessageAuthenticationCode::create("HMAC(MD5)");
139
0
         auto hmac_sha1 = MessageAuthenticationCode::create("HMAC(SHA-1)");
140
141
0
         if(hmac_md5 && hmac_sha1)
142
0
            return std::unique_ptr<KDF>(new TLS_PRF(std::move(hmac_md5), std::move(hmac_sha1)));
143
17.6k
         }
144
0
      }
145
17.6k
#endif
146
147
17.6k
#if defined(BOTAN_HAS_TLS_V12_PRF)
148
17.6k
   if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1)
149
17.6k
      {
150
17.6k
      if(provider.empty() || provider == "base")
151
17.6k
         {
152
17.6k
         return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
153
17.6k
         }
154
0
      }
155
0
#endif
156
157
0
#if defined(BOTAN_HAS_X942_PRF)
158
0
   if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1)
159
0
      {
160
0
      if(provider.empty() || provider == "base")
161
0
         {
162
0
         return std::unique_ptr<KDF>(new X942_PRF(req.arg(0)));
163
0
         }
164
0
      }
165
0
#endif
166
167
0
#if defined(BOTAN_HAS_SP800_108)
168
0
   if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1)
169
0
      {
170
0
      if(provider.empty() || provider == "base")
171
0
         {
172
0
         return kdf_create_mac_or_hash<SP800_108_Counter>(req.arg(0));
173
0
         }
174
0
      }
175
176
0
   if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1)
177
0
      {
178
0
      if(provider.empty() || provider == "base")
179
0
         {
180
0
         return kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0));
181
0
         }
182
0
      }
183
184
0
   if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1)
185
0
      {
186
0
      if(provider.empty() || provider == "base")
187
0
         {
188
0
         return kdf_create_mac_or_hash<SP800_108_Pipeline>(req.arg(0));
189
0
         }
190
0
      }
191
0
#endif
192
193
0
#if defined(BOTAN_HAS_SP800_56A)
194
0
   if(req.algo_name() == "SP800-56A" && req.arg_count() == 1)
195
0
      {
196
0
      if(auto hash = HashFunction::create(req.arg(0)))
197
0
         return std::unique_ptr<KDF>(new SP800_56A_Hash(hash.release()));
198
0
      if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
199
0
         return std::unique_ptr<KDF>(new SP800_56A_HMAC(mac.release()));
200
0
      }
201
0
#endif
202
203
0
#if defined(BOTAN_HAS_SP800_56C)
204
0
   if(req.algo_name() == "SP800-56C" && req.arg_count() == 1)
205
0
      {
206
0
      std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0)));
207
0
      if(exp)
208
0
         {
209
0
         if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
210
0
            return std::unique_ptr<KDF>(new SP800_56C(mac.release(), exp.release()));
211
212
0
         if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
213
0
            return std::unique_ptr<KDF>(new SP800_56C(mac.release(), exp.release()));
214
0
         }
215
0
      }
216
0
#endif
217
218
0
   BOTAN_UNUSED(req);
219
0
   BOTAN_UNUSED(provider);
220
221
0
   return nullptr;
222
0
   }
223
224
//static
225
std::unique_ptr<KDF>
226
KDF::create_or_throw(const std::string& algo,
227
                             const std::string& provider)
228
0
   {
229
0
   if(auto kdf = KDF::create(algo, provider))
230
0
      {
231
0
      return kdf;
232
0
      }
233
0
   throw Lookup_Error("KDF", algo, provider);
234
0
   }
235
236
std::vector<std::string> KDF::providers(const std::string& algo_spec)
237
0
   {
238
0
   return probe_providers_of<KDF>(algo_spec, { "base" });
239
0
   }
240
241
KDF* get_kdf(const std::string& algo_spec)
242
17.6k
   {
243
17.6k
   SCAN_Name request(algo_spec);
244
245
17.6k
   if(request.algo_name() == "Raw")
246
0
      return nullptr; // No KDF
247
248
   //return KDF::create_or_throw(algo_spec).release();
249
17.6k
   auto kdf = KDF::create(algo_spec);
250
17.6k
   if(!kdf)
251
0
      throw Algorithm_Not_Found(algo_spec);
252
17.6k
   return kdf.release();
253
17.6k
   }
254
255
}