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

randombit / botan / 11380871009

17 Oct 2024 08:05AM UTC coverage: 91.125% (-0.001%) from 91.126%
11380871009

push

github

web-flow
Merge pull request #4382 from Rohde-Schwarz/pqc_sig_compat

ML-DSA, SLH-DSA: Provide Type Aliases (+ Small Test Fixes)

91011 of 99875 relevant lines covered (91.12%)

9323177.71 hits per line

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

94.89
/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_DSA)
18
   #include <botan/dsa.h>
19
#endif
20

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

81
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
82
   #include <botan/kyber.h>
83
#endif
84

85
#if defined(BOTAN_HAS_ML_KEM)
86
   #include <botan/ml_kem.h>
87
#endif
88

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

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

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

101
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
102
   #include <botan/dilithium.h>
103
#endif
104

105
#if defined(BOTAN_HAS_ML_DSA)
106
   #include <botan/ml_dsa.h>
107
#endif
108

109
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
110
   #include <botan/sphincsplus.h>
111
#endif
112

113
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
114
   #include <botan/slh_dsa.h>
115
#endif
116

117
namespace Botan {
118

119
std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
22,293✔
120
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
121
   const std::string oid_str = alg_id.oid().to_formatted_string();
22,293✔
122
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
22,293✔
123
   std::string_view alg_name = alg_info[0];
22,293✔
124

125
#if defined(BOTAN_HAS_RSA)
126
   if(alg_name == "RSA") {
22,293✔
127
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
32,021✔
128
   }
129
#endif
130

131
#if defined(BOTAN_HAS_X25519)
132
   if(alg_name == "X25519" || alg_name == "Curve25519") {
5,968✔
133
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
48✔
134
   }
135
#endif
136

137
#if defined(BOTAN_HAS_X448)
138
   if(alg_name == "X448") {
5,847✔
139
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
140
   }
141
#endif
142

143
#if defined(BOTAN_HAS_MCELIECE)
144
   if(alg_name == "McEliece") {
5,845✔
145
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
146
   }
147
#endif
148

149
#if defined(BOTAN_HAS_FRODOKEM)
150
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
5,845✔
151
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
152
   }
153
#endif
154

155
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
156
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
9,198✔
157
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
328✔
158
   }
159
#endif
160

161
#if defined(BOTAN_HAS_ML_KEM)
162
   if(alg_name.starts_with("ML-KEM-")) {
5,364✔
163
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
162✔
164
   }
165
#endif
166

167
#if defined(BOTAN_HAS_ECDSA)
168
   if(alg_name == "ECDSA") {
5,283✔
169
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
7,015✔
170
   }
171
#endif
172

173
#if defined(BOTAN_HAS_ECDH)
174
   if(alg_name == "ECDH") {
1,687✔
175
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
33✔
176
   }
177
#endif
178

179
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
180
   if(alg_name == "DH") {
1,670✔
181
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
11✔
182
   }
183
#endif
184

185
#if defined(BOTAN_HAS_DSA)
186
   if(alg_name == "DSA") {
1,662✔
187
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
188
   }
189
#endif
190

191
#if defined(BOTAN_HAS_ELGAMAL)
192
   if(alg_name == "ElGamal") {
1,428✔
193
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
194
   }
195
#endif
196

197
#if defined(BOTAN_HAS_ECGDSA)
198
   if(alg_name == "ECGDSA") {
1,424✔
199
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
146✔
200
   }
201
#endif
202

203
#if defined(BOTAN_HAS_ECKCDSA)
204
   if(alg_name == "ECKCDSA") {
1,351✔
205
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
144✔
206
   }
207
#endif
208

209
#if defined(BOTAN_HAS_ED25519)
210
   if(alg_name == "Ed25519") {
1,279✔
211
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,528✔
212
   }
213
#endif
214

215
#if defined(BOTAN_HAS_ED448)
216
   if(alg_name == "Ed448") {
515✔
217
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
146✔
218
   }
219
#endif
220

221
#if defined(BOTAN_HAS_GOST_34_10_2001)
222
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
574✔
223
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
132✔
224
   }
225
#endif
226

227
#if defined(BOTAN_HAS_SM2)
228
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
444✔
229
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
30✔
230
   }
231
#endif
232

233
#if defined(BOTAN_HAS_XMSS_RFC8391)
234
   if(alg_name == "XMSS") {
361✔
235
      return std::make_unique<XMSS_PublicKey>(key_bits);
88✔
236
   }
237
#endif
238

239
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
240
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
319✔
241
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
168✔
242
   }
243
#endif
244

245
#if defined(BOTAN_HAS_ML_DSA)
246
   if(alg_name.starts_with("ML-DSA-")) {
233✔
247
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
120✔
248
   }
249
#endif
250

251
#if defined(BOTAN_HAS_HSS_LMS)
252
   if(alg_name == "HSS-LMS") {
173✔
253
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
254
   }
255
#endif
256

257
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
258
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
121✔
259
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
48✔
260
   }
261
#endif
262

263
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
264
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
96✔
265
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
84✔
266
   }
267
#endif
268

269
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
108✔
270
}
22,293✔
271

272
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
4,861✔
273
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
274
   const std::string oid_str = alg_id.oid().to_formatted_string();
4,861✔
275
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
4,861✔
276
   std::string_view alg_name = alg_info[0];
4,861✔
277

278
#if defined(BOTAN_HAS_RSA)
279
   if(alg_name == "RSA") {
4,861✔
280
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
2,086✔
281
   }
282
#endif
283

284
#if defined(BOTAN_HAS_X25519)
285
   if(alg_name == "X25519" || alg_name == "Curve25519") {
2,821✔
286
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
287
   }
288
#endif
289

290
#if defined(BOTAN_HAS_X448)
291
   if(alg_name == "X448") {
2,747✔
292
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
293
   }
294
#endif
295

296
#if defined(BOTAN_HAS_ECDSA)
297
   if(alg_name == "ECDSA") {
2,741✔
298
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
1,528✔
299
   }
300
#endif
301

302
#if defined(BOTAN_HAS_ECDH)
303
   if(alg_name == "ECDH") {
1,541✔
304
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
184✔
305
   }
306
#endif
307

308
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
309
   if(alg_name == "DH") {
1,419✔
310
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
67✔
311
   }
312
#endif
313

314
#if defined(BOTAN_HAS_DSA)
315
   if(alg_name == "DSA") {
1,379✔
316
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
317
   }
318
#endif
319

320
#if defined(BOTAN_HAS_FRODOKEM)
321
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
1,067✔
322
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
323
   }
324
#endif
325

326
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
327
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
733✔
328
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
211✔
329
   }
330
#endif
331

332
#if defined(BOTAN_HAS_ML_KEM)
333
   if(alg_name.starts_with("ML-KEM-")) {
504✔
334
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
93✔
335
   }
336
#endif
337

338
#if defined(BOTAN_HAS_MCELIECE)
339
   if(alg_name == "McEliece") {
411✔
340
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
341
   }
342
#endif
343

344
#if defined(BOTAN_HAS_ECGDSA)
345
   if(alg_name == "ECGDSA") {
407✔
346
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
347
   }
348
#endif
349

350
#if defined(BOTAN_HAS_ECKCDSA)
351
   if(alg_name == "ECKCDSA") {
389✔
352
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
353
   }
354
#endif
355

356
#if defined(BOTAN_HAS_ED25519)
357
   if(alg_name == "Ed25519") {
371✔
358
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
359
   }
360
#endif
361

362
#if defined(BOTAN_HAS_ED448)
363
   if(alg_name == "Ed448") {
361✔
364
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
365
   }
366
#endif
367

368
#if defined(BOTAN_HAS_GOST_34_10_2001)
369
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
388✔
370
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
371
   }
372
#endif
373

374
#if defined(BOTAN_HAS_SM2)
375
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
365✔
376
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
377
   }
378
#endif
379

380
#if defined(BOTAN_HAS_ELGAMAL)
381
   if(alg_name == "ElGamal") {
311✔
382
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
383
   }
384
#endif
385

386
#if defined(BOTAN_HAS_XMSS_RFC8391)
387
   if(alg_name == "XMSS") {
297✔
388
      return std::make_unique<XMSS_PrivateKey>(key_bits);
19✔
389
   }
390
#endif
391

392
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
393
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
288✔
394
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
55✔
395
   }
396
#endif
397

398
#if defined(BOTAN_HAS_ML_DSA)
399
   if(alg_name.starts_with("ML-DSA-")) {
223✔
400
      return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
24✔
401
   }
402
#endif
403

404
#if defined(BOTAN_HAS_HSS_LMS)
405
   if(alg_name == "HSS-LMS-Private-Key") {
199✔
406
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
407
   }
408
#endif
409

410
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
411
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
193✔
412
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
72✔
413
   }
414
#endif
415

416
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
417
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
121✔
418
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
72✔
419
   }
420
#endif
421

422
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
423
}
4,861✔
424

425
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
157✔
426
                                                   const EC_Group& ec_group,
427
                                                   RandomNumberGenerator& rng) {
428
   // Potentially unused if all EC algorithms are disabled
429
   BOTAN_UNUSED(alg_name, ec_group, rng);
157✔
430

431
#if defined(BOTAN_HAS_ECDSA)
432
   if(alg_name == "ECDSA") {
157✔
433
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
144✔
434
   }
435
#endif
436

437
#if defined(BOTAN_HAS_ECDH)
438
   if(alg_name == "ECDH") {
85✔
439
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
58✔
440
   }
441
#endif
442

443
#if defined(BOTAN_HAS_ECKCDSA)
444
   if(alg_name == "ECKCDSA") {
56✔
445
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
36✔
446
   }
447
#endif
448

449
#if defined(BOTAN_HAS_GOST_34_10_2001)
450
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
50✔
451
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
452
   }
453
#endif
454

455
#if defined(BOTAN_HAS_SM2)
456
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
35✔
457
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
16✔
458
   }
459
#endif
460

461
#if defined(BOTAN_HAS_ECGDSA)
462
   if(alg_name == "ECGDSA") {
18✔
463
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
36✔
464
   }
465
#endif
466

467
   return nullptr;
×
468
}
469

470
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,048✔
471
                                                RandomNumberGenerator& rng,
472
                                                std::string_view params,
473
                                                std::string_view provider) {
474
   /*
475
   * Default paramaters are chosen for work factor > 2**128 where possible
476
   */
477

478
#if defined(BOTAN_HAS_X25519)
479
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,247✔
480
      return std::make_unique<X25519_PrivateKey>(rng);
16✔
481
   }
482
#endif
483

484
#if defined(BOTAN_HAS_X448)
485
   if(alg_name == "X448") {
1,040✔
486
      return std::make_unique<X448_PrivateKey>(rng);
10✔
487
   }
488
#endif
489

490
#if defined(BOTAN_HAS_RSA)
491
   if(alg_name == "RSA") {
1,035✔
492
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
51✔
493
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
51✔
494
   }
495
#endif
496

497
#if defined(BOTAN_HAS_MCELIECE)
498
   if(alg_name == "McEliece") {
984✔
499
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
2✔
500
         if(params.empty()) {
2✔
501
            return {2960, 57};
×
502
         }
503

504
         const auto mce_params = split_on(params, ',');
2✔
505

506
         if(mce_params.size() != 2) {
2✔
507
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
508
         }
509

510
         const size_t mce_n = to_u32bit(mce_params[0]);
2✔
511
         const size_t mce_t = to_u32bit(mce_params[1]);
2✔
512
         return {mce_n, mce_t};
2✔
513
      }();
4✔
514

515
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
2✔
516
   }
517
#endif
518

519
#if defined(BOTAN_HAS_FRODOKEM)
520
   if(alg_name == "FrodoKEM") {
982✔
521
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
322✔
522
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
322✔
523
   }
524
#endif
525

526
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
527
   if(alg_name == "Kyber") {
660✔
528
      const auto mode = [&]() -> KyberMode {
504✔
529
         if(params.empty()) {
168✔
530
            return KyberMode::Kyber1024_R3;
1✔
531
         }
532
         return KyberMode(params);
167✔
533
      }();
168✔
534

535
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
168✔
536
   }
537
#endif
538

539
#if defined(BOTAN_HAS_ML_KEM)
540
   if(alg_name == "ML-KEM") {
492✔
541
      const auto mode = [&]() -> ML_KEM_Mode {
474✔
542
         if(params.empty()) {
158✔
543
            return ML_KEM_Mode::ML_KEM_768;
1✔
544
         }
545
         return ML_KEM_Mode(params);
157✔
546
      }();
158✔
547

548
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
158✔
549
   }
550
#endif
551

552
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
553
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
359✔
554
      const auto mode = [&]() -> DilithiumMode {
25✔
555
         if(params.empty()) {
25✔
556
            return DilithiumMode::Dilithium6x5;
557
         }
558
         return DilithiumMode(params);
17✔
559
      }();
25✔
560

561
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
25✔
562
   }
563
#endif
564

565
#if defined(BOTAN_HAS_ML_DSA)
566
   if(alg_name == "ML-DSA") {
309✔
567
      const auto mode = [&]() -> ML_DSA_Mode {
15✔
568
         if(params.empty()) {
15✔
569
            return ML_DSA_Mode::ML_DSA_6x5;
570
         }
571
         return ML_DSA_Mode(params);
7✔
572
      }();
15✔
573

574
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
15✔
575
   }
576
#endif
577

578
#if defined(BOTAN_HAS_HSS_LMS)
579
   if(alg_name == "HSS-LMS") {
294✔
580
      return std::make_unique<HSS_LMS_PrivateKey>(rng, params);
15✔
581
   }
582
#endif
583

584
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
585
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
279✔
586
      auto sphincs_params = Sphincs_Parameters::create(params);
×
587

588
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
589
   }
590
#endif
591

592
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
593
   if(alg_name == "SLH-DSA") {
279✔
594
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
52✔
595

596
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
52✔
597
   }
598
#endif
599

600
#if defined(BOTAN_HAS_XMSS_RFC8391)
601
   if(alg_name == "XMSS") {
227✔
602
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
24✔
603
         if(params.empty()) {
8✔
604
            return XMSS_Parameters::XMSS_SHA2_10_512;
605
         }
606
         return XMSS_Parameters(params).oid();
14✔
607
      }();
8✔
608

609
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
8✔
610
   }
611
#endif
612

613
#if defined(BOTAN_HAS_ED25519)
614
   if(alg_name == "Ed25519") {
219✔
615
      return std::make_unique<Ed25519_PrivateKey>(rng);
26✔
616
   }
617
#endif
618

619
#if defined(BOTAN_HAS_ED448)
620
   if(alg_name == "Ed448") {
206✔
621
      return std::make_unique<Ed448_PrivateKey>(rng);
26✔
622
   }
623
#endif
624

625
   // ECC crypto
626
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
627

628
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
359✔
629
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
79✔
630
      alg_name == "GOST-34.10-2012-512") {
36✔
631
      const std::string group_id = [&]() -> std::string {
471✔
632
         if(!params.empty()) {
157✔
633
            return std::string(params);
148✔
634
         }
635
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
636
            return "sm2p256v1";
×
637
         }
638
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
639
            return "gost_256A";
×
640
         }
641
         if(alg_name == "GOST-34.10-2012-512") {
9✔
642
            return "gost_512A";
×
643
         }
644
         if(alg_name == "ECGDSA") {
9✔
645
            return "brainpool256r1";
×
646
         }
647
         return "secp256r1";
9✔
648
      }();
157✔
649

650
      auto ec_group = EC_Group::from_name(group_id);
157✔
651
      return create_ec_private_key(alg_name, ec_group, rng);
157✔
652
   }
157✔
653
#endif
654

655
   // DL crypto
656
#if defined(BOTAN_HAS_DL_GROUP)
657
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
72✔
658
      const std::string group_id = [&]() -> std::string {
108✔
659
         if(!params.empty()) {
36✔
660
            return std::string(params);
26✔
661
         }
662
         if(alg_name == "DSA") {
10✔
663
            return "dsa/botan/2048";
8✔
664
         }
665
         return "modp/ietf/2048";
2✔
666
      }();
36✔
667

668
      DL_Group modp_group(group_id);
36✔
669

670
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
671
      if(alg_name == "DH") {
36✔
672
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
30✔
673
      }
674
   #endif
675

676
   #if defined(BOTAN_HAS_DSA)
677
      if(alg_name == "DSA") {
21✔
678
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
28✔
679
      }
680
   #endif
681

682
   #if defined(BOTAN_HAS_ELGAMAL)
683
      if(alg_name == "ElGamal") {
7✔
684
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
14✔
685
      }
686
   #endif
687
   }
36✔
688
#endif
689

690
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
691

692
   return std::unique_ptr<Private_Key>();
×
693
}
694

695
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
110✔
696
                                                    const std::vector<std::string>& possible) {
697
   std::vector<std::string> providers;
110✔
698

699
   for(auto&& prov : possible) {
550✔
700
      if(prov == "base") {
440✔
701
         providers.push_back(prov);
110✔
702
      }
703
   }
704

705
   BOTAN_UNUSED(alg_name);
110✔
706

707
   return providers;
110✔
708
}
×
709
}  // 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