• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 16293079084

15 Jul 2025 12:20PM UTC coverage: 90.627% (+0.003%) from 90.624%
16293079084

push

github

web-flow
Merge pull request #4990 from randombit/jack/string-and-span

Improve string<->span conversions

99640 of 109945 relevant lines covered (90.63%)

12253617.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.48
/src/lib/kdf/kdf.cpp
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/mem_utils.h>
16
#include <botan/internal/scan_name.h>
17

18
#if defined(BOTAN_HAS_HKDF)
19
   #include <botan/internal/hkdf.h>
20
#endif
21

22
#if defined(BOTAN_HAS_KDF1)
23
   #include <botan/internal/kdf1.h>
24
#endif
25

26
#if defined(BOTAN_HAS_KDF2)
27
   #include <botan/internal/kdf2.h>
28
#endif
29

30
#if defined(BOTAN_HAS_KDF1_18033)
31
   #include <botan/internal/kdf1_iso18033.h>
32
#endif
33

34
#if defined(BOTAN_HAS_TLS_V12_PRF)
35
   #include <botan/internal/prf_tls.h>
36
#endif
37

38
#if defined(BOTAN_HAS_X942_PRF)
39
   #include <botan/internal/prf_x942.h>
40
#endif
41

42
#if defined(BOTAN_HAS_SP800_108)
43
   #include <botan/internal/sp800_108.h>
44
#endif
45

46
#if defined(BOTAN_HAS_SP800_56A)
47
   #include <botan/internal/sp800_56c_one_step.h>
48
#endif
49

50
#if defined(BOTAN_HAS_SP800_56C)
51
   #include <botan/internal/sp800_56c_two_step.h>
52
#endif
53

54
namespace Botan {
55

56
namespace {
57

58
template <typename KDF_Type, typename... ParamTs>
59
std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm, ParamTs&&... params) {
6,922✔
60
   if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
19,788✔
61
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
5,944✔
62
   }
63

64
   if(auto mac = MessageAuthenticationCode::create(nm)) {
1,956✔
65
      return std::make_unique<KDF_Type>(std::move(mac), std::forward<ParamTs>(params)...);
978✔
66
   }
67

68
   return nullptr;
×
69
}
70

71
}  // namespace
72

73
std::unique_ptr<KDF> KDF::create(std::string_view algo_spec, std::string_view provider) {
8,093✔
74
   const SCAN_Name req(algo_spec);
8,093✔
75

76
#if defined(BOTAN_HAS_HKDF)
77
   if(req.algo_name() == "HKDF" && req.arg_count() == 1) {
8,093✔
78
      if(provider.empty() || provider == "base") {
13✔
79
         return kdf_create_mac_or_hash<HKDF>(req.arg(0));
26✔
80
      }
81
   }
82

83
   if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1) {
8,080✔
84
      if(provider.empty() || provider == "base") {
12✔
85
         return kdf_create_mac_or_hash<HKDF_Extract>(req.arg(0));
24✔
86
      }
87
   }
88

89
   if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1) {
8,068✔
90
      if(provider.empty() || provider == "base") {
12✔
91
         return kdf_create_mac_or_hash<HKDF_Expand>(req.arg(0));
24✔
92
      }
93
   }
94
#endif
95

96
#if defined(BOTAN_HAS_KDF2)
97
   if(req.algo_name() == "KDF2" && req.arg_count() == 1) {
8,056✔
98
      if(provider.empty() || provider == "base") {
529✔
99
         if(auto hash = HashFunction::create(req.arg(0))) {
1,058✔
100
            return std::make_unique<KDF2>(std::move(hash));
529✔
101
         }
529✔
102
      }
103
   }
104
#endif
105

106
#if defined(BOTAN_HAS_KDF1_18033)
107
   if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1) {
7,527✔
108
      if(provider.empty() || provider == "base") {
69✔
109
         if(auto hash = HashFunction::create(req.arg(0))) {
138✔
110
            return std::make_unique<KDF1_18033>(std::move(hash));
69✔
111
         }
69✔
112
      }
113
   }
114
#endif
115

116
#if defined(BOTAN_HAS_KDF1)
117
   if(req.algo_name() == "KDF1" && req.arg_count() == 1) {
7,458✔
118
      if(provider.empty() || provider == "base") {
18✔
119
         if(auto hash = HashFunction::create(req.arg(0))) {
36✔
120
            return std::make_unique<KDF1>(std::move(hash));
18✔
121
         }
18✔
122
      }
123
   }
124
#endif
125

126
#if defined(BOTAN_HAS_TLS_V12_PRF)
127
   if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1) {
7,440✔
128
      if(provider.empty() || provider == "base") {
5,948✔
129
         return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
11,896✔
130
      }
131
   }
132
#endif
133

134
#if defined(BOTAN_HAS_X942_PRF)
135
   if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1) {
1,492✔
136
      if(provider.empty() || provider == "base") {
2✔
137
         return std::make_unique<X942_PRF>(req.arg(0));
2✔
138
      }
139
   }
140
#endif
141

142
#if defined(BOTAN_HAS_SP800_108)
143
   if(req.algo_name() == "SP800-108-Counter" && req.arg_count_between(1, 3)) {
1,490✔
144
      if(provider.empty() || provider == "base") {
299✔
145
         return kdf_create_mac_or_hash<SP800_108_Counter>(
299✔
146
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
598✔
147
      }
148
   }
149

150
   if(req.algo_name() == "SP800-108-Feedback" && req.arg_count_between(1, 3)) {
1,191✔
151
      if(provider.empty() || provider == "base") {
299✔
152
         return kdf_create_mac_or_hash<SP800_108_Feedback>(
299✔
153
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
598✔
154
      }
155
   }
156

157
   if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count_between(1, 3)) {
892✔
158
      if(provider.empty() || provider == "base") {
299✔
159
         return kdf_create_mac_or_hash<SP800_108_Pipeline>(
299✔
160
            req.arg(0), req.arg_as_integer(1, 32), req.arg_as_integer(2, 32));
598✔
161
      }
162
   }
163
#endif
164

165
#if defined(BOTAN_HAS_SP800_56A)
166
   if(req.algo_name() == "SP800-56A" && req.arg_count() == 1) {
593✔
167
      if(auto hash = HashFunction::create(req.arg(0))) {
1,042✔
168
         return std::make_unique<SP800_56C_One_Step_Hash>(std::move(hash));
244✔
169
      }
244✔
170
      if(req.arg(0) == "KMAC-128") {
277✔
171
         return std::make_unique<SP800_56C_One_Step_KMAC128>();
9✔
172
      }
173
      if(req.arg(0) == "KMAC-256") {
268✔
174
         return std::make_unique<SP800_56C_One_Step_KMAC256>();
×
175
      }
176
      if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
536✔
177
         return std::make_unique<SP800_56C_One_Step_HMAC>(std::move(mac));
268✔
178
      }
268✔
179
   }
180
#endif
181

182
#if defined(BOTAN_HAS_SP800_56C)
183
   if(req.algo_name() == "SP800-56C" && req.arg_count() == 1) {
72✔
184
      std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0), 32, 32));
40✔
185
      if(exp) {
40✔
186
         if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
80✔
187
            return std::make_unique<SP800_56C_Two_Step>(std::move(mac), std::move(exp));
40✔
188
         }
40✔
189

190
         if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", req.arg(0)))) {
×
191
            return std::make_unique<SP800_56C_Two_Step>(std::move(mac), std::move(exp));
×
192
         }
×
193
      }
194
   }
40✔
195
#endif
196

197
   BOTAN_UNUSED(req);
32✔
198
   BOTAN_UNUSED(provider);
32✔
199

200
   return nullptr;
32✔
201
}
8,093✔
202

203
//static
204
std::unique_ptr<KDF> KDF::create_or_throw(std::string_view algo, std::string_view provider) {
6,396✔
205
   if(auto kdf = KDF::create(algo, provider)) {
6,396✔
206
      return kdf;
6,396✔
207
   }
6,396✔
208
   throw Lookup_Error("KDF", algo, provider);
×
209
}
210

211
std::vector<std::string> KDF::providers(std::string_view algo_spec) {
×
212
   return probe_providers_of<KDF>(algo_spec);
×
213
}
214

215
//static
216
std::span<const uint8_t> KDF::_as_span(std::string_view s) {
3,840✔
217
   return as_span_of_bytes(s);
3,840✔
218
}
219

220
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc