Botan 3.0.0
Crypto and TLS for C&
pk_algs.cpp
Go to the documentation of this file.
1/*
2* PK Key
3* (C) 1999-2010,2016 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/pk_algs.h>
9#include <botan/internal/parsing.h>
10#include <botan/internal/fmt.h>
11
12#if defined(BOTAN_HAS_RSA)
13 #include <botan/rsa.h>
14#endif
15
16#if defined(BOTAN_HAS_DSA)
17 #include <botan/dsa.h>
18#endif
19
20#if defined(BOTAN_HAS_DL_GROUP)
21 #include <botan/dl_group.h>
22#endif
23
24#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
25 #include <botan/dh.h>
26#endif
27
28#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
29 #include <botan/ecc_key.h>
30#endif
31
32#if defined(BOTAN_HAS_ECDSA)
33 #include <botan/ecdsa.h>
34#endif
35
36#if defined(BOTAN_HAS_ECGDSA)
37 #include <botan/ecgdsa.h>
38#endif
39
40#if defined(BOTAN_HAS_ECKCDSA)
41 #include <botan/eckcdsa.h>
42#endif
43
44#if defined(BOTAN_HAS_ED25519)
45 #include <botan/ed25519.h>
46#endif
47
48#if defined(BOTAN_HAS_GOST_34_10_2001)
49 #include <botan/gost_3410.h>
50#endif
51
52#if defined(BOTAN_HAS_ELGAMAL)
53 #include <botan/elgamal.h>
54#endif
55
56#if defined(BOTAN_HAS_ECDH)
57 #include <botan/ecdh.h>
58#endif
59
60#if defined(BOTAN_HAS_CURVE_25519)
61 #include <botan/curve25519.h>
62#endif
63
64#if defined(BOTAN_HAS_MCELIECE)
65 #include <botan/mceliece.h>
66#endif
67
68#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
69 #include <botan/kyber.h>
70#endif
71
72#if defined(BOTAN_HAS_XMSS_RFC8391)
73 #include <botan/xmss.h>
74#endif
75
76#if defined(BOTAN_HAS_SM2)
77 #include <botan/sm2.h>
78#endif
79
80#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
81 #include <botan/dilithium.h>
82#endif
83
84namespace Botan {
85
86std::unique_ptr<Public_Key>
88 [[maybe_unused]] std::span<const uint8_t> key_bits)
89 {
90 const std::string oid_str = alg_id.oid().to_formatted_string();
91 const std::vector<std::string> alg_info = split_on(oid_str, '/');
92 std::string_view alg_name = alg_info[0];
93
94#if defined(BOTAN_HAS_RSA)
95 if(alg_name == "RSA")
96 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
97#endif
98
99#if defined(BOTAN_HAS_CURVE_25519)
100 if(alg_name == "Curve25519")
101 return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits);
102#endif
103
104#if defined(BOTAN_HAS_MCELIECE)
105 if(alg_name == "McEliece")
106 return std::make_unique<McEliece_PublicKey>(key_bits);
107#endif
108
109#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
110 if(alg_name == "Kyber" || alg_name.starts_with("Kyber-"))
111 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
112#endif
113
114#if defined(BOTAN_HAS_ECDSA)
115 if(alg_name == "ECDSA")
116 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
117#endif
118
119#if defined(BOTAN_HAS_ECDH)
120 if(alg_name == "ECDH")
121 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
122#endif
123
124#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
125 if(alg_name == "DH")
126 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
127#endif
128
129#if defined(BOTAN_HAS_DSA)
130 if(alg_name == "DSA")
131 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
132#endif
133
134#if defined(BOTAN_HAS_ELGAMAL)
135 if(alg_name == "ElGamal")
136 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
137#endif
138
139#if defined(BOTAN_HAS_ECGDSA)
140 if(alg_name == "ECGDSA")
141 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
142#endif
143
144#if defined(BOTAN_HAS_ECKCDSA)
145 if(alg_name == "ECKCDSA")
146 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
147#endif
148
149#if defined(BOTAN_HAS_ED25519)
150 if(alg_name == "Ed25519")
151 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
152#endif
153
154#if defined(BOTAN_HAS_GOST_34_10_2001)
155 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
156 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
157#endif
158
159#if defined(BOTAN_HAS_SM2)
160 if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
161 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
162#endif
163
164#if defined(BOTAN_HAS_XMSS_RFC8391)
165 if(alg_name == "XMSS")
166 return std::make_unique<XMSS_PublicKey>(key_bits);
167#endif
168
169#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
170 if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-"))
171 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
172#endif
173
174 throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
175 }
176
177std::unique_ptr<Private_Key>
179 [[maybe_unused]] std::span<const uint8_t> key_bits)
180 {
181 const std::string oid_str = alg_id.oid().to_formatted_string();
182 const std::vector<std::string> alg_info = split_on(oid_str, '/');
183 std::string_view alg_name = alg_info[0];
184
185#if defined(BOTAN_HAS_RSA)
186 if(alg_name == "RSA")
187 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
188#endif
189
190#if defined(BOTAN_HAS_CURVE_25519)
191 if(alg_name == "Curve25519")
192 return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits);
193#endif
194
195#if defined(BOTAN_HAS_ECDSA)
196 if(alg_name == "ECDSA")
197 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
198#endif
199
200#if defined(BOTAN_HAS_ECDH)
201 if(alg_name == "ECDH")
202 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
203#endif
204
205#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
206 if(alg_name == "DH")
207 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
208#endif
209
210#if defined(BOTAN_HAS_DSA)
211 if(alg_name == "DSA")
212 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
213#endif
214
215#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
216 if(alg_name == "Kyber" || alg_name.starts_with("Kyber-"))
217 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
218#endif
219
220#if defined(BOTAN_HAS_MCELIECE)
221 if(alg_name == "McEliece")
222 return std::make_unique<McEliece_PrivateKey>(key_bits);
223#endif
224
225#if defined(BOTAN_HAS_ECGDSA)
226 if(alg_name == "ECGDSA")
227 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
228#endif
229
230#if defined(BOTAN_HAS_ECKCDSA)
231 if(alg_name == "ECKCDSA")
232 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
233#endif
234
235#if defined(BOTAN_HAS_ED25519)
236 if(alg_name == "Ed25519")
237 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
238#endif
239
240#if defined(BOTAN_HAS_GOST_34_10_2001)
241 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
242 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
243#endif
244
245#if defined(BOTAN_HAS_SM2)
246 if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
247 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
248#endif
249
250#if defined(BOTAN_HAS_ELGAMAL)
251 if(alg_name == "ElGamal")
252 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
253#endif
254
255#if defined(BOTAN_HAS_XMSS_RFC8391)
256 if(alg_name == "XMSS")
257 return std::make_unique<XMSS_PrivateKey>(key_bits);
258#endif
259
260#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
261 if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-"))
262 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
263#endif
264
265 throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
266 }
267
268BOTAN_PUBLIC_API(3,0) std::unique_ptr<Private_Key>
269create_ec_private_key(std::string_view alg_name,
270 const EC_Group& ec_group,
272 {
273 // Potentially unused if all EC algorthms are disabled
274 BOTAN_UNUSED(alg_name, ec_group, rng);
275
276#if defined(BOTAN_HAS_ECDSA)
277 if(alg_name == "ECDSA")
278 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
279#endif
280
281#if defined(BOTAN_HAS_ECDH)
282 if(alg_name == "ECDH")
283 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
284#endif
285
286#if defined(BOTAN_HAS_ECKCDSA)
287 if(alg_name == "ECKCDSA")
288 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
289#endif
290
291#if defined(BOTAN_HAS_GOST_34_10_2001)
292 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
293 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
294#endif
295
296#if defined(BOTAN_HAS_SM2)
297 if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
298 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
299#endif
300
301#if defined(BOTAN_HAS_ECGDSA)
302 if(alg_name == "ECGDSA")
303 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
304#endif
305
306 return nullptr;
307 }
308
309
310std::unique_ptr<Private_Key>
311create_private_key(std::string_view alg_name,
313 std::string_view params,
314 std::string_view provider)
315 {
316 /*
317 * Default paramaters are chosen for work factor > 2**128 where possible
318 */
319
320#if defined(BOTAN_HAS_CURVE_25519)
321 if(alg_name == "Curve25519")
322 return std::make_unique<Curve25519_PrivateKey>(rng);
323#endif
324
325#if defined(BOTAN_HAS_RSA)
326 if(alg_name == "RSA")
327 {
328 const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
329 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
330 }
331#endif
332
333#if defined(BOTAN_HAS_MCELIECE)
334 if(alg_name == "McEliece")
335 {
336 const auto [n, t] = [&]() -> std::pair<size_t, size_t>
337 {
338 if(params.empty())
339 return {2960, 57};
340
341 const auto mce_params = split_on(params, ',');
342
343 if(mce_params.size() != 2)
344 {
345 throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
346 }
347
348 const size_t mce_n = to_u32bit(mce_params[0]);
349 const size_t mce_t = to_u32bit(mce_params[1]);
350 return {mce_n, mce_t};
351 }();
352
353 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
354 }
355#endif
356
357#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
358 if(alg_name == "Kyber")
359 {
360 const auto mode = [&]() -> KyberMode
361 {
362 if(params.empty())
364 return KyberMode(params);
365 }();
366
367 return std::make_unique<Kyber_PrivateKey>(rng, mode);
368 }
369#endif
370
371#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
372 if(alg_name == "Dilithium" || alg_name == "Dilithium-")
373 {
374 const auto mode = [&]() -> DilithiumMode
375 {
376 if(params.empty())
378 return DilithiumMode(params);
379 }();
380
381 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
382 }
383#endif
384
385#if defined(BOTAN_HAS_XMSS_RFC8391)
386 if(alg_name == "XMSS")
387 {
388 const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t
389 {
390 if(params.empty())
392 return XMSS_Parameters(params).oid();
393 }();
394
395 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
396 }
397#endif
398
399#if defined(BOTAN_HAS_ED25519)
400 if(alg_name == "Ed25519")
401 {
402 return std::make_unique<Ed25519_PrivateKey>(rng);
403 }
404#endif
405
406 // ECC crypto
407#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
408
409 if(alg_name == "ECDSA" ||
410 alg_name == "ECDH" ||
411 alg_name == "ECKCDSA" ||
412 alg_name == "ECGDSA" ||
413 alg_name == "SM2" ||
414 alg_name == "SM2_Sig" ||
415 alg_name == "SM2_Enc" ||
416 alg_name == "GOST-34.10" ||
417 alg_name == "GOST-34.10-2012-256" ||
418 alg_name == "GOST-34.10-2012-512")
419 {
420 const std::string group_id = [&]() -> std::string
421 {
422 if(!params.empty())
423 return std::string(params);
424 if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig")
425 return "sm2p256v1";
426 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256")
427 return "gost_256A";
428 if(alg_name == "GOST-34.10-2012-512")
429 return "gost_512A";
430 if(alg_name == "ECGDSA")
431 return "brainpool256r1";
432 return "secp256r1";
433 }();
434
435 const EC_Group ec_group(group_id);
436 return create_ec_private_key(alg_name, ec_group, rng);
437 }
438#endif
439
440 // DL crypto
441#if defined(BOTAN_HAS_DL_GROUP)
442 if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
443 {
444 const std::string group_id = [&]() -> std::string
445 {
446 if(!params.empty())
447 return std::string(params);
448 if(alg_name == "DSA")
449 return "dsa/botan/2048";
450 return "modp/ietf/2048";
451 }();
452
453 DL_Group modp_group(group_id);
454
455#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
456 if(alg_name == "DH")
457 return std::make_unique<DH_PrivateKey>(rng, modp_group);
458#endif
459
460#if defined(BOTAN_HAS_DSA)
461 if(alg_name == "DSA")
462 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
463#endif
464
465#if defined(BOTAN_HAS_ELGAMAL)
466 if(alg_name == "ElGamal")
467 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
468#endif
469 }
470#endif
471
472 BOTAN_UNUSED(alg_name, rng, params, provider);
473
474 return std::unique_ptr<Private_Key>();
475 }
476
477std::vector<std::string>
478probe_provider_private_key(std::string_view alg_name,
479 const std::vector<std::string>& possible)
480 {
481 std::vector<std::string> providers;
482
483 for(auto&& prov : possible)
484 {
485 if(prov == "base")
486 providers.push_back(prov);
487 }
488
489 BOTAN_UNUSED(alg_name);
490
491 return providers;
492 }
493}
#define BOTAN_UNUSED(...)
Definition: assert.h:141
const OID & oid() const
Definition: asn1_obj.h:477
std::string to_formatted_string() const
Definition: asn1_oid.cpp:120
xmss_algorithm_t oid() const
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: alg_id.cpp:12
uint32_t to_u32bit(std::string_view str_view)
Definition: parsing.cpp:31
std::unique_ptr< Private_Key > create_private_key(std::string_view alg_name, RandomNumberGenerator &rng, std::string_view params, std::string_view provider)
Definition: pk_algs.cpp:311
std::string fmt(std::string_view format, const T &... args)
Definition: fmt.h:60
std::vector< std::string > split_on(std::string_view str, char delim)
Definition: parsing.cpp:117
std::vector< std::string > probe_provider_private_key(std::string_view alg_name, const std::vector< std::string > &possible)
Definition: pk_algs.cpp:478
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
Definition: pk_algs.cpp:178
std::unique_ptr< Public_Key > load_public_key(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
Definition: pk_algs.cpp:87
std::unique_ptr< Private_Key > create_ec_private_key(std::string_view alg_name, const EC_Group &ec_group, RandomNumberGenerator &rng)
Definition: pk_algs.cpp:269
Definition: bigint.h:1092