Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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