Botan 3.0.0-alpha0
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/exceptn.h>
13
14#if defined(BOTAN_HAS_HKDF)
15#include <botan/internal/hkdf.h>
16#endif
17
18#if defined(BOTAN_HAS_KDF1)
19#include <botan/internal/kdf1.h>
20#endif
21
22#if defined(BOTAN_HAS_KDF2)
23#include <botan/internal/kdf2.h>
24#endif
25
26#if defined(BOTAN_HAS_KDF1_18033)
27#include <botan/internal/kdf1_iso18033.h>
28#endif
29
30#if defined(BOTAN_HAS_TLS_V12_PRF)
31#include <botan/internal/prf_tls.h>
32#endif
33
34#if defined(BOTAN_HAS_X942_PRF)
35#include <botan/internal/prf_x942.h>
36#endif
37
38#if defined(BOTAN_HAS_SP800_108)
39#include <botan/internal/sp800_108.h>
40#endif
41
42#if defined(BOTAN_HAS_SP800_56A)
43#include <botan/internal/sp800_56a.h>
44#endif
45
46#if defined(BOTAN_HAS_SP800_56C)
47#include <botan/internal/sp800_56c.h>
48#endif
49
50namespace Botan {
51
52namespace {
53
54template<typename KDF_Type>
55std::unique_ptr<KDF>
56kdf_create_mac_or_hash(const std::string& nm)
57 {
58 if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")"))
59 return std::make_unique<KDF_Type>(std::move(mac));
60
61 if(auto mac = MessageAuthenticationCode::create(nm))
62 return std::make_unique<KDF_Type>(std::move(mac));
63
64 return nullptr;
65 }
66
67}
68
69std::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::make_unique<KDF2>(std::move(hash));
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::make_unique<KDF1_18033>(std::move(hash));
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::make_unique<KDF1>(std::move(hash));
129 }
130 }
131#endif
132
133#if defined(BOTAN_HAS_TLS_V12_PRF)
134 if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1)
135 {
136 if(provider.empty() || provider == "base")
137 {
138 return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
139 }
140 }
141#endif
142
143#if defined(BOTAN_HAS_X942_PRF)
144 if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1)
145 {
146 if(provider.empty() || provider == "base")
147 {
148 return std::make_unique<X942_PRF>(req.arg(0));
149 }
150 }
151#endif
152
153#if defined(BOTAN_HAS_SP800_108)
154 if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1)
155 {
156 if(provider.empty() || provider == "base")
157 {
158 return kdf_create_mac_or_hash<SP800_108_Counter>(req.arg(0));
159 }
160 }
161
162 if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1)
163 {
164 if(provider.empty() || provider == "base")
165 {
166 return kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0));
167 }
168 }
169
170 if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1)
171 {
172 if(provider.empty() || provider == "base")
173 {
174 return kdf_create_mac_or_hash<SP800_108_Pipeline>(req.arg(0));
175 }
176 }
177#endif
178
179#if defined(BOTAN_HAS_SP800_56A)
180 if(req.algo_name() == "SP800-56A" && req.arg_count() == 1)
181 {
182 if(auto hash = HashFunction::create(req.arg(0)))
183 return std::make_unique<SP800_56A_Hash>(std::move(hash));
184 if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
185 return std::make_unique<SP800_56A_HMAC>(std::move(mac));
186 }
187#endif
188
189#if defined(BOTAN_HAS_SP800_56C)
190 if(req.algo_name() == "SP800-56C" && req.arg_count() == 1)
191 {
192 std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0)));
193 if(exp)
194 {
195 if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
196 return std::make_unique<SP800_56C>(std::move(mac), std::move(exp));
197
198 if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
199 return std::make_unique<SP800_56C>(std::move(mac), std::move(exp));
200 }
201 }
202#endif
203
204 BOTAN_UNUSED(req);
205 BOTAN_UNUSED(provider);
206
207 return nullptr;
208 }
209
210//static
211std::unique_ptr<KDF>
212KDF::create_or_throw(const std::string& algo,
213 const std::string& provider)
214 {
215 if(auto kdf = KDF::create(algo, provider))
216 {
217 return kdf;
218 }
219 throw Lookup_Error("KDF", algo, provider);
220 }
221
222std::vector<std::string> KDF::providers(const std::string& algo_spec)
223 {
224 return probe_providers_of<KDF>(algo_spec);
225 }
226
227}
#define BOTAN_UNUSED(...)
Definition: assert.h:141
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:98
static std::unique_ptr< KDF > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: kdf.cpp:212
static std::unique_ptr< KDF > create(const std::string &algo_spec, const std::string &provider="")
Definition: kdf.cpp:69
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::vector< std::string > providers(const std::string &algo_spec)
Definition: kdf.cpp:222
static std::unique_ptr< MessageAuthenticationCode > create(const std::string &algo_spec, const std::string &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:49
const std::string & algo_name() const
Definition: scan_name.h:44
Definition: alg_id.cpp:13
MechanismType hash