Coverage Report

Created: 2025-04-11 06: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
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
5.97k
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
5.97k
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
5.97k
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
5.97k
   }
62
63
0
   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
0
   return nullptr;
68
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_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_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> >)
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> >)
Line
Count
Source
58
5.97k
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
59
5.97k
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
60
5.97k
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
61
5.97k
   }
62
63
0
   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
0
   return nullptr;
68
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, unsigned long, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned long&&, unsigned long&&)
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, unsigned long, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned long&&, unsigned long&&)
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, unsigned long, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned long&&, unsigned long&&)
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
5.97k
std::unique_ptr<KDF> KDF::create(std::string_view algo_spec, std::string_view provider) {
73
5.97k
   const SCAN_Name req(algo_spec);
74
75
5.97k
#if defined(BOTAN_HAS_HKDF)
76
5.97k
   if(req.algo_name() == "HKDF" && req.arg_count() == 1) {
77
0
      if(provider.empty() || provider == "base") {
78
0
         return kdf_create_mac_or_hash<HKDF>(req.arg(0));
79
0
      }
80
0
   }
81
82
5.97k
   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
5.97k
   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
5.97k
#endif
94
95
5.97k
#if defined(BOTAN_HAS_KDF2)
96
5.97k
   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
5.97k
#endif
104
105
5.97k
#if defined(BOTAN_HAS_KDF1_18033)
106
5.97k
   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
5.97k
#endif
114
115
5.97k
#if defined(BOTAN_HAS_KDF1)
116
5.97k
   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
5.97k
#endif
124
125
5.97k
#if defined(BOTAN_HAS_TLS_V12_PRF)
126
5.97k
   if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1) {
127
5.97k
      if(provider.empty() || provider == "base") {
128
5.97k
         return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
129
5.97k
      }
130
5.97k
   }
131
0
#endif
132
133
0
#if defined(BOTAN_HAS_X942_PRF)
134
0
   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
0
#endif
140
141
0
#if defined(BOTAN_HAS_SP800_108)
142
0
   if(req.algo_name() == "SP800-108-Counter" && req.arg_count_between(1, 3)) {
143
0
      if(provider.empty() || provider == "base") {
144
0
         return kdf_create_mac_or_hash<SP800_108_Counter>(
145
0
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
146
0
      }
147
0
   }
148
149
0
   if(req.algo_name() == "SP800-108-Feedback" && req.arg_count_between(1, 3)) {
150
0
      if(provider.empty() || provider == "base") {
151
0
         return kdf_create_mac_or_hash<SP800_108_Feedback>(
152
0
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
153
0
      }
154
0
   }
155
156
0
   if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count_between(1, 3)) {
157
0
      if(provider.empty() || provider == "base") {
158
0
         return kdf_create_mac_or_hash<SP800_108_Pipeline>(
159
0
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
160
0
      }
161
0
   }
162
0
#endif
163
164
0
#if defined(BOTAN_HAS_SP800_56A)
165
0
   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
0
#endif
180
181
0
#if defined(BOTAN_HAS_SP800_56C)
182
0
   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
0
#endif
195
196
0
   BOTAN_UNUSED(req);
197
0
   BOTAN_UNUSED(provider);
198
199
0
   return nullptr;
200
0
}
201
202
//static
203
5.97k
std::unique_ptr<KDF> KDF::create_or_throw(std::string_view algo, std::string_view provider) {
204
5.97k
   if(auto kdf = KDF::create(algo, provider)) {
205
5.97k
      return kdf;
206
5.97k
   }
207
0
   throw Lookup_Error("KDF", algo, provider);
208
5.97k
}
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