/src/botan/src/lib/pubkey/pk_algs.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include <botan/internal/parsing.h> |
10 | | |
11 | | #if defined(BOTAN_HAS_RSA) |
12 | | #include <botan/rsa.h> |
13 | | #endif |
14 | | |
15 | | #if defined(BOTAN_HAS_DSA) |
16 | | #include <botan/dsa.h> |
17 | | #endif |
18 | | |
19 | | #if defined(BOTAN_HAS_DL_GROUP) |
20 | | #include <botan/dl_group.h> |
21 | | #endif |
22 | | |
23 | | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
24 | | #include <botan/dh.h> |
25 | | #endif |
26 | | |
27 | | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
28 | | #include <botan/ecc_key.h> |
29 | | #endif |
30 | | |
31 | | #if defined(BOTAN_HAS_ECDSA) |
32 | | #include <botan/ecdsa.h> |
33 | | #endif |
34 | | |
35 | | #if defined(BOTAN_HAS_ECGDSA) |
36 | | #include <botan/ecgdsa.h> |
37 | | #endif |
38 | | |
39 | | #if defined(BOTAN_HAS_ECKCDSA) |
40 | | #include <botan/eckcdsa.h> |
41 | | #endif |
42 | | |
43 | | #if defined(BOTAN_HAS_ED25519) |
44 | | #include <botan/ed25519.h> |
45 | | #endif |
46 | | |
47 | | #if defined(BOTAN_HAS_GOST_34_10_2001) |
48 | | #include <botan/gost_3410.h> |
49 | | #endif |
50 | | |
51 | | #if defined(BOTAN_HAS_ELGAMAL) |
52 | | #include <botan/elgamal.h> |
53 | | #endif |
54 | | |
55 | | #if defined(BOTAN_HAS_ECDH) |
56 | | #include <botan/ecdh.h> |
57 | | #endif |
58 | | |
59 | | #if defined(BOTAN_HAS_CURVE_25519) |
60 | | #include <botan/curve25519.h> |
61 | | #endif |
62 | | |
63 | | #if defined(BOTAN_HAS_MCELIECE) |
64 | | #include <botan/mceliece.h> |
65 | | #endif |
66 | | |
67 | | #if defined(BOTAN_HAS_XMSS_RFC8391) |
68 | | #include <botan/xmss.h> |
69 | | #endif |
70 | | |
71 | | #if defined(BOTAN_HAS_SM2) |
72 | | #include <botan/sm2.h> |
73 | | #endif |
74 | | |
75 | | namespace Botan { |
76 | | |
77 | | std::unique_ptr<Public_Key> |
78 | | load_public_key(const AlgorithmIdentifier& alg_id, |
79 | | const std::vector<uint8_t>& key_bits) |
80 | 9.63k | { |
81 | 9.63k | const std::string oid_str = alg_id.get_oid().to_formatted_string(); |
82 | 9.63k | const std::vector<std::string> alg_info = split_on(oid_str, '/'); |
83 | 9.63k | const std::string alg_name = alg_info[0]; |
84 | | |
85 | 9.63k | #if defined(BOTAN_HAS_RSA) |
86 | 9.63k | if(alg_name == "RSA") |
87 | 7.15k | return std::make_unique<RSA_PublicKey>(alg_id, key_bits); |
88 | 2.48k | #endif |
89 | | |
90 | 2.48k | #if defined(BOTAN_HAS_CURVE_25519) |
91 | 2.48k | if(alg_name == "Curve25519") |
92 | 1 | return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits); |
93 | 2.48k | #endif |
94 | | |
95 | 2.48k | #if defined(BOTAN_HAS_MCELIECE) |
96 | 2.48k | if(alg_name == "McEliece") |
97 | 0 | return std::make_unique<McEliece_PublicKey>(key_bits); |
98 | 2.48k | #endif |
99 | | |
100 | 2.48k | #if defined(BOTAN_HAS_ECDSA) |
101 | 2.48k | if(alg_name == "ECDSA") |
102 | 1.69k | return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits); |
103 | 791 | #endif |
104 | | |
105 | 791 | #if defined(BOTAN_HAS_ECDH) |
106 | 791 | if(alg_name == "ECDH") |
107 | 3 | return std::make_unique<ECDH_PublicKey>(alg_id, key_bits); |
108 | 788 | #endif |
109 | | |
110 | 788 | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
111 | 788 | if(alg_name == "DH") |
112 | 40 | return std::make_unique<DH_PublicKey>(alg_id, key_bits); |
113 | 748 | #endif |
114 | | |
115 | 748 | #if defined(BOTAN_HAS_DSA) |
116 | 748 | if(alg_name == "DSA") |
117 | 160 | return std::make_unique<DSA_PublicKey>(alg_id, key_bits); |
118 | 588 | #endif |
119 | | |
120 | 588 | #if defined(BOTAN_HAS_ELGAMAL) |
121 | 588 | if(alg_name == "ElGamal") |
122 | 0 | return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits); |
123 | 588 | #endif |
124 | | |
125 | 588 | #if defined(BOTAN_HAS_ECGDSA) |
126 | 588 | if(alg_name == "ECGDSA") |
127 | 0 | return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits); |
128 | 588 | #endif |
129 | | |
130 | 588 | #if defined(BOTAN_HAS_ECKCDSA) |
131 | 588 | if(alg_name == "ECKCDSA") |
132 | 0 | return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits); |
133 | 588 | #endif |
134 | | |
135 | 588 | #if defined(BOTAN_HAS_ED25519) |
136 | 588 | if(alg_name == "Ed25519") |
137 | 1 | return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits); |
138 | 587 | #endif |
139 | | |
140 | 587 | #if defined(BOTAN_HAS_GOST_34_10_2001) |
141 | 587 | if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") |
142 | 23 | return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits); |
143 | 564 | #endif |
144 | | |
145 | 564 | #if defined(BOTAN_HAS_SM2) |
146 | 564 | if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") |
147 | 0 | return std::make_unique<SM2_PublicKey>(alg_id, key_bits); |
148 | 564 | #endif |
149 | | |
150 | 564 | #if defined(BOTAN_HAS_XMSS_RFC8391) |
151 | 564 | if(alg_name == "XMSS") |
152 | 0 | return std::make_unique<XMSS_PublicKey>(key_bits); |
153 | 564 | #endif |
154 | | |
155 | 564 | throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name); |
156 | 564 | } |
157 | | |
158 | | std::unique_ptr<Private_Key> |
159 | | load_private_key(const AlgorithmIdentifier& alg_id, |
160 | | const secure_vector<uint8_t>& key_bits) |
161 | 3.36k | { |
162 | 3.36k | const std::string alg_name = alg_id.get_oid().to_formatted_string(); |
163 | | |
164 | 3.36k | #if defined(BOTAN_HAS_RSA) |
165 | 3.36k | if(alg_name == "RSA") |
166 | 268 | return std::make_unique<RSA_PrivateKey>(alg_id, key_bits); |
167 | 3.10k | #endif |
168 | | |
169 | 3.10k | #if defined(BOTAN_HAS_CURVE_25519) |
170 | 3.10k | if(alg_name == "Curve25519") |
171 | 19 | return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits); |
172 | 3.08k | #endif |
173 | | |
174 | 3.08k | #if defined(BOTAN_HAS_ECDSA) |
175 | 3.08k | if(alg_name == "ECDSA") |
176 | 840 | return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits); |
177 | 2.24k | #endif |
178 | | |
179 | 2.24k | #if defined(BOTAN_HAS_ECDH) |
180 | 2.24k | if(alg_name == "ECDH") |
181 | 1.73k | return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits); |
182 | 503 | #endif |
183 | | |
184 | 503 | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
185 | 503 | if(alg_name == "DH") |
186 | 152 | return std::make_unique<DH_PrivateKey>(alg_id, key_bits); |
187 | 351 | #endif |
188 | | |
189 | 351 | #if defined(BOTAN_HAS_DSA) |
190 | 351 | if(alg_name == "DSA") |
191 | 308 | return std::make_unique<DSA_PrivateKey>(alg_id, key_bits); |
192 | 43 | #endif |
193 | | |
194 | 43 | #if defined(BOTAN_HAS_MCELIECE) |
195 | 43 | if(alg_name == "McEliece") |
196 | 0 | return std::make_unique<McEliece_PrivateKey>(key_bits); |
197 | 43 | #endif |
198 | | |
199 | 43 | #if defined(BOTAN_HAS_ECGDSA) |
200 | 43 | if(alg_name == "ECGDSA") |
201 | 0 | return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits); |
202 | 43 | #endif |
203 | | |
204 | 43 | #if defined(BOTAN_HAS_ECKCDSA) |
205 | 43 | if(alg_name == "ECKCDSA") |
206 | 0 | return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits); |
207 | 43 | #endif |
208 | | |
209 | 43 | #if defined(BOTAN_HAS_ED25519) |
210 | 43 | if(alg_name == "Ed25519") |
211 | 30 | return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits); |
212 | 13 | #endif |
213 | | |
214 | 13 | #if defined(BOTAN_HAS_GOST_34_10_2001) |
215 | 13 | if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") |
216 | 0 | return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits); |
217 | 13 | #endif |
218 | | |
219 | 13 | #if defined(BOTAN_HAS_SM2) |
220 | 13 | if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") |
221 | 0 | return std::make_unique<SM2_PrivateKey>(alg_id, key_bits); |
222 | 13 | #endif |
223 | | |
224 | 13 | #if defined(BOTAN_HAS_ELGAMAL) |
225 | 13 | if(alg_name == "ElGamal") |
226 | 0 | return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits); |
227 | 13 | #endif |
228 | | |
229 | 13 | #if defined(BOTAN_HAS_XMSS_RFC8391) |
230 | 13 | if(alg_name == "XMSS") |
231 | 0 | return std::make_unique<XMSS_PrivateKey>(key_bits); |
232 | 13 | #endif |
233 | | |
234 | 13 | throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name); |
235 | 13 | } |
236 | | |
237 | | #if defined(BOTAN_HAS_ECC_GROUP) |
238 | | |
239 | | namespace { |
240 | | |
241 | | std::string default_ec_group_for(const std::string& alg_name) |
242 | 0 | { |
243 | 0 | if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") |
244 | 0 | return "sm2p256v1"; |
245 | 0 | if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") |
246 | 0 | return "gost_256A"; |
247 | 0 | if(alg_name == "GOST-34.10-2012-512") |
248 | 0 | return "gost_512A"; |
249 | 0 | if(alg_name == "ECGDSA") |
250 | 0 | return "brainpool256r1"; |
251 | 0 | return "secp256r1"; |
252 | |
|
253 | 0 | } |
254 | | |
255 | | } |
256 | | |
257 | | #endif |
258 | | |
259 | | BOTAN_PUBLIC_API(3,0) std::unique_ptr<Private_Key> |
260 | | create_ec_private_key(const std::string& alg_name, |
261 | | const EC_Group& ec_group, |
262 | | RandomNumberGenerator& rng) |
263 | 0 | { |
264 | 0 | #if defined(BOTAN_HAS_ECDSA) |
265 | 0 | if(alg_name == "ECDSA") |
266 | 0 | return std::make_unique<ECDSA_PrivateKey>(rng, ec_group); |
267 | 0 | #endif |
268 | | |
269 | 0 | #if defined(BOTAN_HAS_ECDH) |
270 | 0 | if(alg_name == "ECDH") |
271 | 0 | return std::make_unique<ECDH_PrivateKey>(rng, ec_group); |
272 | 0 | #endif |
273 | | |
274 | 0 | #if defined(BOTAN_HAS_ECKCDSA) |
275 | 0 | if(alg_name == "ECKCDSA") |
276 | 0 | return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group); |
277 | 0 | #endif |
278 | | |
279 | 0 | #if defined(BOTAN_HAS_GOST_34_10_2001) |
280 | 0 | if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") |
281 | 0 | return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group); |
282 | 0 | #endif |
283 | | |
284 | 0 | #if defined(BOTAN_HAS_SM2) |
285 | 0 | if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") |
286 | 0 | return std::make_unique<SM2_PrivateKey>(rng, ec_group); |
287 | 0 | #endif |
288 | | |
289 | 0 | #if defined(BOTAN_HAS_ECGDSA) |
290 | 0 | if(alg_name == "ECGDSA") |
291 | 0 | return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group); |
292 | 0 | #endif |
293 | | |
294 | 0 | return nullptr; |
295 | 0 | } |
296 | | |
297 | | |
298 | | std::unique_ptr<Private_Key> |
299 | | create_private_key(const std::string& alg_name, |
300 | | RandomNumberGenerator& rng, |
301 | | const std::string& params, |
302 | | const std::string& provider) |
303 | 0 | { |
304 | | /* |
305 | | * Default paramaters are chosen for work factor > 2**128 where possible |
306 | | */ |
307 | |
|
308 | 0 | #if defined(BOTAN_HAS_CURVE_25519) |
309 | 0 | if(alg_name == "Curve25519") |
310 | 0 | return std::make_unique<Curve25519_PrivateKey>(rng); |
311 | 0 | #endif |
312 | | |
313 | 0 | #if defined(BOTAN_HAS_RSA) |
314 | 0 | if(alg_name == "RSA") |
315 | 0 | { |
316 | 0 | const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params)); |
317 | 0 | return std::make_unique<RSA_PrivateKey>(rng, rsa_bits); |
318 | 0 | } |
319 | 0 | #endif |
320 | | |
321 | 0 | #if defined(BOTAN_HAS_MCELIECE) |
322 | 0 | if(alg_name == "McEliece") |
323 | 0 | { |
324 | 0 | std::vector<std::string> mce_param = |
325 | 0 | Botan::split_on(params.empty() ? "2960,57" : params, ','); |
326 | |
|
327 | 0 | if(mce_param.size() != 2) |
328 | 0 | throw Invalid_Argument("create_private_key bad McEliece parameters " + params); |
329 | | |
330 | 0 | size_t mce_n = Botan::to_u32bit(mce_param[0]); |
331 | 0 | size_t mce_t = Botan::to_u32bit(mce_param[1]); |
332 | |
|
333 | 0 | return std::make_unique<Botan::McEliece_PrivateKey>(rng, mce_n, mce_t); |
334 | 0 | } |
335 | 0 | #endif |
336 | | |
337 | 0 | #if defined(BOTAN_HAS_XMSS_RFC8391) |
338 | 0 | if(alg_name == "XMSS") |
339 | 0 | { |
340 | 0 | return std::make_unique<XMSS_PrivateKey>(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng); |
341 | 0 | } |
342 | 0 | #endif |
343 | | |
344 | 0 | #if defined(BOTAN_HAS_ED25519) |
345 | 0 | if(alg_name == "Ed25519") |
346 | 0 | { |
347 | 0 | return std::make_unique<Ed25519_PrivateKey>(rng); |
348 | 0 | } |
349 | 0 | #endif |
350 | | |
351 | | // ECC crypto |
352 | 0 | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
353 | | |
354 | 0 | if(alg_name == "ECDSA" || |
355 | 0 | alg_name == "ECDH" || |
356 | 0 | alg_name == "ECKCDSA" || |
357 | 0 | alg_name == "ECGDSA" || |
358 | 0 | alg_name == "SM2" || |
359 | 0 | alg_name == "SM2_Sig" || |
360 | 0 | alg_name == "SM2_Enc" || |
361 | 0 | alg_name == "GOST-34.10" || |
362 | 0 | alg_name == "GOST-34.10-2012-256" || |
363 | 0 | alg_name == "GOST-34.10-2012-512") |
364 | 0 | { |
365 | 0 | const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params); |
366 | 0 | return create_ec_private_key(alg_name, ec_group, rng); |
367 | 0 | } |
368 | 0 | #endif |
369 | | |
370 | | // DL crypto |
371 | 0 | #if defined(BOTAN_HAS_DL_GROUP) |
372 | 0 | if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") |
373 | 0 | { |
374 | 0 | std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048"; |
375 | 0 | DL_Group modp_group(params.empty() ? default_group : params); |
376 | |
|
377 | 0 | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
378 | 0 | if(alg_name == "DH") |
379 | 0 | return std::make_unique<DH_PrivateKey>(rng, modp_group); |
380 | 0 | #endif |
381 | | |
382 | 0 | #if defined(BOTAN_HAS_DSA) |
383 | 0 | if(alg_name == "DSA") |
384 | 0 | return std::make_unique<DSA_PrivateKey>(rng, modp_group); |
385 | 0 | #endif |
386 | | |
387 | 0 | #if defined(BOTAN_HAS_ELGAMAL) |
388 | 0 | if(alg_name == "ElGamal") |
389 | 0 | return std::make_unique<ElGamal_PrivateKey>(rng, modp_group); |
390 | 0 | #endif |
391 | 0 | } |
392 | 0 | #endif |
393 | | |
394 | 0 | BOTAN_UNUSED(alg_name, rng, params, provider); |
395 | |
|
396 | 0 | return std::unique_ptr<Private_Key>(); |
397 | 0 | } |
398 | | |
399 | | std::vector<std::string> |
400 | | probe_provider_private_key(const std::string& alg_name, |
401 | | const std::vector<std::string>& possible) |
402 | 0 | { |
403 | 0 | std::vector<std::string> providers; |
404 | |
|
405 | 0 | for(auto&& prov : possible) |
406 | 0 | { |
407 | 0 | if(prov == "base") |
408 | 0 | providers.push_back(prov); |
409 | 0 | } |
410 | |
|
411 | 0 | BOTAN_UNUSED(alg_name); |
412 | |
|
413 | 0 | return providers; |
414 | 0 | } |
415 | | } |