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

randombit / botan / 12827477116

17 Jan 2025 10:41AM UTC coverage: 91.206% (+0.008%) from 91.198%
12827477116

push

github

web-flow
Merge pull request #4551 from Rohde-Schwarz/feature/flexible_sp800_kdf

SP.800-108 may handle different counter and L encoding widths

93405 of 102411 relevant lines covered (91.21%)

11455192.7 hits per line

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

90.24
/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/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_56c_one_step.h>
46
#endif
47

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

52
namespace Botan {
53

54
namespace {
55

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

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

66
   return nullptr;
×
67
}
68

69
}  // namespace
70

71
std::unique_ptr<KDF> KDF::create(std::string_view algo_spec, std::string_view provider) {
8,010✔
72
   const SCAN_Name req(algo_spec);
8,010✔
73

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

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

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

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

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

114
#if defined(BOTAN_HAS_KDF1)
115
   if(req.algo_name() == "KDF1" && req.arg_count() == 1) {
7,372✔
116
      if(provider.empty() || provider == "base") {
18✔
117
         if(auto hash = HashFunction::create(req.arg(0))) {
36✔
118
            return std::make_unique<KDF1>(std::move(hash));
18✔
119
         }
18✔
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) {
7,354✔
126
      if(provider.empty() || provider == "base") {
5,862✔
127
         return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
11,724✔
128
      }
129
   }
130
#endif
131

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

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

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

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

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

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

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

195
   BOTAN_UNUSED(req);
32✔
196
   BOTAN_UNUSED(provider);
32✔
197

198
   return nullptr;
32✔
199
}
8,010✔
200

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

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

213
}  // 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