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