Coverage Report

Created: 2025-07-11 06:15

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