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