Coverage Report

Created: 2025-03-09 06:52

/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
10
#include <botan/assert.h>
11
#include <botan/exceptn.h>
12
#include <botan/hash.h>
13
#include <botan/mac.h>
14
#include <botan/internal/fmt.h>
15
#include <botan/internal/scan_name.h>
16
17
#if defined(BOTAN_HAS_HKDF)
18
   #include <botan/internal/hkdf.h>
19
#endif
20
21
#if defined(BOTAN_HAS_KDF1)
22
   #include <botan/internal/kdf1.h>
23
#endif
24
25
#if defined(BOTAN_HAS_KDF2)
26
   #include <botan/internal/kdf2.h>
27
#endif
28
29
#if defined(BOTAN_HAS_KDF1_18033)
30
   #include <botan/internal/kdf1_iso18033.h>
31
#endif
32
33
#if defined(BOTAN_HAS_TLS_V12_PRF)
34
   #include <botan/internal/prf_tls.h>
35
#endif
36
37
#if defined(BOTAN_HAS_X942_PRF)
38
   #include <botan/internal/prf_x942.h>
39
#endif
40
41
#if defined(BOTAN_HAS_SP800_108)
42
   #include <botan/internal/sp800_108.h>
43
#endif
44
45
#if defined(BOTAN_HAS_SP800_56A)
46
   #include <botan/internal/sp800_56c_one_step.h>
47
#endif
48
49
#if defined(BOTAN_HAS_SP800_56C)
50
   #include <botan/internal/sp800_56c_two_step.h>
51
#endif
52
53
namespace Botan {
54
55
namespace {
56
57
template <typename KDF_Type, typename... ParamTs>
58
604
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
604
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
365
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
365
   }
62
63
239
   if(auto mac = MessageAuthenticationCode::create(nm)) {
64
233
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
65
233
   }
66
67
6
   return nullptr;
68
239
}
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_view<char, std::__1::char_traits<char> >)
Line
Count
Source
58
368
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
368
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
365
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
365
   }
62
63
3
   if(auto mac = MessageAuthenticationCode::create(nm)) {
64
0
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
65
0
   }
66
67
3
   return nullptr;
68
3
}
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_view<char, std::__1::char_traits<char> >)
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_view<char, std::__1::char_traits<char> >)
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::TLS_12_PRF>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
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, unsigned long, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned long&&, unsigned long&&)
Line
Count
Source
58
116
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
116
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
0
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
0
   }
62
63
116
   if(auto mac = MessageAuthenticationCode::create(nm)) {
64
115
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
65
115
   }
66
67
1
   return nullptr;
68
116
}
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, unsigned long, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned long&&, unsigned long&&)
Line
Count
Source
58
68
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
68
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
0
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
0
   }
62
63
68
   if(auto mac = MessageAuthenticationCode::create(nm)) {
64
67
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
65
67
   }
66
67
1
   return nullptr;
68
68
}
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, unsigned long, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned long&&, unsigned long&&)
Line
Count
Source
58
52
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
52
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
0
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
0
   }
62
63
52
   if(auto mac = MessageAuthenticationCode::create(nm)) {
64
51
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
65
51
   }
66
67
1
   return nullptr;
68
52
}
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, int, int>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, int&&, int&&)
69
70
}  // namespace
71
72
606
std::unique_ptr<KDF> KDF::create(std::string_view algo_spec, std::string_view provider) {
73
606
   const SCAN_Name req(algo_spec);
74
75
606
#if defined(BOTAN_HAS_HKDF)
76
606
   if(req.algo_name() == "HKDF" && req.arg_count() == 1) {
77
368
      if(provider.empty() || provider == "base") {
78
368
         return kdf_create_mac_or_hash<HKDF>(req.arg(0));
79
368
      }
80
368
   }
81
82
238
   if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1) {
83
0
      if(provider.empty() || provider == "base") {
84
0
         return kdf_create_mac_or_hash<HKDF_Extract>(req.arg(0));
85
0
      }
86
0
   }
87
88
238
   if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1) {
89
0
      if(provider.empty() || provider == "base") {
90
0
         return kdf_create_mac_or_hash<HKDF_Expand>(req.arg(0));
91
0
      }
92
0
   }
93
238
#endif
94
95
238
#if defined(BOTAN_HAS_KDF2)
96
238
   if(req.algo_name() == "KDF2" && req.arg_count() == 1) {
97
0
      if(provider.empty() || provider == "base") {
98
0
         if(auto hash = HashFunction::create(req.arg(0))) {
99
0
            return std::make_unique<KDF2>(std::move(hash));
100
0
         }
101
0
      }
102
0
   }
103
238
#endif
104
105
238
#if defined(BOTAN_HAS_KDF1_18033)
106
238
   if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1) {
107
0
      if(provider.empty() || provider == "base") {
108
0
         if(auto hash = HashFunction::create(req.arg(0))) {
109
0
            return std::make_unique<KDF1_18033>(std::move(hash));
110
0
         }
111
0
      }
112
0
   }
113
238
#endif
114
115
238
#if defined(BOTAN_HAS_KDF1)
116
238
   if(req.algo_name() == "KDF1" && req.arg_count() == 1) {
117
0
      if(provider.empty() || provider == "base") {
118
0
         if(auto hash = HashFunction::create(req.arg(0))) {
119
0
            return std::make_unique<KDF1>(std::move(hash));
120
0
         }
121
0
      }
122
0
   }
123
238
#endif
124
125
238
#if defined(BOTAN_HAS_TLS_V12_PRF)
126
238
   if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1) {
127
0
      if(provider.empty() || provider == "base") {
128
0
         return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
129
0
      }
130
0
   }
131
238
#endif
132
133
238
#if defined(BOTAN_HAS_X942_PRF)
134
238
   if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1) {
135
0
      if(provider.empty() || provider == "base") {
136
0
         return std::make_unique<X942_PRF>(req.arg(0));
137
0
      }
138
0
   }
139
238
#endif
140
141
238
#if defined(BOTAN_HAS_SP800_108)
142
238
   if(req.algo_name() == "SP800-108-Counter" && req.arg_count_between(1, 3)) {
143
116
      if(provider.empty() || provider == "base") {
144
116
         return kdf_create_mac_or_hash<SP800_108_Counter>(
145
116
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
146
116
      }
147
116
   }
148
149
122
   if(req.algo_name() == "SP800-108-Feedback" && req.arg_count_between(1, 3)) {
150
68
      if(provider.empty() || provider == "base") {
151
68
         return kdf_create_mac_or_hash<SP800_108_Feedback>(
152
68
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
153
68
      }
154
68
   }
155
156
54
   if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count_between(1, 3)) {
157
52
      if(provider.empty() || provider == "base") {
158
52
         return kdf_create_mac_or_hash<SP800_108_Pipeline>(
159
52
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
160
52
      }
161
52
   }
162
2
#endif
163
164
2
#if defined(BOTAN_HAS_SP800_56A)
165
2
   if(req.algo_name() == "SP800-56A" && req.arg_count() == 1) {
166
0
      if(auto hash = HashFunction::create(req.arg(0))) {
167
0
         return std::make_unique<SP800_56C_One_Step_Hash>(std::move(hash));
168
0
      }
169
0
      if(req.arg(0) == "KMAC-128") {
170
0
         return std::make_unique<SP800_56C_One_Step_KMAC128>();
171
0
      }
172
0
      if(req.arg(0) == "KMAC-256") {
173
0
         return std::make_unique<SP800_56C_One_Step_KMAC256>();
174
0
      }
175
0
      if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
176
0
         return std::make_unique<SP800_56C_One_Step_HMAC>(std::move(mac));
177
0
      }
178
0
   }
179
2
#endif
180
181
2
#if defined(BOTAN_HAS_SP800_56C)
182
2
   if(req.algo_name() == "SP800-56C" && req.arg_count() == 1) {
183
0
      std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0), 32, 32));
184
0
      if(exp) {
185
0
         if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
186
0
            return std::make_unique<SP800_56C_Two_Step>(std::move(mac), std::move(exp));
187
0
         }
188
189
0
         if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", req.arg(0)))) {
190
0
            return std::make_unique<SP800_56C_Two_Step>(std::move(mac), std::move(exp));
191
0
         }
192
0
      }
193
0
   }
194
2
#endif
195
196
2
   BOTAN_UNUSED(req);
197
2
   BOTAN_UNUSED(provider);
198
199
2
   return nullptr;
200
2
}
201
202
//static
203
0
std::unique_ptr<KDF> KDF::create_or_throw(std::string_view algo, std::string_view provider) {
204
0
   if(auto kdf = KDF::create(algo, provider)) {
205
0
      return kdf;
206
0
   }
207
0
   throw Lookup_Error("KDF", algo, provider);
208
0
}
209
210
0
std::vector<std::string> KDF::providers(std::string_view algo_spec) {
211
0
   return probe_providers_of<KDF>(algo_spec);
212
0
}
213
214
}  // namespace Botan