• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 13021208024

28 Jan 2025 11:07PM UTC coverage: 91.241% (-0.02%) from 91.258%
13021208024

push

github

web-flow
Merge pull request #4604 from randombit/jack/support-minimal-curves

Avoid requiring legacy_ec_group in order to run the tests

94137 of 103174 relevant lines covered (91.24%)

11291073.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.44
/src/lib/pubkey/pk_algs.cpp
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/internal/fmt.h>
11
#include <botan/internal/parsing.h>
12

13
#if defined(BOTAN_HAS_RSA)
14
   #include <botan/rsa.h>
15
#endif
16

17
#if defined(BOTAN_HAS_CLASSICMCELIECE)
18
   #include <botan/cmce.h>
19
#endif
20

21
#if defined(BOTAN_HAS_DSA)
22
   #include <botan/dsa.h>
23
#endif
24

25
#if defined(BOTAN_HAS_DL_GROUP)
26
   #include <botan/dl_group.h>
27
#endif
28

29
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
30
   #include <botan/dh.h>
31
#endif
32

33
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
34
   #include <botan/ecc_key.h>
35
#endif
36

37
#if defined(BOTAN_HAS_ECDSA)
38
   #include <botan/ecdsa.h>
39
#endif
40

41
#if defined(BOTAN_HAS_ECGDSA)
42
   #include <botan/ecgdsa.h>
43
#endif
44

45
#if defined(BOTAN_HAS_ECKCDSA)
46
   #include <botan/eckcdsa.h>
47
#endif
48

49
#if defined(BOTAN_HAS_ED25519)
50
   #include <botan/ed25519.h>
51
#endif
52

53
#if defined(BOTAN_HAS_ED448)
54
   #include <botan/ed448.h>
55
#endif
56

57
#if defined(BOTAN_HAS_GOST_34_10_2001)
58
   #include <botan/gost_3410.h>
59
#endif
60

61
#if defined(BOTAN_HAS_ELGAMAL)
62
   #include <botan/elgamal.h>
63
#endif
64

65
#if defined(BOTAN_HAS_ECDH)
66
   #include <botan/ecdh.h>
67
#endif
68

69
#if defined(BOTAN_HAS_X25519)
70
   #include <botan/x25519.h>
71
#endif
72

73
#if defined(BOTAN_HAS_X448)
74
   #include <botan/x448.h>
75
#endif
76

77
#if defined(BOTAN_HAS_MCELIECE)
78
   #include <botan/mceliece.h>
79
#endif
80

81
#if defined(BOTAN_HAS_FRODOKEM)
82
   #include <botan/frodokem.h>
83
#endif
84

85
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
86
   #include <botan/kyber.h>
87
#endif
88

89
#if defined(BOTAN_HAS_ML_KEM)
90
   #include <botan/ml_kem.h>
91
#endif
92

93
#if defined(BOTAN_HAS_HSS_LMS)
94
   #include <botan/hss_lms.h>
95
#endif
96

97
#if defined(BOTAN_HAS_XMSS_RFC8391)
98
   #include <botan/xmss.h>
99
#endif
100

101
#if defined(BOTAN_HAS_SM2)
102
   #include <botan/sm2.h>
103
#endif
104

105
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
106
   #include <botan/dilithium.h>
107
#endif
108

109
#if defined(BOTAN_HAS_ML_DSA)
110
   #include <botan/ml_dsa.h>
111
#endif
112

113
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
114
   #include <botan/sphincsplus.h>
115
#endif
116

117
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
118
   #include <botan/slh_dsa.h>
119
#endif
120

121
namespace Botan {
122

123
std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
21,567✔
124
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
125
   const std::string oid_str = alg_id.oid().to_formatted_string();
21,567✔
126
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
21,567✔
127
   std::string_view alg_name = alg_info[0];
21,567✔
128

129
#if defined(BOTAN_HAS_RSA)
130
   if(alg_name == "RSA") {
21,567✔
131
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
30,491✔
132
   }
133
#endif
134

135
#if defined(BOTAN_HAS_X25519)
136
   if(alg_name == "X25519" || alg_name == "Curve25519") {
6,028✔
137
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
78✔
138
   }
139
#endif
140

141
#if defined(BOTAN_HAS_X448)
142
   if(alg_name == "X448") {
5,877✔
143
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
144
   }
145
#endif
146

147
#if defined(BOTAN_HAS_MCELIECE)
148
   if(alg_name == "McEliece") {
5,875✔
149
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
150
   }
151
#endif
152

153
#if defined(BOTAN_HAS_FRODOKEM)
154
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
5,875✔
155
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
156
   }
157
#endif
158

159
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
160
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
9,221✔
161
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
324✔
162
   }
163
#endif
164

165
#if defined(BOTAN_HAS_ML_KEM)
166
   if(alg_name.starts_with("ML-KEM-")) {
5,396✔
167
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
197✔
168
   }
169
#endif
170

171
#if defined(BOTAN_HAS_ECDSA)
172
   if(alg_name == "ECDSA") {
5,297✔
173
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
6,881✔
174
   }
175
#endif
176

177
#if defined(BOTAN_HAS_ECDH)
178
   if(alg_name == "ECDH") {
1,708✔
179
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
33✔
180
   }
181
#endif
182

183
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
184
   if(alg_name == "DH") {
1,691✔
185
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
11✔
186
   }
187
#endif
188

189
#if defined(BOTAN_HAS_DSA)
190
   if(alg_name == "DSA") {
1,683✔
191
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
192
   }
193
#endif
194

195
#if defined(BOTAN_HAS_ELGAMAL)
196
   if(alg_name == "ElGamal") {
1,449✔
197
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
198
   }
199
#endif
200

201
#if defined(BOTAN_HAS_ECGDSA)
202
   if(alg_name == "ECGDSA") {
1,445✔
203
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
146✔
204
   }
205
#endif
206

207
#if defined(BOTAN_HAS_ECKCDSA)
208
   if(alg_name == "ECKCDSA") {
1,372✔
209
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
144✔
210
   }
211
#endif
212

213
#if defined(BOTAN_HAS_ED25519)
214
   if(alg_name == "Ed25519") {
1,300✔
215
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,528✔
216
   }
217
#endif
218

219
#if defined(BOTAN_HAS_ED448)
220
   if(alg_name == "Ed448") {
536✔
221
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
146✔
222
   }
223
#endif
224

225
#if defined(BOTAN_HAS_GOST_34_10_2001)
226
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
595✔
227
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
132✔
228
   }
229
#endif
230

231
#if defined(BOTAN_HAS_SM2)
232
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
465✔
233
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
30✔
234
   }
235
#endif
236

237
#if defined(BOTAN_HAS_XMSS_RFC8391)
238
   if(alg_name == "XMSS") {
382✔
239
      return std::make_unique<XMSS_PublicKey>(key_bits);
88✔
240
   }
241
#endif
242

243
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
244
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
340✔
245
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
168✔
246
   }
247
#endif
248

249
#if defined(BOTAN_HAS_ML_DSA)
250
   if(alg_name.starts_with("ML-DSA-")) {
254✔
251
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
120✔
252
   }
253
#endif
254

255
#if defined(BOTAN_HAS_HSS_LMS)
256
   if(alg_name == "HSS-LMS") {
194✔
257
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
258
   }
259
#endif
260

261
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
262
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
142✔
263
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
48✔
264
   }
265
#endif
266

267
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
268
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
117✔
269
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
86✔
270
   }
271
#endif
272

273
#if defined(BOTAN_HAS_CLASSICMCELIECE)
274
   if(alg_name.starts_with("ClassicMcEliece")) {
74✔
275
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
40✔
276
   }
277
#endif
278

279
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
108✔
280
}
21,567✔
281

282
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
4,964✔
283
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
284
   const std::string oid_str = alg_id.oid().to_formatted_string();
4,964✔
285
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
4,964✔
286
   std::string_view alg_name = alg_info[0];
4,964✔
287

288
#if defined(BOTAN_HAS_RSA)
289
   if(alg_name == "RSA") {
4,964✔
290
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
1,023✔
291
   }
292
#endif
293

294
#if defined(BOTAN_HAS_X25519)
295
   if(alg_name == "X25519" || alg_name == "Curve25519") {
3,987✔
296
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
297
   }
298
#endif
299

300
#if defined(BOTAN_HAS_X448)
301
   if(alg_name == "X448") {
3,913✔
302
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
303
   }
304
#endif
305

306
#if defined(BOTAN_HAS_ECDSA)
307
   if(alg_name == "ECDSA") {
3,907✔
308
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
4,078✔
309
   }
310
#endif
311

312
#if defined(BOTAN_HAS_ECDH)
313
   if(alg_name == "ECDH") {
1,569✔
314
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
210✔
315
   }
316
#endif
317

318
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
319
   if(alg_name == "DH") {
1,447✔
320
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
67✔
321
   }
322
#endif
323

324
#if defined(BOTAN_HAS_DSA)
325
   if(alg_name == "DSA") {
1,407✔
326
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
327
   }
328
#endif
329

330
#if defined(BOTAN_HAS_FRODOKEM)
331
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
1,095✔
332
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
333
   }
334
#endif
335

336
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
337
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
761✔
338
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
211✔
339
   }
340
#endif
341

342
#if defined(BOTAN_HAS_ML_KEM)
343
   if(alg_name.starts_with("ML-KEM-")) {
532✔
344
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
93✔
345
   }
346
#endif
347

348
#if defined(BOTAN_HAS_MCELIECE)
349
   if(alg_name == "McEliece") {
439✔
350
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
351
   }
352
#endif
353

354
#if defined(BOTAN_HAS_ECGDSA)
355
   if(alg_name == "ECGDSA") {
435✔
356
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
357
   }
358
#endif
359

360
#if defined(BOTAN_HAS_ECKCDSA)
361
   if(alg_name == "ECKCDSA") {
417✔
362
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
363
   }
364
#endif
365

366
#if defined(BOTAN_HAS_ED25519)
367
   if(alg_name == "Ed25519") {
399✔
368
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
369
   }
370
#endif
371

372
#if defined(BOTAN_HAS_ED448)
373
   if(alg_name == "Ed448") {
389✔
374
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
375
   }
376
#endif
377

378
#if defined(BOTAN_HAS_GOST_34_10_2001)
379
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
416✔
380
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
381
   }
382
#endif
383

384
#if defined(BOTAN_HAS_SM2)
385
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
393✔
386
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
387
   }
388
#endif
389

390
#if defined(BOTAN_HAS_ELGAMAL)
391
   if(alg_name == "ElGamal") {
339✔
392
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
393
   }
394
#endif
395

396
#if defined(BOTAN_HAS_XMSS_RFC8391)
397
   if(alg_name == "XMSS") {
325✔
398
      return std::make_unique<XMSS_PrivateKey>(key_bits);
19✔
399
   }
400
#endif
401

402
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
403
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
316✔
404
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
55✔
405
   }
406
#endif
407

408
#if defined(BOTAN_HAS_ML_DSA)
409
   if(alg_name.starts_with("ML-DSA-")) {
251✔
410
      return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
24✔
411
   }
412
#endif
413

414
#if defined(BOTAN_HAS_HSS_LMS)
415
   if(alg_name == "HSS-LMS-Private-Key") {
227✔
416
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
417
   }
418
#endif
419

420
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
421
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
221✔
422
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
72✔
423
   }
424
#endif
425

426
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
427
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
149✔
428
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
72✔
429
   }
430
#endif
431

432
#if defined(BOTAN_HAS_CLASSICMCELIECE)
433
   if(alg_name.starts_with("ClassicMcEliece")) {
77✔
434
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
28✔
435
   }
436
#endif
437

438
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
439
}
4,964✔
440

441
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
188✔
442
                                                   const EC_Group& ec_group,
443
                                                   RandomNumberGenerator& rng) {
444
   // Potentially unused if all EC algorithms are disabled
445
   BOTAN_UNUSED(alg_name, ec_group, rng);
188✔
446

447
#if defined(BOTAN_HAS_ECDSA)
448
   if(alg_name == "ECDSA") {
188✔
449
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
144✔
450
   }
451
#endif
452

453
#if defined(BOTAN_HAS_ECDH)
454
   if(alg_name == "ECDH") {
116✔
455
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
74✔
456
   }
457
#endif
458

459
#if defined(BOTAN_HAS_ECKCDSA)
460
   if(alg_name == "ECKCDSA") {
79✔
461
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
60✔
462
   }
463
#endif
464

465
#if defined(BOTAN_HAS_GOST_34_10_2001)
466
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
61✔
467
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
468
   }
469
#endif
470

471
#if defined(BOTAN_HAS_SM2)
472
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
46✔
473
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
16✔
474
   }
475
#endif
476

477
#if defined(BOTAN_HAS_ECGDSA)
478
   if(alg_name == "ECGDSA") {
29✔
479
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
58✔
480
   }
481
#endif
482

483
   return nullptr;
×
484
}
485

486
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,195✔
487
                                                RandomNumberGenerator& rng,
488
                                                std::string_view params,
489
                                                std::string_view provider) {
490
   /*
491
   * Default paramaters are chosen for work factor > 2**128 where possible
492
   */
493

494
#if defined(BOTAN_HAS_X25519)
495
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,453✔
496
      return std::make_unique<X25519_PrivateKey>(rng);
70✔
497
   }
498
#endif
499

500
#if defined(BOTAN_HAS_X448)
501
   if(alg_name == "X448") {
1,160✔
502
      return std::make_unique<X448_PrivateKey>(rng);
10✔
503
   }
504
#endif
505

506
#if defined(BOTAN_HAS_RSA)
507
   if(alg_name == "RSA") {
1,155✔
508
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
51✔
509
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
51✔
510
   }
511
#endif
512

513
#if defined(BOTAN_HAS_MCELIECE)
514
   if(alg_name == "McEliece") {
1,104✔
515
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
2✔
516
         if(params.empty()) {
2✔
517
            return {2960, 57};
×
518
         }
519

520
         const auto mce_params = split_on(params, ',');
2✔
521

522
         if(mce_params.size() != 2) {
2✔
523
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
524
         }
525

526
         const size_t mce_n = to_u32bit(mce_params[0]);
2✔
527
         const size_t mce_t = to_u32bit(mce_params[1]);
2✔
528
         return {mce_n, mce_t};
2✔
529
      }();
4✔
530

531
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
2✔
532
   }
533
#endif
534
#if defined(BOTAN_HAS_CLASSICMCELIECE)
535
   if(alg_name == "ClassicMcEliece") {
1,102✔
536
      auto cmce_params_set = params.empty() ? Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f
39✔
537
                                            : Classic_McEliece_Parameter_Set::from_string(params);
39✔
538
      return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
39✔
539
   }
540
#endif
541

542
#if defined(BOTAN_HAS_FRODOKEM)
543
   if(alg_name == "FrodoKEM") {
1,063✔
544
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
322✔
545
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
322✔
546
   }
547
#endif
548

549
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
550
   if(alg_name == "Kyber") {
741✔
551
      const auto mode = [&]() -> KyberMode {
543✔
552
         if(params.empty()) {
181✔
553
            return KyberMode::Kyber1024_R3;
1✔
554
         }
555
         return KyberMode(params);
180✔
556
      }();
181✔
557

558
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
181✔
559
   }
560
#endif
561

562
#if defined(BOTAN_HAS_ML_KEM)
563
   if(alg_name == "ML-KEM") {
560✔
564
      const auto mode = [&]() -> ML_KEM_Mode {
537✔
565
         if(params.empty()) {
179✔
566
            return ML_KEM_Mode::ML_KEM_768;
1✔
567
         }
568
         return ML_KEM_Mode(params);
178✔
569
      }();
179✔
570

571
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
179✔
572
   }
573
#endif
574

575
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
576
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
409✔
577
      const auto mode = [&]() -> DilithiumMode {
28✔
578
         if(params.empty()) {
28✔
579
            return DilithiumMode::Dilithium6x5;
580
         }
581
         return DilithiumMode(params);
20✔
582
      }();
28✔
583

584
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
28✔
585
   }
586
#endif
587

588
#if defined(BOTAN_HAS_ML_DSA)
589
   if(alg_name == "ML-DSA") {
353✔
590
      const auto mode = [&]() -> ML_DSA_Mode {
15✔
591
         if(params.empty()) {
15✔
592
            return ML_DSA_Mode::ML_DSA_6x5;
593
         }
594
         return ML_DSA_Mode(params);
7✔
595
      }();
15✔
596

597
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
15✔
598
   }
599
#endif
600

601
#if defined(BOTAN_HAS_HSS_LMS)
602
   if(alg_name == "HSS-LMS") {
338✔
603
      const auto hss_params = [&]() -> std::string {
45✔
604
         if(params.empty()) {
15✔
605
            return "SHA-256,HW(10,1)";
×
606
         } else {
607
            return std::string(params);
15✔
608
         }
609
      }();
15✔
610
      return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
15✔
611
   }
15✔
612
#endif
613

614
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
615
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
323✔
616
      auto sphincs_params = Sphincs_Parameters::create(params);
×
617

618
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
619
   }
620
#endif
621

622
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
623
   if(alg_name == "SLH-DSA") {
323✔
624
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
52✔
625

626
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
52✔
627
   }
628
#endif
629

630
#if defined(BOTAN_HAS_XMSS_RFC8391)
631
   if(alg_name == "XMSS") {
271✔
632
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
24✔
633
         if(params.empty()) {
8✔
634
            return XMSS_Parameters::XMSS_SHA2_10_512;
635
         }
636
         return XMSS_Parameters(params).oid();
14✔
637
      }();
8✔
638

639
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
8✔
640
   }
641
#endif
642

643
#if defined(BOTAN_HAS_ED25519)
644
   if(alg_name == "Ed25519") {
263✔
645
      return std::make_unique<Ed25519_PrivateKey>(rng);
42✔
646
   }
647
#endif
648

649
#if defined(BOTAN_HAS_ED448)
650
   if(alg_name == "Ed448") {
242✔
651
      return std::make_unique<Ed448_PrivateKey>(rng);
26✔
652
   }
653
#endif
654

655
   // ECC crypto
656
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
657

658
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
431✔
659
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
88✔
660
      alg_name == "GOST-34.10-2012-512") {
41✔
661
      const std::string group_id = [&]() -> std::string {
564✔
662
         if(!params.empty()) {
188✔
663
            return std::string(params);
179✔
664
         }
665
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
666
            return "sm2p256v1";
×
667
         }
668
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
669
            return "gost_256A";
×
670
         }
671
         if(alg_name == "GOST-34.10-2012-512") {
9✔
672
            return "gost_512A";
×
673
         }
674
         if(alg_name == "ECGDSA") {
9✔
675
            return "brainpool256r1";
×
676
         }
677
         return "secp256r1";
9✔
678
      }();
188✔
679

680
      if(EC_Group::supports_named_group(group_id)) {
188✔
681
         auto ec_group = EC_Group::from_name(group_id);
188✔
682
         return create_ec_private_key(alg_name, ec_group, rng);
188✔
683
      } else {
188✔
684
         return {};
×
685
      }
686
   }
188✔
687
#endif
688

689
   // DL crypto
690
#if defined(BOTAN_HAS_DL_GROUP)
691
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
82✔
692
      const std::string group_id = [&]() -> std::string {
123✔
693
         if(!params.empty()) {
41✔
694
            return std::string(params);
31✔
695
         }
696
         if(alg_name == "DSA") {
10✔
697
            return "dsa/botan/2048";
8✔
698
         }
699
         return "modp/ietf/2048";
2✔
700
      }();
41✔
701

702
      auto modp_group = DL_Group::from_name(group_id);
41✔
703

704
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
705
      if(alg_name == "DH") {
41✔
706
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
30✔
707
      }
708
   #endif
709

710
   #if defined(BOTAN_HAS_DSA)
711
      if(alg_name == "DSA") {
26✔
712
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
34✔
713
      }
714
   #endif
715

716
   #if defined(BOTAN_HAS_ELGAMAL)
717
      if(alg_name == "ElGamal") {
9✔
718
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
18✔
719
      }
720
   #endif
721
   }
41✔
722
#endif
723

724
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
725

726
   return std::unique_ptr<Private_Key>();
×
727
}
728

729
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
112✔
730
                                                    const std::vector<std::string>& possible) {
731
   std::vector<std::string> providers;
112✔
732

733
   for(auto&& prov : possible) {
560✔
734
      if(prov == "base") {
448✔
735
         providers.push_back(prov);
112✔
736
      }
737
   }
738

739
   BOTAN_UNUSED(alg_name);
112✔
740

741
   return providers;
112✔
742
}
×
743
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc