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

randombit / botan / 28311706783

27 Jun 2026 04:51PM UTC coverage: 89.346% (-0.006%) from 89.352%
28311706783

push

github

web-flow
Merge pull request #5703 from randombit/jack/alg-id-param-validation

Validate AlgorithmIdentifier parameters on decode

112110 of 125479 relevant lines covered (89.35%)

10963156.46 hits per line

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

92.42
/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/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,
19,728✔
131
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
132
   const std::string alg_name = [&]() -> std::string {
59,184✔
133
      if(const auto name = alg_id.oid().registered_name()) {
19,728✔
134
         const std::vector<std::string> alg_info = split_on(*name, '/');
19,728✔
135
         if(!alg_info.empty()) {
19,728✔
136
            return alg_info[0];
19,728✔
137
         }
138
      }
39,456✔
139

140
      throw Decoding_Error(
×
141
         fmt("Public key decoding failed, no algorithm associated with {}", alg_id.oid().to_string()));
×
142
   }();
19,728✔
143

144
#if defined(BOTAN_HAS_RSA)
145
   if(alg_name == "RSA") {
19,728✔
146
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
23,641✔
147
   }
148
#endif
149

150
#if defined(BOTAN_HAS_X25519)
151
   if(alg_name == "X25519" || alg_name == "Curve25519") {
7,886✔
152
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
78✔
153
   }
154
#endif
155

156
#if defined(BOTAN_HAS_X448)
157
   if(alg_name == "X448") {
7,847✔
158
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
159
   }
160
#endif
161

162
#if defined(BOTAN_HAS_MCELIECE)
163
   if(alg_name == "McEliece") {
7,845✔
164
      return std::make_unique<McEliece_PublicKey>(alg_id, key_bits);
2✔
165
   }
166
#endif
167

168
#if defined(BOTAN_HAS_FRODOKEM)
169
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
23,374✔
170
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
171
   }
172
#endif
173

174
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
175
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
15,056✔
176
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
324✔
177
   }
178
#endif
179

180
#if defined(BOTAN_HAS_ML_KEM)
181
   if(alg_name.starts_with("ML-KEM-")) {
7,366✔
182
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
197✔
183
   }
184
#endif
185

186
#if defined(BOTAN_HAS_ECDSA)
187
   if(alg_name == "ECDSA") {
7,267✔
188
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
11,641✔
189
   }
190
#endif
191

192
#if defined(BOTAN_HAS_ECDH)
193
   if(alg_name == "ECDH") {
1,428✔
194
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
34✔
195
   }
196
#endif
197

198
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
199
   if(alg_name == "DH") {
1,411✔
200
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
4✔
201
   }
202
#endif
203

204
#if defined(BOTAN_HAS_DSA)
205
   if(alg_name == "DSA") {
1,409✔
206
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
148✔
207
   }
208
#endif
209

210
#if defined(BOTAN_HAS_ELGAMAL)
211
   if(alg_name == "ElGamal") {
1,335✔
212
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
213
   }
214
#endif
215

216
#if defined(BOTAN_HAS_ECGDSA)
217
   if(alg_name == "ECGDSA") {
1,331✔
218
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
134✔
219
   }
220
#endif
221

222
#if defined(BOTAN_HAS_ECKCDSA)
223
   if(alg_name == "ECKCDSA") {
1,264✔
224
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
132✔
225
   }
226
#endif
227

228
#if defined(BOTAN_HAS_ED25519)
229
   if(alg_name == "Ed25519") {
1,198✔
230
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,516✔
231
   }
232
#endif
233

234
#if defined(BOTAN_HAS_ED448)
235
   if(alg_name == "Ed448") {
440✔
236
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
134✔
237
   }
238
#endif
239

240
#if defined(BOTAN_HAS_GOST_34_10_2001)
241
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
373✔
242
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
116✔
243
   }
244
#endif
245

246
#if defined(BOTAN_HAS_SM2)
247
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
315✔
248
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
30✔
249
   }
250
#endif
251

252
#if defined(BOTAN_HAS_XMSS_RFC8391)
253
   if(alg_name == "XMSS") {
300✔
254
      return std::make_unique<XMSS_PublicKey>(alg_id, key_bits);
68✔
255
   }
256
#endif
257

258
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
259
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
532✔
260
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
156✔
261
   }
262
#endif
263

264
#if defined(BOTAN_HAS_ML_DSA)
265
   if(alg_name.starts_with("ML-DSA-")) {
188✔
266
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
108✔
267
   }
268
#endif
269

270
#if defined(BOTAN_HAS_HSS_LMS)
271
   if(alg_name == "HSS-LMS") {
134✔
272
      return std::make_unique<HSS_LMS_PublicKey>(alg_id, key_bits);
94✔
273
   }
274
#endif
275

276
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
277
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
174✔
278
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
48✔
279
   }
280
#endif
281

282
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
283
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
83✔
284
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
86✔
285
   }
286
#endif
287

288
#if defined(BOTAN_HAS_CLASSICMCELIECE)
289
   if(alg_name.starts_with("ClassicMcEliece")) {
20✔
290
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
121✔
291
   }
292
#endif
293

294
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
×
295
}
19,647✔
296

297
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
3,938✔
298
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
299
   const std::string alg_name = [&]() -> std::string {
11,814✔
300
      if(const auto name = alg_id.oid().registered_name()) {
3,938✔
301
         const std::vector<std::string> alg_info = split_on(*name, '/');
3,938✔
302
         if(!alg_info.empty()) {
3,938✔
303
            return alg_info[0];
3,938✔
304
         }
305
      }
7,876✔
306

307
      throw Decoding_Error(
×
308
         fmt("Private key decoding failed, no algorithm associated with {}", alg_id.oid().to_string()));
×
309
   }();
3,938✔
310

311
#if defined(BOTAN_HAS_RSA)
312
   if(alg_name == "RSA") {
3,938✔
313
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
1,107✔
314
   }
315
#endif
316

317
#if defined(BOTAN_HAS_X25519)
318
   if(alg_name == "X25519" || alg_name == "Curve25519") {
2,831✔
319
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
320
   }
321
#endif
322

323
#if defined(BOTAN_HAS_X448)
324
   if(alg_name == "X448") {
2,803✔
325
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
326
   }
327
#endif
328

329
#if defined(BOTAN_HAS_ECDSA)
330
   if(alg_name == "ECDSA") {
2,797✔
331
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
3,179✔
332
   }
333
#endif
334

335
#if defined(BOTAN_HAS_ECDH)
336
   if(alg_name == "ECDH") {
1,173✔
337
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
140✔
338
   }
339
#endif
340

341
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
342
   if(alg_name == "DH") {
1,103✔
343
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
66✔
344
   }
345
#endif
346

347
#if defined(BOTAN_HAS_DSA)
348
   if(alg_name == "DSA") {
1,070✔
349
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
47✔
350
   }
351
#endif
352

353
#if defined(BOTAN_HAS_FRODOKEM)
354
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
2,952✔
355
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
356
   }
357
#endif
358

359
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
360
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
1,388✔
361
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
219✔
362
   }
363
#endif
364

365
#if defined(BOTAN_HAS_ML_KEM)
366
   if(alg_name.starts_with("ML-KEM-")) {
475✔
367
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
93✔
368
   }
369
#endif
370

371
#if defined(BOTAN_HAS_MCELIECE)
372
   if(alg_name == "McEliece") {
382✔
373
      return std::make_unique<McEliece_PrivateKey>(alg_id, key_bits);
4✔
374
   }
375
#endif
376

377
#if defined(BOTAN_HAS_ECGDSA)
378
   if(alg_name == "ECGDSA") {
378✔
379
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
380
   }
381
#endif
382

383
#if defined(BOTAN_HAS_ECKCDSA)
384
   if(alg_name == "ECKCDSA") {
360✔
385
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
386
   }
387
#endif
388

389
#if defined(BOTAN_HAS_ED25519)
390
   if(alg_name == "Ed25519") {
342✔
391
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
16✔
392
   }
393
#endif
394

395
#if defined(BOTAN_HAS_ED448)
396
   if(alg_name == "Ed448") {
333✔
397
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
398
   }
399
#endif
400

401
#if defined(BOTAN_HAS_GOST_34_10_2001)
402
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
315✔
403
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
404
   }
405
#endif
406

407
#if defined(BOTAN_HAS_SM2)
408
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
303✔
409
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
410
   }
411
#endif
412

413
#if defined(BOTAN_HAS_ELGAMAL)
414
   if(alg_name == "ElGamal") {
283✔
415
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
416
   }
417
#endif
418

419
#if defined(BOTAN_HAS_XMSS_RFC8391)
420
   if(alg_name == "XMSS") {
269✔
421
      return std::make_unique<XMSS_PrivateKey>(alg_id, key_bits);
12✔
422
   }
423
#endif
424

425
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
426
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
514✔
427
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
55✔
428
   }
429
#endif
430

431
#if defined(BOTAN_HAS_ML_DSA)
432
   if(alg_name.starts_with("ML-DSA-")) {
202✔
433
      return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
24✔
434
   }
435
#endif
436

437
#if defined(BOTAN_HAS_HSS_LMS)
438
   if(alg_name == "HSS-LMS-Private-Key") {
178✔
439
      return std::make_unique<HSS_LMS_PrivateKey>(alg_id, key_bits);
6✔
440
   }
441
#endif
442

443
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
444
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
344✔
445
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
72✔
446
   }
447
#endif
448

449
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
450
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
128✔
451
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
72✔
452
   }
453
#endif
454

455
#if defined(BOTAN_HAS_CLASSICMCELIECE)
456
   if(alg_name.starts_with("ClassicMcEliece")) {
28✔
457
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
117✔
458
   }
459
#endif
460

461
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
×
462
}
3,849✔
463

464
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
422✔
465
                                                   const EC_Group& ec_group,
466
                                                   RandomNumberGenerator& rng) {
467
   // Potentially unused if all EC algorithms are disabled
468
   BOTAN_UNUSED(alg_name, ec_group, rng);
422✔
469

470
#if defined(BOTAN_HAS_ECDSA)
471
   if(alg_name == "ECDSA") {
422✔
472
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
476✔
473
   }
474
#endif
475

476
#if defined(BOTAN_HAS_ECDH)
477
   if(alg_name == "ECDH") {
184✔
478
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
112✔
479
   }
480
#endif
481

482
#if defined(BOTAN_HAS_ECKCDSA)
483
   if(alg_name == "ECKCDSA") {
128✔
484
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
96✔
485
   }
486
#endif
487

488
#if defined(BOTAN_HAS_GOST_34_10_2001)
489
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
92✔
490
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
491
   }
492
#endif
493

494
#if defined(BOTAN_HAS_SM2)
495
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
89✔
496
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
40✔
497
   }
498
#endif
499

500
#if defined(BOTAN_HAS_ECGDSA)
501
   if(alg_name == "ECGDSA") {
48✔
502
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
96✔
503
   }
504
#endif
505

506
   return nullptr;
×
507
}
508

509
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
3,494✔
510
                                                RandomNumberGenerator& rng,
511
                                                std::string_view params,
512
                                                std::string_view provider) {
513
   /*
514
   * Default parameters are chosen for work factor > 2**128 where possible
515
   */
516

517
#if defined(BOTAN_HAS_X25519)
518
   if(alg_name == "X25519" || alg_name == "Curve25519") {
5,768✔
519
      return std::make_unique<X25519_PrivateKey>(rng);
2,064✔
520
   }
521
#endif
522

523
#if defined(BOTAN_HAS_X448)
524
   if(alg_name == "X448") {
2,462✔
525
      return std::make_unique<X448_PrivateKey>(rng);
36✔
526
   }
527
#endif
528

529
#if defined(BOTAN_HAS_RSA)
530
   if(alg_name == "RSA") {
2,444✔
531
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
55✔
532
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
55✔
533
   }
534
#endif
535

536
#if defined(BOTAN_HAS_MCELIECE)
537
   if(alg_name == "McEliece") {
2,389✔
538
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
3✔
539
         if(params.empty()) {
3✔
540
            return {2960, 57};
×
541
         }
542

543
         const auto mce_params = split_on(params, ',');
3✔
544

545
         if(mce_params.size() != 2) {
3✔
546
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
547
         }
548

549
         const size_t mce_n = to_u32bit(mce_params[0]);
3✔
550
         const size_t mce_t = to_u32bit(mce_params[1]);
3✔
551
         return {mce_n, mce_t};
3✔
552
      }();
6✔
553

554
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
3✔
555
   }
556
#endif
557
#if defined(BOTAN_HAS_CLASSICMCELIECE)
558
   if(alg_name == "ClassicMcEliece") {
2,386✔
559
      auto cmce_params_set = params.empty() ? Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f
51✔
560
                                            : Classic_McEliece_Parameter_Set::from_string(params);
51✔
561
      return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
51✔
562
   }
563
#endif
564

565
#if defined(BOTAN_HAS_FRODOKEM)
566
   if(alg_name == "FrodoKEM") {
2,335✔
567
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
324✔
568
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
324✔
569
   }
570
#endif
571

572
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
573
   if(alg_name == "Kyber") {
2,011✔
574
      const auto mode = [&]() -> KyberMode {
483✔
575
         if(params.empty()) {
161✔
576
            return KyberMode::Kyber1024_R3;
1✔
577
         }
578
         return KyberMode(params);
160✔
579
      }();
161✔
580

581
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
161✔
582
   }
583
#endif
584

585
#if defined(BOTAN_HAS_ML_KEM)
586
   if(alg_name == "ML-KEM") {
1,850✔
587
      const auto mode = [&]() -> ML_KEM_Mode {
3,522✔
588
         if(params.empty()) {
1,174✔
589
            return ML_KEM_Mode::ML_KEM_768;
1✔
590
         }
591
         return ML_KEM_Mode(params);
1,173✔
592
      }();
1,174✔
593

594
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
1,174✔
595
   }
596
#endif
597

598
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
599
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
697✔
600
      const auto mode = [&]() -> DilithiumMode {
21✔
601
         if(params.empty()) {
21✔
602
            return DilithiumMode::Dilithium6x5;
603
         }
604
         return DilithiumMode(params);
13✔
605
      }();
21✔
606

607
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
21✔
608
   }
609
#endif
610

611
#if defined(BOTAN_HAS_ML_DSA)
612
   if(alg_name == "ML-DSA") {
655✔
613
      const auto mode = [&]() -> ML_DSA_Mode {
20✔
614
         if(params.empty()) {
20✔
615
            return ML_DSA_Mode::ML_DSA_6x5;
616
         }
617
         return ML_DSA_Mode(params);
12✔
618
      }();
20✔
619

620
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
20✔
621
   }
622
#endif
623

624
#if defined(BOTAN_HAS_HSS_LMS)
625
   if(alg_name == "HSS-LMS") {
635✔
626
      const auto hss_params = [&]() -> std::string {
81✔
627
         if(params.empty()) {
27✔
628
            return "SHA-256,HW(10,1)";
×
629
         } else {
630
            return std::string(params);
27✔
631
         }
632
      }();
27✔
633
      return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
27✔
634
   }
27✔
635
#endif
636

637
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
638
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
608✔
639
      auto sphincs_params = Sphincs_Parameters::create(params);
×
640

641
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
642
   }
643
#endif
644

645
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
646
   if(alg_name == "SLH-DSA") {
608✔
647
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
52✔
648

649
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
52✔
650
   }
651
#endif
652

653
#if defined(BOTAN_HAS_XMSS_RFC8391)
654
   if(alg_name == "XMSS") {
556✔
655
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
6✔
656
         if(params.empty()) {
6✔
657
            return XMSS_Parameters::XMSS_SHA2_10_512;
658
         }
659
         return XMSS_Parameters::from_name(params).oid();
6✔
660
      }();
6✔
661

662
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
6✔
663
   }
664
#endif
665

666
#if defined(BOTAN_HAS_ED25519)
667
   if(alg_name == "Ed25519") {
550✔
668
      return std::make_unique<Ed25519_PrivateKey>(rng);
72✔
669
   }
670
#endif
671

672
#if defined(BOTAN_HAS_ED448)
673
   if(alg_name == "Ed448") {
514✔
674
      return std::make_unique<Ed448_PrivateKey>(rng);
50✔
675
   }
676
#endif
677

678
   // ECC crypto
679
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
680

681
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
938✔
682
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
124✔
683
      alg_name == "GOST-34.10-2012-512") {
71✔
684
      const std::string group_id = [&]() -> std::string {
1,254✔
685
         if(!params.empty()) {
418✔
686
            return std::string(params);
409✔
687
         }
688
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
689
            return "sm2p256v1";
×
690
         }
691
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
692
            return "gost_256A";
×
693
         }
694
         if(alg_name == "GOST-34.10-2012-512") {
9✔
695
            return "gost_512A";
×
696
         }
697
         if(alg_name == "ECGDSA") {
9✔
698
            return "brainpool256r1";
×
699
         }
700
         return "secp256r1";
9✔
701
      }();
418✔
702

703
      if(EC_Group::supports_named_group(group_id)) {
418✔
704
         auto ec_group = EC_Group::from_name(group_id);
418✔
705
         return create_ec_private_key(alg_name, ec_group, rng);
418✔
706
      } else {
418✔
707
         return {};
×
708
      }
709
   }
418✔
710
#endif
711

712
   // DL crypto
713
#if defined(BOTAN_HAS_DL_GROUP)
714
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
142✔
715
      const std::string group_id = [&]() -> std::string {
213✔
716
         if(!params.empty()) {
71✔
717
            return std::string(params);
61✔
718
         }
719
         if(alg_name == "DSA") {
10✔
720
            return "dsa/botan/2048";
8✔
721
         }
722
         return "modp/ietf/2048";
2✔
723
      }();
71✔
724

725
      auto modp_group = DL_Group::from_name(group_id);
71✔
726

727
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
728
      if(alg_name == "DH") {
71✔
729
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
56✔
730
      }
731
   #endif
732

733
   #if defined(BOTAN_HAS_DSA)
734
      if(alg_name == "DSA") {
43✔
735
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
62✔
736
      }
737
   #endif
738

739
   #if defined(BOTAN_HAS_ELGAMAL)
740
      if(alg_name == "ElGamal") {
12✔
741
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
24✔
742
      }
743
   #endif
744
   }
71✔
745
#endif
746

747
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
748

749
   return std::unique_ptr<Private_Key>();
×
750
}
751

752
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
112✔
753
                                                    const std::vector<std::string>& possible) {
754
   std::vector<std::string> providers;
112✔
755

756
   for(auto&& prov : possible) {
560✔
757
      if(prov == "base") {
448✔
758
         providers.push_back(prov);
112✔
759
      }
760
   }
761

762
   BOTAN_UNUSED(alg_name);
112✔
763

764
   return providers;
112✔
765
}
×
766
}  // 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