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

randombit / botan / 11346280461

15 Oct 2024 12:42PM UTC coverage: 91.116% (-0.4%) from 91.512%
11346280461

Pull #4291

github

web-flow
Merge bfb91307b into 41619a286
Pull Request #4291: PQC: SLH-DSA

90991 of 99863 relevant lines covered (91.12%)

9298501.65 hits per line

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

95.5
/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) || defined(BOTAN_HAS_ML_KEM)
82
   #include <botan/kyber.h>
83
#endif
84

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

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

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

97
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES) || defined(BOTAN_HAS_ML_DSA)
98
   #include <botan/dilithium.h>
99
#endif
100

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

105
namespace Botan {
106

107
std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
22,289✔
108
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
109
   const std::string oid_str = alg_id.oid().to_formatted_string();
22,289✔
110
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
22,289✔
111
   std::string_view alg_name = alg_info[0];
22,289✔
112

113
#if defined(BOTAN_HAS_RSA)
114
   if(alg_name == "RSA") {
22,289✔
115
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
32,021✔
116
   }
117
#endif
118

119
#if defined(BOTAN_HAS_X25519)
120
   if(alg_name == "X25519" || alg_name == "Curve25519") {
5,964✔
121
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
48✔
122
   }
123
#endif
124

125
#if defined(BOTAN_HAS_X448)
126
   if(alg_name == "X448") {
5,843✔
127
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
128
   }
129
#endif
130

131
#if defined(BOTAN_HAS_MCELIECE)
132
   if(alg_name == "McEliece") {
5,841✔
133
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
134
   }
135
#endif
136

137
#if defined(BOTAN_HAS_FRODOKEM)
138
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
5,841✔
139
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
140
   }
141
#endif
142

143
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S) || defined(BOTAN_HAS_ML_KEM)
144
   if(alg_name.starts_with("ML-KEM-") || alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
9,190✔
145
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
490✔
146
   }
147
#endif
148

149
#if defined(BOTAN_HAS_ECDSA)
150
   if(alg_name == "ECDSA") {
5,279✔
151
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
7,007✔
152
   }
153
#endif
154

155
#if defined(BOTAN_HAS_ECDH)
156
   if(alg_name == "ECDH") {
1,687✔
157
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
33✔
158
   }
159
#endif
160

161
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
162
   if(alg_name == "DH") {
1,670✔
163
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
11✔
164
   }
165
#endif
166

167
#if defined(BOTAN_HAS_DSA)
168
   if(alg_name == "DSA") {
1,662✔
169
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
170
   }
171
#endif
172

173
#if defined(BOTAN_HAS_ELGAMAL)
174
   if(alg_name == "ElGamal") {
1,428✔
175
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
176
   }
177
#endif
178

179
#if defined(BOTAN_HAS_ECGDSA)
180
   if(alg_name == "ECGDSA") {
1,424✔
181
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
146✔
182
   }
183
#endif
184

185
#if defined(BOTAN_HAS_ECKCDSA)
186
   if(alg_name == "ECKCDSA") {
1,351✔
187
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
144✔
188
   }
189
#endif
190

191
#if defined(BOTAN_HAS_ED25519)
192
   if(alg_name == "Ed25519") {
1,279✔
193
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,528✔
194
   }
195
#endif
196

197
#if defined(BOTAN_HAS_ED448)
198
   if(alg_name == "Ed448") {
515✔
199
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
146✔
200
   }
201
#endif
202

203
#if defined(BOTAN_HAS_GOST_34_10_2001)
204
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
574✔
205
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
132✔
206
   }
207
#endif
208

209
#if defined(BOTAN_HAS_SM2)
210
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
444✔
211
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
30✔
212
   }
213
#endif
214

215
#if defined(BOTAN_HAS_XMSS_RFC8391)
216
   if(alg_name == "XMSS") {
361✔
217
      return std::make_unique<XMSS_PublicKey>(key_bits);
88✔
218
   }
219
#endif
220

221
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES) || defined(BOTAN_HAS_ML_DSA)
222
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-") || alg_name.starts_with("ML-DSA-")) {
319✔
223
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
288✔
224
   }
225
#endif
226

227
#if defined(BOTAN_HAS_HSS_LMS)
228
   if(alg_name == "HSS-LMS") {
173✔
229
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
230
   }
231
#endif
232

233
#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
234
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-") || alg_name.starts_with("SLH-DSA-") ||
175✔
235
      alg_name.starts_with("Hash-SLH-DSA-")) {
54✔
236
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
132✔
237
   }
238
#endif
239

240
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
108✔
241
}
22,289✔
242

243
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
4,861✔
244
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
245
   const std::string oid_str = alg_id.oid().to_formatted_string();
4,861✔
246
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
4,861✔
247
   std::string_view alg_name = alg_info[0];
4,861✔
248

249
#if defined(BOTAN_HAS_RSA)
250
   if(alg_name == "RSA") {
4,861✔
251
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
2,086✔
252
   }
253
#endif
254

255
#if defined(BOTAN_HAS_X25519)
256
   if(alg_name == "X25519" || alg_name == "Curve25519") {
2,821✔
257
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
258
   }
259
#endif
260

261
#if defined(BOTAN_HAS_X448)
262
   if(alg_name == "X448") {
2,747✔
263
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
264
   }
265
#endif
266

267
#if defined(BOTAN_HAS_ECDSA)
268
   if(alg_name == "ECDSA") {
2,741✔
269
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
1,528✔
270
   }
271
#endif
272

273
#if defined(BOTAN_HAS_ECDH)
274
   if(alg_name == "ECDH") {
1,541✔
275
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
184✔
276
   }
277
#endif
278

279
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
280
   if(alg_name == "DH") {
1,419✔
281
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
67✔
282
   }
283
#endif
284

285
#if defined(BOTAN_HAS_DSA)
286
   if(alg_name == "DSA") {
1,379✔
287
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
288
   }
289
#endif
290

291
#if defined(BOTAN_HAS_FRODOKEM)
292
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
1,067✔
293
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
294
   }
295
#endif
296

297
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S) || defined(BOTAN_HAS_ML_KEM)
298
   if(alg_name.starts_with("ML-KEM-") || alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
733✔
299
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
304✔
300
   }
301
#endif
302

303
#if defined(BOTAN_HAS_MCELIECE)
304
   if(alg_name == "McEliece") {
411✔
305
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
306
   }
307
#endif
308

309
#if defined(BOTAN_HAS_ECGDSA)
310
   if(alg_name == "ECGDSA") {
407✔
311
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
312
   }
313
#endif
314

315
#if defined(BOTAN_HAS_ECKCDSA)
316
   if(alg_name == "ECKCDSA") {
389✔
317
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
318
   }
319
#endif
320

321
#if defined(BOTAN_HAS_ED25519)
322
   if(alg_name == "Ed25519") {
371✔
323
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
324
   }
325
#endif
326

327
#if defined(BOTAN_HAS_ED448)
328
   if(alg_name == "Ed448") {
361✔
329
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
330
   }
331
#endif
332

333
#if defined(BOTAN_HAS_GOST_34_10_2001)
334
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
388✔
335
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
336
   }
337
#endif
338

339
#if defined(BOTAN_HAS_SM2)
340
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
365✔
341
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
342
   }
343
#endif
344

345
#if defined(BOTAN_HAS_ELGAMAL)
346
   if(alg_name == "ElGamal") {
311✔
347
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
348
   }
349
#endif
350

351
#if defined(BOTAN_HAS_XMSS_RFC8391)
352
   if(alg_name == "XMSS") {
297✔
353
      return std::make_unique<XMSS_PrivateKey>(key_bits);
19✔
354
   }
355
#endif
356

357
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES) || defined(BOTAN_HAS_ML_DSA)
358
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-") || alg_name.starts_with("ML-DSA-")) {
288✔
359
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
79✔
360
   }
361
#endif
362

363
#if defined(BOTAN_HAS_HSS_LMS)
364
   if(alg_name == "HSS-LMS-Private-Key") {
199✔
365
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
366
   }
367
#endif
368

369
#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
370
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-") || alg_name.starts_with("SLH-DSA-") ||
242✔
371
      alg_name.starts_with("Hash-SLH-DSA-")) {
49✔
372
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
144✔
373
   }
374
#endif
375

376
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
377
}
4,861✔
378

379
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
157✔
380
                                                   const EC_Group& ec_group,
381
                                                   RandomNumberGenerator& rng) {
382
   // Potentially unused if all EC algorithms are disabled
383
   BOTAN_UNUSED(alg_name, ec_group, rng);
157✔
384

385
#if defined(BOTAN_HAS_ECDSA)
386
   if(alg_name == "ECDSA") {
157✔
387
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
144✔
388
   }
389
#endif
390

391
#if defined(BOTAN_HAS_ECDH)
392
   if(alg_name == "ECDH") {
85✔
393
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
58✔
394
   }
395
#endif
396

397
#if defined(BOTAN_HAS_ECKCDSA)
398
   if(alg_name == "ECKCDSA") {
56✔
399
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
36✔
400
   }
401
#endif
402

403
#if defined(BOTAN_HAS_GOST_34_10_2001)
404
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
50✔
405
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
406
   }
407
#endif
408

409
#if defined(BOTAN_HAS_SM2)
410
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
35✔
411
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
16✔
412
   }
413
#endif
414

415
#if defined(BOTAN_HAS_ECGDSA)
416
   if(alg_name == "ECGDSA") {
18✔
417
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
36✔
418
   }
419
#endif
420

421
   return nullptr;
×
422
}
423

424
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,051✔
425
                                                RandomNumberGenerator& rng,
426
                                                std::string_view params,
427
                                                std::string_view provider) {
428
   /*
429
   * Default paramaters are chosen for work factor > 2**128 where possible
430
   */
431

432
#if defined(BOTAN_HAS_X25519)
433
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,250✔
434
      return std::make_unique<X25519_PrivateKey>(rng);
16✔
435
   }
436
#endif
437

438
#if defined(BOTAN_HAS_X448)
439
   if(alg_name == "X448") {
1,043✔
440
      return std::make_unique<X448_PrivateKey>(rng);
10✔
441
   }
442
#endif
443

444
#if defined(BOTAN_HAS_RSA)
445
   if(alg_name == "RSA") {
1,038✔
446
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
51✔
447
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
51✔
448
   }
449
#endif
450

451
#if defined(BOTAN_HAS_MCELIECE)
452
   if(alg_name == "McEliece") {
987✔
453
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
2✔
454
         if(params.empty()) {
2✔
455
            return {2960, 57};
×
456
         }
457

458
         const auto mce_params = split_on(params, ',');
2✔
459

460
         if(mce_params.size() != 2) {
2✔
461
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
462
         }
463

464
         const size_t mce_n = to_u32bit(mce_params[0]);
2✔
465
         const size_t mce_t = to_u32bit(mce_params[1]);
2✔
466
         return {mce_n, mce_t};
2✔
467
      }();
4✔
468

469
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
2✔
470
   }
471
#endif
472

473
#if defined(BOTAN_HAS_FRODOKEM)
474
   if(alg_name == "FrodoKEM") {
985✔
475
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
322✔
476
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
322✔
477
   }
478
#endif
479

480
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
481
   if(alg_name == "Kyber") {
663✔
482
      const auto mode = [&]() -> KyberMode {
513✔
483
         if(params.empty()) {
171✔
484
            return KyberMode::Kyber1024_R3;
1✔
485
         }
486
         return KyberMode(params);
170✔
487
      }();
171✔
488

489
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
171✔
490
   }
491
#endif
492

493
#if defined(BOTAN_HAS_ML_KEM)
494
   if(alg_name == "ML-KEM") {
492✔
495
      const auto mode = [&]() -> KyberMode {
474✔
496
         if(params.empty()) {
158✔
497
            return KyberMode::ML_KEM_768;
1✔
498
         }
499
         return KyberMode(params);
157✔
500
      }();
158✔
501

502
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
158✔
503
   }
504
#endif
505

506
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
507
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
359✔
508
      const auto mode = [&]() -> DilithiumMode {
25✔
509
         if(params.empty()) {
25✔
510
            return DilithiumMode::Dilithium6x5;
511
         }
512
         return DilithiumMode(params);
17✔
513
      }();
25✔
514

515
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
25✔
516
   }
517
#endif
518

519
#if defined(BOTAN_HAS_ML_DSA)
520
   if(alg_name == "ML-DSA") {
309✔
521
      const auto mode = [&]() -> DilithiumMode {
15✔
522
         if(params.empty()) {
15✔
523
            return DilithiumMode::ML_DSA_6x5;
524
         }
525
         return DilithiumMode(params);
7✔
526
      }();
15✔
527

528
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
15✔
529
   }
530
#endif
531

532
#if defined(BOTAN_HAS_HSS_LMS)
533
   if(alg_name == "HSS-LMS") {
294✔
534
      return std::make_unique<HSS_LMS_PrivateKey>(rng, params);
15✔
535
   }
536
#endif
537

538
#if defined(BOTAN_HAS_SPHINCS_PLUS_COMMON)
539
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus" || alg_name == "SLH-DSA") {
331✔
540
      auto sphincs_params = Sphincs_Parameters::create(params);
52✔
541

542
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
52✔
543
   }
544
#endif
545

546
#if defined(BOTAN_HAS_XMSS_RFC8391)
547
   if(alg_name == "XMSS") {
227✔
548
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
24✔
549
         if(params.empty()) {
8✔
550
            return XMSS_Parameters::XMSS_SHA2_10_512;
551
         }
552
         return XMSS_Parameters(params).oid();
14✔
553
      }();
8✔
554

555
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
8✔
556
   }
557
#endif
558

559
#if defined(BOTAN_HAS_ED25519)
560
   if(alg_name == "Ed25519") {
219✔
561
      return std::make_unique<Ed25519_PrivateKey>(rng);
26✔
562
   }
563
#endif
564

565
#if defined(BOTAN_HAS_ED448)
566
   if(alg_name == "Ed448") {
206✔
567
      return std::make_unique<Ed448_PrivateKey>(rng);
26✔
568
   }
569
#endif
570

571
   // ECC crypto
572
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
573

574
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
359✔
575
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
79✔
576
      alg_name == "GOST-34.10-2012-512") {
36✔
577
      const std::string group_id = [&]() -> std::string {
471✔
578
         if(!params.empty()) {
157✔
579
            return std::string(params);
148✔
580
         }
581
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
582
            return "sm2p256v1";
×
583
         }
584
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
585
            return "gost_256A";
×
586
         }
587
         if(alg_name == "GOST-34.10-2012-512") {
9✔
588
            return "gost_512A";
×
589
         }
590
         if(alg_name == "ECGDSA") {
9✔
591
            return "brainpool256r1";
×
592
         }
593
         return "secp256r1";
9✔
594
      }();
157✔
595

596
      auto ec_group = EC_Group::from_name(group_id);
157✔
597
      return create_ec_private_key(alg_name, ec_group, rng);
157✔
598
   }
157✔
599
#endif
600

601
   // DL crypto
602
#if defined(BOTAN_HAS_DL_GROUP)
603
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
72✔
604
      const std::string group_id = [&]() -> std::string {
108✔
605
         if(!params.empty()) {
36✔
606
            return std::string(params);
26✔
607
         }
608
         if(alg_name == "DSA") {
10✔
609
            return "dsa/botan/2048";
8✔
610
         }
611
         return "modp/ietf/2048";
2✔
612
      }();
36✔
613

614
      DL_Group modp_group(group_id);
36✔
615

616
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
617
      if(alg_name == "DH") {
36✔
618
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
30✔
619
      }
620
   #endif
621

622
   #if defined(BOTAN_HAS_DSA)
623
      if(alg_name == "DSA") {
21✔
624
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
28✔
625
      }
626
   #endif
627

628
   #if defined(BOTAN_HAS_ELGAMAL)
629
      if(alg_name == "ElGamal") {
7✔
630
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
14✔
631
      }
632
   #endif
633
   }
36✔
634
#endif
635

636
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
637

638
   return std::unique_ptr<Private_Key>();
×
639
}
640

641
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
110✔
642
                                                    const std::vector<std::string>& possible) {
643
   std::vector<std::string> providers;
110✔
644

645
   for(auto&& prov : possible) {
550✔
646
      if(prov == "base") {
440✔
647
         providers.push_back(prov);
110✔
648
      }
649
   }
650

651
   BOTAN_UNUSED(alg_name);
110✔
652

653
   return providers;
110✔
654
}
×
655
}  // 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