Coverage Report

Created: 2026-06-15 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/pubkey/pk_algs.cpp
Line
Count
Source
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
10
#include <botan/asn1_obj.h>
11
#include <botan/assert.h>
12
#include <botan/pk_keys.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/parsing.h>
15
16
#if defined(BOTAN_HAS_RSA)
17
   #include <botan/rsa.h>
18
#endif
19
20
#if defined(BOTAN_HAS_CLASSICMCELIECE)
21
   #include <botan/cmce.h>
22
#endif
23
24
#if defined(BOTAN_HAS_DSA)
25
   #include <botan/dsa.h>
26
#endif
27
28
#if defined(BOTAN_HAS_DL_GROUP)
29
   #include <botan/dl_group.h>
30
#endif
31
32
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
33
   #include <botan/dh.h>
34
#endif
35
36
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
37
   #include <botan/ecc_key.h>
38
#endif
39
40
#if defined(BOTAN_HAS_ECC_GROUP)
41
   #include <botan/ec_group.h>
42
#endif
43
44
#if defined(BOTAN_HAS_ECDSA)
45
   #include <botan/ecdsa.h>
46
#endif
47
48
#if defined(BOTAN_HAS_ECGDSA)
49
   #include <botan/ecgdsa.h>
50
#endif
51
52
#if defined(BOTAN_HAS_ECKCDSA)
53
   #include <botan/eckcdsa.h>
54
#endif
55
56
#if defined(BOTAN_HAS_ED25519)
57
   #include <botan/ed25519.h>
58
#endif
59
60
#if defined(BOTAN_HAS_ED448)
61
   #include <botan/ed448.h>
62
#endif
63
64
#if defined(BOTAN_HAS_GOST_34_10_2001)
65
   #include <botan/gost_3410.h>
66
#endif
67
68
#if defined(BOTAN_HAS_ELGAMAL)
69
   #include <botan/elgamal.h>
70
#endif
71
72
#if defined(BOTAN_HAS_ECDH)
73
   #include <botan/ecdh.h>
74
#endif
75
76
#if defined(BOTAN_HAS_X25519)
77
   #include <botan/x25519.h>
78
#endif
79
80
#if defined(BOTAN_HAS_X448)
81
   #include <botan/x448.h>
82
#endif
83
84
#if defined(BOTAN_HAS_MCELIECE)
85
   #include <botan/mceliece.h>
86
#endif
87
88
#if defined(BOTAN_HAS_FRODOKEM)
89
   #include <botan/frodokem.h>
90
#endif
91
92
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
93
   #include <botan/kyber.h>
94
#endif
95
96
#if defined(BOTAN_HAS_ML_KEM)
97
   #include <botan/ml_kem.h>
98
#endif
99
100
#if defined(BOTAN_HAS_HSS_LMS)
101
   #include <botan/hss_lms.h>
102
#endif
103
104
#if defined(BOTAN_HAS_XMSS_RFC8391)
105
   #include <botan/xmss.h>
106
#endif
107
108
#if defined(BOTAN_HAS_SM2)
109
   #include <botan/sm2.h>
110
#endif
111
112
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
113
   #include <botan/dilithium.h>
114
#endif
115
116
#if defined(BOTAN_HAS_ML_DSA)
117
   #include <botan/ml_dsa.h>
118
#endif
119
120
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
121
   #include <botan/sphincsplus.h>
122
#endif
123
124
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
125
   #include <botan/slh_dsa.h>
126
#endif
127
128
namespace Botan {
129
130
std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
131
8.61k
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
132
8.61k
   const std::string oid_str = alg_id.oid().to_formatted_string();
133
8.61k
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
134
8.61k
   const std::string_view alg_name = alg_info[0];
135
136
8.61k
#if defined(BOTAN_HAS_RSA)
137
8.61k
   if(alg_name == "RSA") {
138
1.35k
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
139
1.35k
   }
140
7.25k
#endif
141
142
7.25k
#if defined(BOTAN_HAS_X25519)
143
7.25k
   if(alg_name == "X25519" || alg_name == "Curve25519") {
144
1
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
145
1
   }
146
7.25k
#endif
147
148
7.25k
#if defined(BOTAN_HAS_X448)
149
7.25k
   if(alg_name == "X448") {
150
1
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
151
1
   }
152
7.25k
#endif
153
154
7.25k
#if defined(BOTAN_HAS_MCELIECE)
155
7.25k
   if(alg_name == "McEliece") {
156
0
      return std::make_unique<McEliece_PublicKey>(alg_id, key_bits);
157
0
   }
158
7.25k
#endif
159
160
7.25k
#if defined(BOTAN_HAS_FRODOKEM)
161
7.25k
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
162
0
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
163
0
   }
164
7.25k
#endif
165
166
7.25k
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
167
7.25k
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
168
0
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
169
0
   }
170
7.25k
#endif
171
172
7.25k
#if defined(BOTAN_HAS_ML_KEM)
173
7.25k
   if(alg_name.starts_with("ML-KEM-")) {
174
9
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
175
9
   }
176
7.24k
#endif
177
178
7.24k
#if defined(BOTAN_HAS_ECDSA)
179
7.24k
   if(alg_name == "ECDSA") {
180
1.75k
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
181
1.75k
   }
182
5.48k
#endif
183
184
5.48k
#if defined(BOTAN_HAS_ECDH)
185
5.48k
   if(alg_name == "ECDH") {
186
0
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
187
0
   }
188
5.48k
#endif
189
190
5.48k
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
191
5.48k
   if(alg_name == "DH") {
192
5
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
193
5
   }
194
5.48k
#endif
195
196
5.48k
#if defined(BOTAN_HAS_DSA)
197
5.48k
   if(alg_name == "DSA") {
198
59
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
199
59
   }
200
5.42k
#endif
201
202
5.42k
#if defined(BOTAN_HAS_ELGAMAL)
203
5.42k
   if(alg_name == "ElGamal") {
204
0
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
205
0
   }
206
5.42k
#endif
207
208
5.42k
#if defined(BOTAN_HAS_ECGDSA)
209
5.42k
   if(alg_name == "ECGDSA") {
210
0
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
211
0
   }
212
5.42k
#endif
213
214
5.42k
#if defined(BOTAN_HAS_ECKCDSA)
215
5.42k
   if(alg_name == "ECKCDSA") {
216
0
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
217
0
   }
218
5.42k
#endif
219
220
5.42k
#if defined(BOTAN_HAS_ED25519)
221
5.42k
   if(alg_name == "Ed25519") {
222
1
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
223
1
   }
224
5.42k
#endif
225
226
5.42k
#if defined(BOTAN_HAS_ED448)
227
5.42k
   if(alg_name == "Ed448") {
228
1
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
229
1
   }
230
5.41k
#endif
231
232
5.41k
#if defined(BOTAN_HAS_GOST_34_10_2001)
233
5.41k
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
234
1.07k
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
235
1.07k
   }
236
4.34k
#endif
237
238
4.34k
#if defined(BOTAN_HAS_SM2)
239
4.34k
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
240
0
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
241
0
   }
242
4.34k
#endif
243
244
4.34k
#if defined(BOTAN_HAS_XMSS_RFC8391)
245
4.34k
   if(alg_name == "XMSS") {
246
0
      return std::make_unique<XMSS_PublicKey>(alg_id, key_bits);
247
0
   }
248
4.34k
#endif
249
250
4.34k
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
251
4.34k
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
252
0
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
253
0
   }
254
4.34k
#endif
255
256
4.34k
#if defined(BOTAN_HAS_ML_DSA)
257
4.34k
   if(alg_name.starts_with("ML-DSA-")) {
258
9
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
259
9
   }
260
4.33k
#endif
261
262
4.33k
#if defined(BOTAN_HAS_HSS_LMS)
263
4.33k
   if(alg_name == "HSS-LMS") {
264
0
      return std::make_unique<HSS_LMS_PublicKey>(alg_id, key_bits);
265
0
   }
266
4.33k
#endif
267
268
4.33k
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
269
4.33k
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
270
0
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
271
0
   }
272
4.33k
#endif
273
274
4.33k
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
275
4.33k
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
276
36
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
277
36
   }
278
4.29k
#endif
279
280
4.29k
#if defined(BOTAN_HAS_CLASSICMCELIECE)
281
4.29k
   if(alg_name.starts_with("ClassicMcEliece")) {
282
0
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
283
0
   }
284
4.29k
#endif
285
286
4.29k
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
287
4.29k
}
288
289
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
290
11.5k
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
291
11.5k
   const std::string oid_str = alg_id.oid().to_formatted_string();
292
11.5k
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
293
11.5k
   const std::string_view alg_name = alg_info[0];
294
295
11.5k
#if defined(BOTAN_HAS_RSA)
296
11.5k
   if(alg_name == "RSA") {
297
34
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
298
34
   }
299
11.5k
#endif
300
301
11.5k
#if defined(BOTAN_HAS_X25519)
302
11.5k
   if(alg_name == "X25519" || alg_name == "Curve25519") {
303
9
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
304
9
   }
305
11.5k
#endif
306
307
11.5k
#if defined(BOTAN_HAS_X448)
308
11.5k
   if(alg_name == "X448") {
309
4
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
310
4
   }
311
11.5k
#endif
312
313
11.5k
#if defined(BOTAN_HAS_ECDSA)
314
11.5k
   if(alg_name == "ECDSA") {
315
10.3k
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
316
10.3k
   }
317
1.14k
#endif
318
319
1.14k
#if defined(BOTAN_HAS_ECDH)
320
1.14k
   if(alg_name == "ECDH") {
321
770
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
322
770
   }
323
370
#endif
324
325
370
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
326
370
   if(alg_name == "DH") {
327
94
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
328
94
   }
329
276
#endif
330
331
276
#if defined(BOTAN_HAS_DSA)
332
276
   if(alg_name == "DSA") {
333
10
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
334
10
   }
335
266
#endif
336
337
266
#if defined(BOTAN_HAS_FRODOKEM)
338
266
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
339
0
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
340
0
   }
341
266
#endif
342
343
266
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
344
266
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
345
0
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
346
0
   }
347
266
#endif
348
349
266
#if defined(BOTAN_HAS_ML_KEM)
350
266
   if(alg_name.starts_with("ML-KEM-")) {
351
42
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
352
42
   }
353
224
#endif
354
355
224
#if defined(BOTAN_HAS_MCELIECE)
356
224
   if(alg_name == "McEliece") {
357
0
      return std::make_unique<McEliece_PrivateKey>(alg_id, key_bits);
358
0
   }
359
224
#endif
360
361
224
#if defined(BOTAN_HAS_ECGDSA)
362
224
   if(alg_name == "ECGDSA") {
363
0
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
364
0
   }
365
224
#endif
366
367
224
#if defined(BOTAN_HAS_ECKCDSA)
368
224
   if(alg_name == "ECKCDSA") {
369
0
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
370
0
   }
371
224
#endif
372
373
224
#if defined(BOTAN_HAS_ED25519)
374
224
   if(alg_name == "Ed25519") {
375
10
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
376
10
   }
377
214
#endif
378
379
214
#if defined(BOTAN_HAS_ED448)
380
214
   if(alg_name == "Ed448") {
381
4
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
382
4
   }
383
210
#endif
384
385
210
#if defined(BOTAN_HAS_GOST_34_10_2001)
386
210
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
387
2
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
388
2
   }
389
208
#endif
390
391
208
#if defined(BOTAN_HAS_SM2)
392
208
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
393
0
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
394
0
   }
395
208
#endif
396
397
208
#if defined(BOTAN_HAS_ELGAMAL)
398
208
   if(alg_name == "ElGamal") {
399
0
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
400
0
   }
401
208
#endif
402
403
208
#if defined(BOTAN_HAS_XMSS_RFC8391)
404
208
   if(alg_name == "XMSS") {
405
0
      return std::make_unique<XMSS_PrivateKey>(alg_id, key_bits);
406
0
   }
407
208
#endif
408
409
208
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
410
208
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
411
0
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
412
0
   }
413
208
#endif
414
415
208
#if defined(BOTAN_HAS_ML_DSA)
416
208
   if(alg_name.starts_with("ML-DSA-")) {
417
87
      return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
418
87
   }
419
121
#endif
420
421
121
#if defined(BOTAN_HAS_HSS_LMS)
422
121
   if(alg_name == "HSS-LMS-Private-Key") {
423
0
      return std::make_unique<HSS_LMS_PrivateKey>(alg_id, key_bits);
424
0
   }
425
121
#endif
426
427
121
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
428
121
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
429
0
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
430
0
   }
431
121
#endif
432
433
121
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
434
121
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
435
14
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
436
14
   }
437
107
#endif
438
439
107
#if defined(BOTAN_HAS_CLASSICMCELIECE)
440
107
   if(alg_name.starts_with("ClassicMcEliece")) {
441
0
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
442
0
   }
443
107
#endif
444
445
107
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
446
107
}
447
448
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
449
                                                   const EC_Group& ec_group,
450
0
                                                   RandomNumberGenerator& rng) {
451
   // Potentially unused if all EC algorithms are disabled
452
0
   BOTAN_UNUSED(alg_name, ec_group, rng);
453
454
0
#if defined(BOTAN_HAS_ECDSA)
455
0
   if(alg_name == "ECDSA") {
456
0
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
457
0
   }
458
0
#endif
459
460
0
#if defined(BOTAN_HAS_ECDH)
461
0
   if(alg_name == "ECDH") {
462
0
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
463
0
   }
464
0
#endif
465
466
0
#if defined(BOTAN_HAS_ECKCDSA)
467
0
   if(alg_name == "ECKCDSA") {
468
0
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
469
0
   }
470
0
#endif
471
472
0
#if defined(BOTAN_HAS_GOST_34_10_2001)
473
0
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
474
0
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
475
0
   }
476
0
#endif
477
478
0
#if defined(BOTAN_HAS_SM2)
479
0
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
480
0
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
481
0
   }
482
0
#endif
483
484
0
#if defined(BOTAN_HAS_ECGDSA)
485
0
   if(alg_name == "ECGDSA") {
486
0
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
487
0
   }
488
0
#endif
489
490
0
   return nullptr;
491
0
}
492
493
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
494
                                                RandomNumberGenerator& rng,
495
                                                std::string_view params,
496
0
                                                std::string_view provider) {
497
   /*
498
   * Default parameters are chosen for work factor > 2**128 where possible
499
   */
500
501
0
#if defined(BOTAN_HAS_X25519)
502
0
   if(alg_name == "X25519" || alg_name == "Curve25519") {
503
0
      return std::make_unique<X25519_PrivateKey>(rng);
504
0
   }
505
0
#endif
506
507
0
#if defined(BOTAN_HAS_X448)
508
0
   if(alg_name == "X448") {
509
0
      return std::make_unique<X448_PrivateKey>(rng);
510
0
   }
511
0
#endif
512
513
0
#if defined(BOTAN_HAS_RSA)
514
0
   if(alg_name == "RSA") {
515
0
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
516
0
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
517
0
   }
518
0
#endif
519
520
0
#if defined(BOTAN_HAS_MCELIECE)
521
0
   if(alg_name == "McEliece") {
522
0
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
523
0
         if(params.empty()) {
524
0
            return {2960, 57};
525
0
         }
526
527
0
         const auto mce_params = split_on(params, ',');
528
529
0
         if(mce_params.size() != 2) {
530
0
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
531
0
         }
532
533
0
         const size_t mce_n = to_u32bit(mce_params[0]);
534
0
         const size_t mce_t = to_u32bit(mce_params[1]);
535
0
         return {mce_n, mce_t};
536
0
      }();
537
538
0
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
539
0
   }
540
0
#endif
541
0
#if defined(BOTAN_HAS_CLASSICMCELIECE)
542
0
   if(alg_name == "ClassicMcEliece") {
543
0
      auto cmce_params_set = params.empty() ? Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f
544
0
                                            : Classic_McEliece_Parameter_Set::from_string(params);
545
0
      return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
546
0
   }
547
0
#endif
548
549
0
#if defined(BOTAN_HAS_FRODOKEM)
550
0
   if(alg_name == "FrodoKEM") {
551
0
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
552
0
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
553
0
   }
554
0
#endif
555
556
0
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
557
0
   if(alg_name == "Kyber") {
558
0
      const auto mode = [&]() -> KyberMode {
559
0
         if(params.empty()) {
560
0
            return KyberMode::Kyber1024_R3;
561
0
         }
562
0
         return KyberMode(params);
563
0
      }();
564
565
0
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
566
0
   }
567
0
#endif
568
569
0
#if defined(BOTAN_HAS_ML_KEM)
570
0
   if(alg_name == "ML-KEM") {
571
0
      const auto mode = [&]() -> ML_KEM_Mode {
572
0
         if(params.empty()) {
573
0
            return ML_KEM_Mode::ML_KEM_768;
574
0
         }
575
0
         return ML_KEM_Mode(params);
576
0
      }();
577
578
0
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
579
0
   }
580
0
#endif
581
582
0
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
583
0
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
584
0
      const auto mode = [&]() -> DilithiumMode {
585
0
         if(params.empty()) {
586
0
            return DilithiumMode::Dilithium6x5;
587
0
         }
588
0
         return DilithiumMode(params);
589
0
      }();
590
591
0
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
592
0
   }
593
0
#endif
594
595
0
#if defined(BOTAN_HAS_ML_DSA)
596
0
   if(alg_name == "ML-DSA") {
597
0
      const auto mode = [&]() -> ML_DSA_Mode {
598
0
         if(params.empty()) {
599
0
            return ML_DSA_Mode::ML_DSA_6x5;
600
0
         }
601
0
         return ML_DSA_Mode(params);
602
0
      }();
603
604
0
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
605
0
   }
606
0
#endif
607
608
0
#if defined(BOTAN_HAS_HSS_LMS)
609
0
   if(alg_name == "HSS-LMS") {
610
0
      const auto hss_params = [&]() -> std::string {
611
0
         if(params.empty()) {
612
0
            return "SHA-256,HW(10,1)";
613
0
         } else {
614
0
            return std::string(params);
615
0
         }
616
0
      }();
617
0
      return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
618
0
   }
619
0
#endif
620
621
0
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
622
0
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
623
0
      auto sphincs_params = Sphincs_Parameters::create(params);
624
625
0
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
626
0
   }
627
0
#endif
628
629
0
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
630
0
   if(alg_name == "SLH-DSA") {
631
0
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
632
633
0
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
634
0
   }
635
0
#endif
636
637
0
#if defined(BOTAN_HAS_XMSS_RFC8391)
638
0
   if(alg_name == "XMSS") {
639
0
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
640
0
         if(params.empty()) {
641
0
            return XMSS_Parameters::XMSS_SHA2_10_512;
642
0
         }
643
0
         return XMSS_Parameters::from_name(params).oid();
644
0
      }();
645
646
0
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
647
0
   }
648
0
#endif
649
650
0
#if defined(BOTAN_HAS_ED25519)
651
0
   if(alg_name == "Ed25519") {
652
0
      return std::make_unique<Ed25519_PrivateKey>(rng);
653
0
   }
654
0
#endif
655
656
0
#if defined(BOTAN_HAS_ED448)
657
0
   if(alg_name == "Ed448") {
658
0
      return std::make_unique<Ed448_PrivateKey>(rng);
659
0
   }
660
0
#endif
661
662
   // ECC crypto
663
0
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
664
665
0
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
666
0
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
667
0
      alg_name == "GOST-34.10-2012-512") {
668
0
      const std::string group_id = [&]() -> std::string {
669
0
         if(!params.empty()) {
670
0
            return std::string(params);
671
0
         }
672
0
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
673
0
            return "sm2p256v1";
674
0
         }
675
0
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
676
0
            return "gost_256A";
677
0
         }
678
0
         if(alg_name == "GOST-34.10-2012-512") {
679
0
            return "gost_512A";
680
0
         }
681
0
         if(alg_name == "ECGDSA") {
682
0
            return "brainpool256r1";
683
0
         }
684
0
         return "secp256r1";
685
0
      }();
686
687
0
      if(EC_Group::supports_named_group(group_id)) {
688
0
         auto ec_group = EC_Group::from_name(group_id);
689
0
         return create_ec_private_key(alg_name, ec_group, rng);
690
0
      } else {
691
0
         return {};
692
0
      }
693
0
   }
694
0
#endif
695
696
   // DL crypto
697
0
#if defined(BOTAN_HAS_DL_GROUP)
698
0
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
699
0
      const std::string group_id = [&]() -> std::string {
700
0
         if(!params.empty()) {
701
0
            return std::string(params);
702
0
         }
703
0
         if(alg_name == "DSA") {
704
0
            return "dsa/botan/2048";
705
0
         }
706
0
         return "modp/ietf/2048";
707
0
      }();
708
709
0
      auto modp_group = DL_Group::from_name(group_id);
710
711
0
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
712
0
      if(alg_name == "DH") {
713
0
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
714
0
      }
715
0
   #endif
716
717
0
   #if defined(BOTAN_HAS_DSA)
718
0
      if(alg_name == "DSA") {
719
0
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
720
0
      }
721
0
   #endif
722
723
0
   #if defined(BOTAN_HAS_ELGAMAL)
724
0
      if(alg_name == "ElGamal") {
725
0
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
726
0
      }
727
0
   #endif
728
0
   }
729
0
#endif
730
731
0
   BOTAN_UNUSED(alg_name, rng, params, provider);
732
733
0
   return std::unique_ptr<Private_Key>();
734
0
}
735
736
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
737
0
                                                    const std::vector<std::string>& possible) {
738
0
   std::vector<std::string> providers;
739
740
0
   for(auto&& prov : possible) {
741
0
      if(prov == "base") {
742
0
         providers.push_back(prov);
743
0
      }
744
0
   }
745
746
0
   BOTAN_UNUSED(alg_name);
747
748
0
   return providers;
749
0
}
750
}  // namespace Botan