Botan 3.5.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
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
52namespace Botan {
53
54namespace {
55
56template <typename KDF_Type>
57std::unique_ptr<KDF> kdf_create_mac_or_hash(std::string_view nm) {
58 if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", nm))) {
59 return std::make_unique<KDF_Type>(std::move(mac));
60 }
61
62 if(auto mac = MessageAuthenticationCode::create(nm)) {
63 return std::make_unique<KDF_Type>(std::move(mac));
64 }
65
66 return nullptr;
67}
68
69} // namespace
70
71std::unique_ptr<KDF> KDF::create(std::string_view algo_spec, std::string_view provider) {
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 if(provider.empty() || provider == "base") {
77 return kdf_create_mac_or_hash<HKDF>(req.arg(0));
78 }
79 }
80
81 if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1) {
82 if(provider.empty() || provider == "base") {
83 return kdf_create_mac_or_hash<HKDF_Extract>(req.arg(0));
84 }
85 }
86
87 if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1) {
88 if(provider.empty() || provider == "base") {
89 return kdf_create_mac_or_hash<HKDF_Expand>(req.arg(0));
90 }
91 }
92#endif
93
94#if defined(BOTAN_HAS_KDF2)
95 if(req.algo_name() == "KDF2" && req.arg_count() == 1) {
96 if(provider.empty() || provider == "base") {
97 if(auto hash = HashFunction::create(req.arg(0))) {
98 return std::make_unique<KDF2>(std::move(hash));
99 }
100 }
101 }
102#endif
103
104#if defined(BOTAN_HAS_KDF1_18033)
105 if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1) {
106 if(provider.empty() || provider == "base") {
107 if(auto hash = HashFunction::create(req.arg(0))) {
108 return std::make_unique<KDF1_18033>(std::move(hash));
109 }
110 }
111 }
112#endif
113
114#if defined(BOTAN_HAS_KDF1)
115 if(req.algo_name() == "KDF1" && req.arg_count() == 1) {
116 if(provider.empty() || provider == "base") {
117 if(auto hash = HashFunction::create(req.arg(0))) {
118 return std::make_unique<KDF1>(std::move(hash));
119 }
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) {
126 if(provider.empty() || provider == "base") {
127 return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
128 }
129 }
130#endif
131
132#if defined(BOTAN_HAS_X942_PRF)
133 if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1) {
134 if(provider.empty() || provider == "base") {
135 return std::make_unique<X942_PRF>(req.arg(0));
136 }
137 }
138#endif
139
140#if defined(BOTAN_HAS_SP800_108)
141 if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1) {
142 if(provider.empty() || provider == "base") {
143 return kdf_create_mac_or_hash<SP800_108_Counter>(req.arg(0));
144 }
145 }
146
147 if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1) {
148 if(provider.empty() || provider == "base") {
149 return kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0));
150 }
151 }
152
153 if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1) {
154 if(provider.empty() || provider == "base") {
155 return kdf_create_mac_or_hash<SP800_108_Pipeline>(req.arg(0));
156 }
157 }
158#endif
159
160#if defined(BOTAN_HAS_SP800_56A)
161 if(req.algo_name() == "SP800-56A" && req.arg_count() == 1) {
162 if(auto hash = HashFunction::create(req.arg(0))) {
163 return std::make_unique<SP800_56C_One_Step_Hash>(std::move(hash));
164 }
165 if(req.arg(0) == "KMAC-128") {
166 return std::make_unique<SP800_56C_One_Step_KMAC128>();
167 }
168 if(req.arg(0) == "KMAC-256") {
169 return std::make_unique<SP800_56C_One_Step_KMAC256>();
170 }
171 if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
172 return std::make_unique<SP800_56C_One_Step_HMAC>(std::move(mac));
173 }
174 }
175#endif
176
177#if defined(BOTAN_HAS_SP800_56C)
178 if(req.algo_name() == "SP800-56C" && req.arg_count() == 1) {
179 std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0)));
180 if(exp) {
181 if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
182 return std::make_unique<SP800_56C_Two_Step>(std::move(mac), std::move(exp));
183 }
184
185 if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", req.arg(0)))) {
186 return std::make_unique<SP800_56C_Two_Step>(std::move(mac), std::move(exp));
187 }
188 }
189 }
190#endif
191
192 BOTAN_UNUSED(req);
193 BOTAN_UNUSED(provider);
194
195 return nullptr;
196}
197
198//static
199std::unique_ptr<KDF> KDF::create_or_throw(std::string_view algo, std::string_view provider) {
200 if(auto kdf = KDF::create(algo, provider)) {
201 return kdf;
202 }
203 throw Lookup_Error("KDF", algo, provider);
204}
205
206std::vector<std::string> KDF::providers(std::string_view algo_spec) {
207 return probe_providers_of<KDF>(algo_spec);
208}
209
210} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:107
static std::unique_ptr< KDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition kdf.cpp:199
static std::vector< std::string > providers(std::string_view algo_spec)
Definition kdf.cpp:206
static std::unique_ptr< KDF > create(std::string_view algo_spec, std::string_view provider="")
Definition kdf.cpp:71
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:51
std::string arg(size_t i) const
size_t arg_count() const
Definition scan_name.h:49
const std::string & algo_name() const
Definition scan_name.h:44
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
std::vector< std::string > probe_providers_of(std::string_view algo_spec, const std::vector< std::string > &possible={"base"})
Definition scan_name.h:105