/src/Botan-3.4.0/src/lib/ffi/ffi_pkey_algs.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 2015,2017 Jack Lloyd |
3 | | * (C) 2017 Ribose Inc |
4 | | * (C) 2018 René Korthaus, Rohde & Schwarz Cybersecurity |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #include <botan/ffi.h> |
10 | | |
11 | | #include <botan/hash.h> |
12 | | #include <botan/pem.h> |
13 | | #include <botan/internal/ffi_mp.h> |
14 | | #include <botan/internal/ffi_pkey.h> |
15 | | #include <botan/internal/ffi_rng.h> |
16 | | #include <botan/internal/ffi_util.h> |
17 | | |
18 | | #if defined(BOTAN_HAS_DL_GROUP) |
19 | | #include <botan/dl_group.h> |
20 | | #endif |
21 | | |
22 | | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
23 | | #include <botan/ecc_key.h> |
24 | | #endif |
25 | | |
26 | | #if defined(BOTAN_HAS_RSA) |
27 | | #include <botan/rsa.h> |
28 | | #endif |
29 | | |
30 | | #if defined(BOTAN_HAS_ELGAMAL) |
31 | | #include <botan/elgamal.h> |
32 | | #endif |
33 | | |
34 | | #if defined(BOTAN_HAS_DSA) |
35 | | #include <botan/dsa.h> |
36 | | #endif |
37 | | |
38 | | #if defined(BOTAN_HAS_ECDSA) |
39 | | #include <botan/ecdsa.h> |
40 | | #endif |
41 | | |
42 | | #if defined(BOTAN_HAS_SM2) |
43 | | #include <botan/sm2.h> |
44 | | #endif |
45 | | |
46 | | #if defined(BOTAN_HAS_ECDH) |
47 | | #include <botan/ecdh.h> |
48 | | #endif |
49 | | |
50 | | #if defined(BOTAN_HAS_CURVE_25519) |
51 | | #include <botan/curve25519.h> |
52 | | #endif |
53 | | |
54 | | #if defined(BOTAN_HAS_X448) |
55 | | #include <botan/x448.h> |
56 | | #endif |
57 | | |
58 | | #if defined(BOTAN_HAS_ED25519) |
59 | | #include <botan/ed25519.h> |
60 | | #endif |
61 | | |
62 | | #if defined(BOTAN_HAS_ED448) |
63 | | #include <botan/ed448.h> |
64 | | #endif |
65 | | |
66 | | #if defined(BOTAN_HAS_MCELIECE) |
67 | | #include <botan/mceliece.h> |
68 | | #endif |
69 | | |
70 | | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
71 | | #include <botan/dh.h> |
72 | | #endif |
73 | | |
74 | | #if defined(BOTAN_HAS_KYBER) |
75 | | #include <botan/kyber.h> |
76 | | #endif |
77 | | |
78 | | namespace { |
79 | | |
80 | | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
81 | | |
82 | | // These are always called within an existing try/catch block |
83 | | |
84 | | template <class ECPrivateKey_t> |
85 | 0 | int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key, const Botan::BigInt& scalar, const char* curve_name) { |
86 | 0 | if(curve_name == nullptr) { |
87 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
88 | 0 | } |
89 | | |
90 | 0 | Botan::Null_RNG null_rng; |
91 | 0 | Botan::EC_Group grp(curve_name); |
92 | 0 | key.reset(new ECPrivateKey_t(null_rng, grp, scalar)); |
93 | 0 | return BOTAN_FFI_SUCCESS; |
94 | 0 | } Unexecuted instantiation: ffi_pkey_algs.cpp:int (anonymous namespace)::privkey_load_ec<Botan::ECDSA_PrivateKey>(std::__1::unique_ptr<Botan::ECDSA_PrivateKey, std::__1::default_delete<Botan::ECDSA_PrivateKey> >&, Botan::BigInt const&, char const*) Unexecuted instantiation: ffi_pkey_algs.cpp:int (anonymous namespace)::privkey_load_ec<Botan::ECDH_PrivateKey>(std::__1::unique_ptr<Botan::ECDH_PrivateKey, std::__1::default_delete<Botan::ECDH_PrivateKey> >&, Botan::BigInt const&, char const*) Unexecuted instantiation: ffi_pkey_algs.cpp:int (anonymous namespace)::privkey_load_ec<Botan::SM2_PrivateKey>(std::__1::unique_ptr<Botan::SM2_PrivateKey, std::__1::default_delete<Botan::SM2_PrivateKey> >&, Botan::BigInt const&, char const*) |
95 | | |
96 | | template <class ECPublicKey_t> |
97 | | int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key, |
98 | | const Botan::BigInt& public_x, |
99 | | const Botan::BigInt& public_y, |
100 | 69.8k | const char* curve_name) { |
101 | 69.8k | if(curve_name == nullptr) { |
102 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
103 | 0 | } |
104 | | |
105 | 69.8k | Botan::EC_Group grp(curve_name); |
106 | 69.8k | Botan::EC_Point uncompressed_point = grp.point(public_x, public_y); |
107 | 69.8k | key.reset(new ECPublicKey_t(grp, uncompressed_point)); |
108 | 69.8k | return BOTAN_FFI_SUCCESS; |
109 | 69.8k | } ffi_pkey_algs.cpp:int (anonymous namespace)::pubkey_load_ec<Botan::ECDSA_PublicKey>(std::__1::unique_ptr<Botan::ECDSA_PublicKey, std::__1::default_delete<Botan::ECDSA_PublicKey> >&, Botan::BigInt const&, Botan::BigInt const&, char const*) Line | Count | Source | 100 | 54.9k | const char* curve_name) { | 101 | 54.9k | if(curve_name == nullptr) { | 102 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; | 103 | 0 | } | 104 | | | 105 | 54.9k | Botan::EC_Group grp(curve_name); | 106 | 54.9k | Botan::EC_Point uncompressed_point = grp.point(public_x, public_y); | 107 | 54.9k | key.reset(new ECPublicKey_t(grp, uncompressed_point)); | 108 | 54.9k | return BOTAN_FFI_SUCCESS; | 109 | 54.9k | } |
Unexecuted instantiation: ffi_pkey_algs.cpp:int (anonymous namespace)::pubkey_load_ec<Botan::ECDH_PublicKey>(std::__1::unique_ptr<Botan::ECDH_PublicKey, std::__1::default_delete<Botan::ECDH_PublicKey> >&, Botan::BigInt const&, Botan::BigInt const&, char const*) ffi_pkey_algs.cpp:int (anonymous namespace)::pubkey_load_ec<Botan::SM2_PublicKey>(std::__1::unique_ptr<Botan::SM2_PublicKey, std::__1::default_delete<Botan::SM2_PublicKey> >&, Botan::BigInt const&, Botan::BigInt const&, char const*) Line | Count | Source | 100 | 14.9k | const char* curve_name) { | 101 | 14.9k | if(curve_name == nullptr) { | 102 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; | 103 | 0 | } | 104 | | | 105 | 14.9k | Botan::EC_Group grp(curve_name); | 106 | 14.9k | Botan::EC_Point uncompressed_point = grp.point(public_x, public_y); | 107 | 14.9k | key.reset(new ECPublicKey_t(grp, uncompressed_point)); | 108 | 14.9k | return BOTAN_FFI_SUCCESS; | 109 | 14.9k | } |
|
110 | | |
111 | | #endif |
112 | | |
113 | 0 | Botan::BigInt pubkey_get_field(const Botan::Public_Key& key, std::string_view field) { |
114 | 0 | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
115 | | // Not currently handled by get_int_field |
116 | 0 | if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) { |
117 | 0 | if(field == "public_x") { |
118 | 0 | return ecc->public_point().get_affine_x(); |
119 | 0 | } else if(field == "public_y") { |
120 | 0 | return ecc->public_point().get_affine_y(); |
121 | 0 | } |
122 | 0 | } |
123 | 0 | #endif |
124 | | |
125 | 0 | try { |
126 | 0 | return key.get_int_field(field); |
127 | 0 | } catch(Botan::Unknown_PK_Field_Name&) { |
128 | 0 | throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER); |
129 | 0 | } |
130 | 0 | } |
131 | | |
132 | 0 | Botan::BigInt privkey_get_field(const Botan::Private_Key& key, std::string_view field) { |
133 | 0 | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
134 | | // Not currently handled by get_int_field |
135 | 0 | if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) { |
136 | 0 | if(field == "public_x") { |
137 | 0 | return ecc->public_point().get_affine_x(); |
138 | 0 | } else if(field == "public_y") { |
139 | 0 | return ecc->public_point().get_affine_y(); |
140 | 0 | } |
141 | 0 | } |
142 | 0 | #endif |
143 | | |
144 | 0 | try { |
145 | 0 | return key.get_int_field(field); |
146 | 0 | } catch(Botan::Unknown_PK_Field_Name&) { |
147 | 0 | throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER); |
148 | 0 | } |
149 | 0 | } |
150 | | |
151 | | } // namespace |
152 | | |
153 | | extern "C" { |
154 | | |
155 | | using namespace Botan_FFI; |
156 | | |
157 | 0 | int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char* field_name_cstr) { |
158 | 0 | if(field_name_cstr == nullptr) { |
159 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
160 | 0 | } |
161 | | |
162 | 0 | const std::string field_name(field_name_cstr); |
163 | |
|
164 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = pubkey_get_field(k, field_name); }); |
165 | 0 | } |
166 | | |
167 | 0 | int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char* field_name_cstr) { |
168 | 0 | if(field_name_cstr == nullptr) { |
169 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
170 | 0 | } |
171 | | |
172 | 0 | const std::string field_name(field_name_cstr); |
173 | |
|
174 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = privkey_get_field(k, field_name); }); |
175 | 0 | } |
176 | | |
177 | | /* RSA specific operations */ |
178 | | |
179 | 0 | int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits) { |
180 | 0 | if(n_bits < 1024 || n_bits > 16 * 1024) { |
181 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
182 | 0 | } |
183 | | |
184 | 0 | std::string n_str = std::to_string(n_bits); |
185 | |
|
186 | 0 | return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj); |
187 | 0 | } |
188 | | |
189 | 0 | int botan_privkey_load_rsa(botan_privkey_t* key, botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e) { |
190 | 0 | #if defined(BOTAN_HAS_RSA) |
191 | 0 | *key = nullptr; |
192 | |
|
193 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
194 | 0 | auto rsa = std::make_unique<Botan::RSA_PrivateKey>(safe_get(rsa_p), safe_get(rsa_q), safe_get(rsa_e)); |
195 | 0 | *key = new botan_privkey_struct(std::move(rsa)); |
196 | 0 | return BOTAN_FFI_SUCCESS; |
197 | 0 | }); |
198 | | #else |
199 | | BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e); |
200 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
201 | | #endif |
202 | 0 | } |
203 | | |
204 | 0 | int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key, const uint8_t bits[], size_t len) { |
205 | 0 | #if defined(BOTAN_HAS_RSA) |
206 | 0 | *key = nullptr; |
207 | |
|
208 | 0 | Botan::secure_vector<uint8_t> src(bits, bits + len); |
209 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
210 | 0 | Botan::AlgorithmIdentifier alg_id("RSA", Botan::AlgorithmIdentifier::USE_NULL_PARAM); |
211 | 0 | auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src); |
212 | 0 | *key = new botan_privkey_struct(std::move(rsa)); |
213 | 0 | return BOTAN_FFI_SUCCESS; |
214 | 0 | }); |
215 | | #else |
216 | | BOTAN_UNUSED(key, bits, len); |
217 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
218 | | #endif |
219 | 0 | } |
220 | | |
221 | 54.8k | int botan_pubkey_load_rsa(botan_pubkey_t* key, botan_mp_t n, botan_mp_t e) { |
222 | 54.8k | #if defined(BOTAN_HAS_RSA) |
223 | 54.8k | *key = nullptr; |
224 | 54.8k | return ffi_guard_thunk(__func__, [=]() -> int { |
225 | 54.8k | auto rsa = std::make_unique<Botan::RSA_PublicKey>(safe_get(n), safe_get(e)); |
226 | 54.8k | *key = new botan_pubkey_struct(std::move(rsa)); |
227 | 54.8k | return BOTAN_FFI_SUCCESS; |
228 | 54.8k | }); |
229 | | #else |
230 | | BOTAN_UNUSED(key, n, e); |
231 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
232 | | #endif |
233 | 54.8k | } |
234 | | |
235 | 0 | int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key) { |
236 | 0 | return botan_privkey_get_field(p, key, "p"); |
237 | 0 | } |
238 | | |
239 | 0 | int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key) { |
240 | 0 | return botan_privkey_get_field(q, key, "q"); |
241 | 0 | } |
242 | | |
243 | 0 | int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key) { |
244 | 0 | return botan_privkey_get_field(n, key, "n"); |
245 | 0 | } |
246 | | |
247 | 0 | int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key) { |
248 | 0 | return botan_privkey_get_field(e, key, "e"); |
249 | 0 | } |
250 | | |
251 | 0 | int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key) { |
252 | 0 | return botan_privkey_get_field(d, key, "d"); |
253 | 0 | } |
254 | | |
255 | 0 | int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key) { |
256 | 0 | return botan_pubkey_get_field(e, key, "e"); |
257 | 0 | } |
258 | | |
259 | 0 | int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key) { |
260 | 0 | return botan_pubkey_get_field(n, key, "n"); |
261 | 0 | } |
262 | | |
263 | 0 | int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t* out_len, uint32_t flags) { |
264 | 0 | #if defined(BOTAN_HAS_RSA) |
265 | 0 | return BOTAN_FFI_VISIT(rsa_key, [=](const auto& k) -> int { |
266 | 0 | if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k)) { |
267 | 0 | if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER) |
268 | 0 | return write_vec_output(out, out_len, rsa->private_key_bits()); |
269 | 0 | else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM) |
270 | 0 | return write_str_output(out, out_len, Botan::PEM_Code::encode(rsa->private_key_bits(), "RSA PRIVATE KEY")); |
271 | 0 | else |
272 | 0 | return BOTAN_FFI_ERROR_BAD_FLAG; |
273 | 0 | } else { |
274 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
275 | 0 | } |
276 | 0 | }); |
277 | | #else |
278 | | BOTAN_UNUSED(rsa_key, out, out_len, flags); |
279 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
280 | | #endif |
281 | 0 | } |
282 | | |
283 | | /* DSA specific operations */ |
284 | 0 | int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) { |
285 | 0 | #if defined(BOTAN_HAS_DSA) |
286 | |
|
287 | 0 | if((rng_obj == nullptr) || (key == nullptr)) { |
288 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
289 | 0 | } |
290 | | |
291 | 0 | if((pbits % 64) || (qbits % 8) || (pbits < 1024) || (pbits > 3072) || (qbits < 160) || (qbits > 256)) { |
292 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
293 | 0 | } |
294 | | |
295 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
296 | 0 | Botan::RandomNumberGenerator& rng = safe_get(rng_obj); |
297 | 0 | Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits); |
298 | 0 | auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group); |
299 | 0 | *key = new botan_privkey_struct(std::move(dsa)); |
300 | 0 | return BOTAN_FFI_SUCCESS; |
301 | 0 | }); |
302 | | #else |
303 | | BOTAN_UNUSED(key, rng_obj, pbits, qbits); |
304 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
305 | | #endif |
306 | 0 | } |
307 | | |
308 | 0 | int botan_privkey_load_dsa(botan_privkey_t* key, botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x) { |
309 | 0 | #if defined(BOTAN_HAS_DSA) |
310 | 0 | *key = nullptr; |
311 | |
|
312 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
313 | 0 | Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g)); |
314 | 0 | auto dsa = std::make_unique<Botan::DSA_PrivateKey>(group, safe_get(x)); |
315 | 0 | *key = new botan_privkey_struct(std::move(dsa)); |
316 | 0 | return BOTAN_FFI_SUCCESS; |
317 | 0 | }); |
318 | | #else |
319 | | BOTAN_UNUSED(key, p, q, g, x); |
320 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
321 | | #endif |
322 | 0 | } |
323 | | |
324 | 14.1k | int botan_pubkey_load_dsa(botan_pubkey_t* key, botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y) { |
325 | 14.1k | #if defined(BOTAN_HAS_DSA) |
326 | 14.1k | *key = nullptr; |
327 | | |
328 | 14.1k | return ffi_guard_thunk(__func__, [=]() -> int { |
329 | 14.1k | Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g)); |
330 | 14.1k | auto dsa = std::make_unique<Botan::DSA_PublicKey>(group, safe_get(y)); |
331 | 14.1k | *key = new botan_pubkey_struct(std::move(dsa)); |
332 | 14.1k | return BOTAN_FFI_SUCCESS; |
333 | 14.1k | }); |
334 | | #else |
335 | | BOTAN_UNUSED(key, p, q, g, y); |
336 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
337 | | #endif |
338 | 14.1k | } |
339 | | |
340 | 0 | int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key) { |
341 | 0 | return botan_privkey_get_field(x, key, "x"); |
342 | 0 | } |
343 | | |
344 | 0 | int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key) { |
345 | 0 | return botan_pubkey_get_field(p, key, "p"); |
346 | 0 | } |
347 | | |
348 | 0 | int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key) { |
349 | 0 | return botan_pubkey_get_field(q, key, "q"); |
350 | 0 | } |
351 | | |
352 | 0 | int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key) { |
353 | 0 | return botan_pubkey_get_field(g, key, "g"); |
354 | 0 | } |
355 | | |
356 | 0 | int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key) { |
357 | 0 | return botan_pubkey_get_field(y, key, "y"); |
358 | 0 | } |
359 | | |
360 | 0 | int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) { |
361 | 0 | return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj); |
362 | 0 | } |
363 | | |
364 | | /* ECDSA specific operations */ |
365 | | |
366 | 0 | int botan_pubkey_ecc_key_used_explicit_encoding(botan_pubkey_t key) { |
367 | 0 | #if defined(BOTAN_HAS_ECC_KEY) |
368 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
369 | 0 | const Botan::Public_Key& pub_key = safe_get(key); |
370 | 0 | const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key); |
371 | |
|
372 | 0 | if(ec_key == nullptr) { |
373 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
374 | 0 | } |
375 | | |
376 | 0 | return ec_key->domain().used_explicit_encoding() ? 1 : 0; |
377 | 0 | }); |
378 | | #else |
379 | | BOTAN_UNUSED(key); |
380 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
381 | | #endif |
382 | 0 | } |
383 | | |
384 | | int botan_pubkey_load_ecdsa(botan_pubkey_t* key, |
385 | | const botan_mp_t public_x, |
386 | | const botan_mp_t public_y, |
387 | 54.9k | const char* curve_name) { |
388 | 54.9k | #if defined(BOTAN_HAS_ECDSA) |
389 | 54.9k | return ffi_guard_thunk(__func__, [=]() -> int { |
390 | 54.9k | std::unique_ptr<Botan::ECDSA_PublicKey> p_key; |
391 | | |
392 | 54.9k | int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name); |
393 | 54.9k | if(rc == BOTAN_FFI_SUCCESS) { |
394 | 54.8k | *key = new botan_pubkey_struct(std::move(p_key)); |
395 | 54.8k | } |
396 | | |
397 | 54.9k | return rc; |
398 | 54.9k | }); |
399 | | #else |
400 | | BOTAN_UNUSED(key, public_x, public_y, curve_name); |
401 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
402 | | #endif |
403 | 54.9k | } |
404 | | |
405 | 0 | int botan_privkey_load_ecdsa(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) { |
406 | 0 | #if defined(BOTAN_HAS_ECDSA) |
407 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
408 | 0 | std::unique_ptr<Botan::ECDSA_PrivateKey> p_key; |
409 | 0 | int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name); |
410 | 0 | if(rc == BOTAN_FFI_SUCCESS) { |
411 | 0 | *key = new botan_privkey_struct(std::move(p_key)); |
412 | 0 | } |
413 | 0 | return rc; |
414 | 0 | }); |
415 | | #else |
416 | | BOTAN_UNUSED(key, scalar, curve_name); |
417 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
418 | | #endif |
419 | 0 | } |
420 | | |
421 | | /* ElGamal specific operations */ |
422 | 0 | int botan_privkey_create_elgamal(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) { |
423 | 0 | #if defined(BOTAN_HAS_ELGAMAL) |
424 | |
|
425 | 0 | if((rng_obj == nullptr) || (key == nullptr)) { |
426 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
427 | 0 | } |
428 | | |
429 | 0 | if((pbits < 1024) || (qbits < 160)) { |
430 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
431 | 0 | } |
432 | | |
433 | 0 | Botan::DL_Group::PrimeType prime_type = |
434 | 0 | ((pbits - 1) == qbits) ? Botan::DL_Group::Strong : Botan::DL_Group::Prime_Subgroup; |
435 | |
|
436 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
437 | 0 | Botan::RandomNumberGenerator& rng = safe_get(rng_obj); |
438 | 0 | Botan::DL_Group group(rng, prime_type, pbits, qbits); |
439 | 0 | auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group); |
440 | 0 | *key = new botan_privkey_struct(std::move(elg)); |
441 | 0 | return BOTAN_FFI_SUCCESS; |
442 | 0 | }); |
443 | | #else |
444 | | BOTAN_UNUSED(key, rng_obj, pbits, qbits); |
445 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
446 | | #endif |
447 | 0 | } |
448 | | |
449 | 0 | int botan_pubkey_load_elgamal(botan_pubkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t y) { |
450 | 0 | #if defined(BOTAN_HAS_ELGAMAL) |
451 | 0 | *key = nullptr; |
452 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
453 | 0 | Botan::DL_Group group(safe_get(p), safe_get(g)); |
454 | 0 | auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group, safe_get(y)); |
455 | 0 | *key = new botan_pubkey_struct(std::move(elg)); |
456 | 0 | return BOTAN_FFI_SUCCESS; |
457 | 0 | }); |
458 | | #else |
459 | | BOTAN_UNUSED(key, p, g, y); |
460 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
461 | | #endif |
462 | 0 | } |
463 | | |
464 | 0 | int botan_privkey_load_elgamal(botan_privkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t x) { |
465 | 0 | #if defined(BOTAN_HAS_ELGAMAL) |
466 | 0 | *key = nullptr; |
467 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
468 | 0 | Botan::DL_Group group(safe_get(p), safe_get(g)); |
469 | 0 | auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(group, safe_get(x)); |
470 | 0 | *key = new botan_privkey_struct(std::move(elg)); |
471 | 0 | return BOTAN_FFI_SUCCESS; |
472 | 0 | }); |
473 | | #else |
474 | | BOTAN_UNUSED(key, p, g, x); |
475 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
476 | | #endif |
477 | 0 | } |
478 | | |
479 | | /* Diffie Hellman specific operations */ |
480 | | |
481 | 0 | int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) { |
482 | 0 | return botan_privkey_create(key_obj, "DH", param_str, rng_obj); |
483 | 0 | } |
484 | | |
485 | 0 | int botan_privkey_load_dh(botan_privkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t x) { |
486 | | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
487 | | *key = nullptr; |
488 | | return ffi_guard_thunk(__func__, [=]() -> int { |
489 | | Botan::DL_Group group(safe_get(p), safe_get(g)); |
490 | | auto dh = std::make_unique<Botan::DH_PrivateKey>(group, safe_get(x)); |
491 | | *key = new botan_privkey_struct(std::move(dh)); |
492 | | return BOTAN_FFI_SUCCESS; |
493 | | }); |
494 | | #else |
495 | 0 | BOTAN_UNUSED(key, p, g, x); |
496 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
497 | 0 | #endif |
498 | 0 | } |
499 | | |
500 | 0 | int botan_pubkey_load_dh(botan_pubkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t y) { |
501 | | #if defined(BOTAN_HAS_DIFFIE_HELLMAN) |
502 | | *key = nullptr; |
503 | | return ffi_guard_thunk(__func__, [=]() -> int { |
504 | | Botan::DL_Group group(safe_get(p), safe_get(g)); |
505 | | auto dh = std::make_unique<Botan::DH_PublicKey>(group, safe_get(y)); |
506 | | *key = new botan_pubkey_struct(std::move(dh)); |
507 | | return BOTAN_FFI_SUCCESS; |
508 | | }); |
509 | | #else |
510 | 0 | BOTAN_UNUSED(key, p, g, y); |
511 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
512 | 0 | #endif |
513 | 0 | } |
514 | | |
515 | | /* ECDH + x25519/x448 specific operations */ |
516 | | |
517 | 0 | int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) { |
518 | 0 | if(param_str == nullptr) { |
519 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
520 | 0 | } |
521 | | |
522 | 0 | const std::string params(param_str); |
523 | |
|
524 | 0 | if(params == "curve25519") { |
525 | 0 | return botan_privkey_create(key_obj, "Curve25519", "", rng_obj); |
526 | 0 | } |
527 | | |
528 | 0 | if(params == "x448") { |
529 | 0 | return botan_privkey_create(key_obj, "X448", "", rng_obj); |
530 | 0 | } |
531 | | |
532 | 0 | return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj); |
533 | 0 | } |
534 | | |
535 | | int botan_pubkey_load_ecdh(botan_pubkey_t* key, |
536 | | const botan_mp_t public_x, |
537 | | const botan_mp_t public_y, |
538 | 0 | const char* curve_name) { |
539 | 0 | #if defined(BOTAN_HAS_ECDH) |
540 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
541 | 0 | std::unique_ptr<Botan::ECDH_PublicKey> p_key; |
542 | 0 | int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name); |
543 | |
|
544 | 0 | if(rc == BOTAN_FFI_SUCCESS) { |
545 | 0 | *key = new botan_pubkey_struct(std::move(p_key)); |
546 | 0 | } |
547 | 0 | return rc; |
548 | 0 | }); |
549 | | #else |
550 | | BOTAN_UNUSED(key, public_x, public_y, curve_name); |
551 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
552 | | #endif |
553 | 0 | } |
554 | | |
555 | 0 | int botan_privkey_load_ecdh(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) { |
556 | 0 | #if defined(BOTAN_HAS_ECDH) |
557 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
558 | 0 | std::unique_ptr<Botan::ECDH_PrivateKey> p_key; |
559 | 0 | int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name); |
560 | 0 | if(rc == BOTAN_FFI_SUCCESS) { |
561 | 0 | *key = new botan_privkey_struct(std::move(p_key)); |
562 | 0 | } |
563 | 0 | return rc; |
564 | 0 | }); |
565 | | #else |
566 | | BOTAN_UNUSED(key, scalar, curve_name); |
567 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
568 | | #endif |
569 | 0 | } |
570 | | |
571 | | /* SM2 specific operations */ |
572 | | |
573 | | int botan_pubkey_sm2_compute_za( |
574 | 7.58k | uint8_t out[], size_t* out_len, const char* ident, const char* hash_algo, const botan_pubkey_t key) { |
575 | 7.58k | if(out == nullptr || out_len == nullptr) { |
576 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
577 | 0 | } |
578 | 7.58k | if(ident == nullptr || hash_algo == nullptr || key == nullptr) { |
579 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
580 | 0 | } |
581 | | |
582 | 7.58k | #if defined(BOTAN_HAS_SM2) |
583 | 7.58k | return ffi_guard_thunk(__func__, [=]() -> int { |
584 | 7.58k | const Botan::Public_Key& pub_key = safe_get(key); |
585 | 7.58k | const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key); |
586 | | |
587 | 7.58k | if(ec_key == nullptr) { |
588 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
589 | 0 | } |
590 | | |
591 | 7.58k | if(ec_key->algo_name() != "SM2") { |
592 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
593 | 0 | } |
594 | | |
595 | 7.58k | const std::string ident_str(ident); |
596 | 7.58k | std::unique_ptr<Botan::HashFunction> hash = Botan::HashFunction::create_or_throw(hash_algo); |
597 | | |
598 | 7.58k | const std::vector<uint8_t> za = Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point()); |
599 | | |
600 | 7.58k | return write_vec_output(out, out_len, za); |
601 | 7.58k | }); |
602 | | #else |
603 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
604 | | #endif |
605 | 7.58k | } |
606 | | |
607 | | int botan_pubkey_load_sm2(botan_pubkey_t* key, |
608 | | const botan_mp_t public_x, |
609 | | const botan_mp_t public_y, |
610 | 14.9k | const char* curve_name) { |
611 | 14.9k | #if defined(BOTAN_HAS_SM2) |
612 | 14.9k | return ffi_guard_thunk(__func__, [=]() -> int { |
613 | 14.9k | std::unique_ptr<Botan::SM2_PublicKey> p_key; |
614 | 14.9k | if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name)) { |
615 | 14.8k | *key = new botan_pubkey_struct(std::move(p_key)); |
616 | 14.8k | return BOTAN_FFI_SUCCESS; |
617 | 14.8k | } |
618 | 111 | return BOTAN_FFI_ERROR_UNKNOWN_ERROR; |
619 | 14.9k | }); |
620 | | #else |
621 | | BOTAN_UNUSED(key, public_x, public_y, curve_name); |
622 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
623 | | #endif |
624 | 14.9k | } |
625 | | |
626 | 0 | int botan_privkey_load_sm2(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) { |
627 | 0 | #if defined(BOTAN_HAS_SM2) |
628 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
629 | 0 | std::unique_ptr<Botan::SM2_PrivateKey> p_key; |
630 | 0 | int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name); |
631 | |
|
632 | 0 | if(rc == BOTAN_FFI_SUCCESS) { |
633 | 0 | *key = new botan_privkey_struct(std::move(p_key)); |
634 | 0 | } |
635 | 0 | return rc; |
636 | 0 | }); |
637 | | #else |
638 | | BOTAN_UNUSED(key, scalar, curve_name); |
639 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
640 | | #endif |
641 | 0 | } |
642 | | |
643 | | int botan_pubkey_load_sm2_enc(botan_pubkey_t* key, |
644 | | const botan_mp_t public_x, |
645 | | const botan_mp_t public_y, |
646 | 0 | const char* curve_name) { |
647 | 0 | return botan_pubkey_load_sm2(key, public_x, public_y, curve_name); |
648 | 0 | } |
649 | | |
650 | 0 | int botan_privkey_load_sm2_enc(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) { |
651 | 0 | return botan_privkey_load_sm2(key, scalar, curve_name); |
652 | 0 | } |
653 | | |
654 | | /* Ed25519 specific operations */ |
655 | | |
656 | 0 | int botan_privkey_load_ed25519(botan_privkey_t* key, const uint8_t privkey[32]) { |
657 | 0 | #if defined(BOTAN_HAS_ED25519) |
658 | 0 | *key = nullptr; |
659 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
660 | 0 | const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32); |
661 | 0 | auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec); |
662 | 0 | *key = new botan_privkey_struct(std::move(ed25519)); |
663 | 0 | return BOTAN_FFI_SUCCESS; |
664 | 0 | }); |
665 | | #else |
666 | | BOTAN_UNUSED(key, privkey); |
667 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
668 | | #endif |
669 | 0 | } |
670 | | |
671 | 64.6k | int botan_pubkey_load_ed25519(botan_pubkey_t* key, const uint8_t pubkey[32]) { |
672 | 64.6k | #if defined(BOTAN_HAS_ED25519) |
673 | 64.6k | *key = nullptr; |
674 | 64.6k | return ffi_guard_thunk(__func__, [=]() -> int { |
675 | 64.6k | const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32); |
676 | 64.6k | auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec); |
677 | 64.6k | *key = new botan_pubkey_struct(std::move(ed25519)); |
678 | 64.6k | return BOTAN_FFI_SUCCESS; |
679 | 64.6k | }); |
680 | | #else |
681 | | BOTAN_UNUSED(key, pubkey); |
682 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
683 | | #endif |
684 | 64.6k | } |
685 | | |
686 | 0 | int botan_privkey_ed25519_get_privkey(botan_privkey_t key, uint8_t output[64]) { |
687 | 0 | #if defined(BOTAN_HAS_ED25519) |
688 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
689 | 0 | if(auto ed = dynamic_cast<const Botan::Ed25519_PrivateKey*>(&k)) { |
690 | 0 | const auto ed_key = ed->raw_private_key_bits(); |
691 | 0 | if(ed_key.size() != 64) |
692 | 0 | return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE; |
693 | 0 | Botan::copy_mem(output, ed_key.data(), ed_key.size()); |
694 | 0 | return BOTAN_FFI_SUCCESS; |
695 | 0 | } else { |
696 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
697 | 0 | } |
698 | 0 | }); |
699 | | #else |
700 | | BOTAN_UNUSED(key, output); |
701 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
702 | | #endif |
703 | 0 | } |
704 | | |
705 | 0 | int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key, uint8_t output[32]) { |
706 | 0 | #if defined(BOTAN_HAS_ED25519) |
707 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
708 | 0 | if(auto ed = dynamic_cast<const Botan::Ed25519_PublicKey*>(&k)) { |
709 | 0 | const std::vector<uint8_t>& ed_key = ed->get_public_key(); |
710 | 0 | if(ed_key.size() != 32) |
711 | 0 | return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE; |
712 | 0 | Botan::copy_mem(output, ed_key.data(), ed_key.size()); |
713 | 0 | return BOTAN_FFI_SUCCESS; |
714 | 0 | } else { |
715 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
716 | 0 | } |
717 | 0 | }); |
718 | | #else |
719 | | BOTAN_UNUSED(key, output); |
720 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
721 | | #endif |
722 | 0 | } |
723 | | |
724 | | /* Ed448 specific operations */ |
725 | | |
726 | 0 | int botan_privkey_load_ed448(botan_privkey_t* key, const uint8_t privkey[57]) { |
727 | | #if defined(BOTAN_HAS_ED448) |
728 | | *key = nullptr; |
729 | | return ffi_guard_thunk(__func__, [=]() -> int { |
730 | | auto ed448 = std::make_unique<Botan::Ed448_PrivateKey>(std::span(privkey, 57)); |
731 | | *key = new botan_privkey_struct(std::move(ed448)); |
732 | | return BOTAN_FFI_SUCCESS; |
733 | | }); |
734 | | #else |
735 | 0 | BOTAN_UNUSED(key, privkey); |
736 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
737 | 0 | #endif |
738 | 0 | } |
739 | | |
740 | 0 | int botan_pubkey_load_ed448(botan_pubkey_t* key, const uint8_t pubkey[57]) { |
741 | | #if defined(BOTAN_HAS_ED448) |
742 | | *key = nullptr; |
743 | | return ffi_guard_thunk(__func__, [=]() -> int { |
744 | | auto ed448 = std::make_unique<Botan::Ed448_PublicKey>(std::span(pubkey, 57)); |
745 | | *key = new botan_pubkey_struct(std::move(ed448)); |
746 | | return BOTAN_FFI_SUCCESS; |
747 | | }); |
748 | | #else |
749 | 0 | BOTAN_UNUSED(key, pubkey); |
750 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
751 | 0 | #endif |
752 | 0 | } |
753 | | |
754 | 0 | int botan_privkey_ed448_get_privkey(botan_privkey_t key, uint8_t output[57]) { |
755 | | #if defined(BOTAN_HAS_ED448) |
756 | | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
757 | | if(auto ed = dynamic_cast<const Botan::Ed448_PrivateKey*>(&k)) { |
758 | | const auto ed_key = ed->raw_private_key_bits(); |
759 | | Botan::copy_mem(std::span(output, 57), ed_key); |
760 | | return BOTAN_FFI_SUCCESS; |
761 | | } else { |
762 | | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
763 | | } |
764 | | }); |
765 | | #else |
766 | 0 | BOTAN_UNUSED(key, output); |
767 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
768 | 0 | #endif |
769 | 0 | } |
770 | | |
771 | 0 | int botan_pubkey_ed448_get_pubkey(botan_pubkey_t key, uint8_t output[57]) { |
772 | | #if defined(BOTAN_HAS_ED448) |
773 | | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
774 | | if(auto ed = dynamic_cast<const Botan::Ed448_PublicKey*>(&k)) { |
775 | | const auto ed_key = ed->public_key_bits(); |
776 | | Botan::copy_mem(std::span(output, 57), ed_key); |
777 | | return BOTAN_FFI_SUCCESS; |
778 | | } else { |
779 | | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
780 | | } |
781 | | }); |
782 | | #else |
783 | 0 | BOTAN_UNUSED(key, output); |
784 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
785 | 0 | #endif |
786 | 0 | } |
787 | | |
788 | | /* X25519 specific operations */ |
789 | | |
790 | 0 | int botan_privkey_load_x25519(botan_privkey_t* key, const uint8_t privkey[32]) { |
791 | 0 | #if defined(BOTAN_HAS_X25519) |
792 | 0 | *key = nullptr; |
793 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
794 | 0 | const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32); |
795 | 0 | auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(privkey_vec); |
796 | 0 | *key = new botan_privkey_struct(std::move(x25519)); |
797 | 0 | return BOTAN_FFI_SUCCESS; |
798 | 0 | }); |
799 | | #else |
800 | | BOTAN_UNUSED(key, privkey); |
801 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
802 | | #endif |
803 | 0 | } |
804 | | |
805 | 0 | int botan_pubkey_load_x25519(botan_pubkey_t* key, const uint8_t pubkey[32]) { |
806 | 0 | #if defined(BOTAN_HAS_X25519) |
807 | 0 | *key = nullptr; |
808 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
809 | 0 | const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32); |
810 | 0 | auto x25519 = std::make_unique<Botan::X25519_PublicKey>(pubkey_vec); |
811 | 0 | *key = new botan_pubkey_struct(std::move(x25519)); |
812 | 0 | return BOTAN_FFI_SUCCESS; |
813 | 0 | }); |
814 | | #else |
815 | | BOTAN_UNUSED(key, pubkey); |
816 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
817 | | #endif |
818 | 0 | } |
819 | | |
820 | 0 | int botan_privkey_x25519_get_privkey(botan_privkey_t key, uint8_t output[32]) { |
821 | 0 | #if defined(BOTAN_HAS_X25519) |
822 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
823 | 0 | if(auto x25519 = dynamic_cast<const Botan::X25519_PrivateKey*>(&k)) { |
824 | 0 | const auto x25519_key = x25519->raw_private_key_bits(); |
825 | 0 | if(x25519_key.size() != 32) |
826 | 0 | return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE; |
827 | 0 | Botan::copy_mem(output, x25519_key.data(), x25519_key.size()); |
828 | 0 | return BOTAN_FFI_SUCCESS; |
829 | 0 | } else { |
830 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
831 | 0 | } |
832 | 0 | }); |
833 | | #else |
834 | | BOTAN_UNUSED(key, output); |
835 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
836 | | #endif |
837 | 0 | } |
838 | | |
839 | 0 | int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key, uint8_t output[32]) { |
840 | 0 | #if defined(BOTAN_HAS_X25519) |
841 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
842 | 0 | if(auto x25519 = dynamic_cast<const Botan::X25519_PublicKey*>(&k)) { |
843 | 0 | const std::vector<uint8_t>& x25519_key = x25519->public_value(); |
844 | 0 | if(x25519_key.size() != 32) |
845 | 0 | return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE; |
846 | 0 | Botan::copy_mem(output, x25519_key.data(), x25519_key.size()); |
847 | 0 | return BOTAN_FFI_SUCCESS; |
848 | 0 | } else { |
849 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
850 | 0 | } |
851 | 0 | }); |
852 | | #else |
853 | | BOTAN_UNUSED(key, output); |
854 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
855 | | #endif |
856 | 0 | } |
857 | | |
858 | | /* X448 specific operations */ |
859 | | |
860 | 0 | int botan_privkey_load_x448(botan_privkey_t* key, const uint8_t privkey[56]) { |
861 | | #if defined(BOTAN_HAS_X448) |
862 | | *key = nullptr; |
863 | | return ffi_guard_thunk(__func__, [=]() -> int { |
864 | | auto x448 = std::make_unique<Botan::X448_PrivateKey>(std::span(privkey, 56)); |
865 | | *key = new botan_privkey_struct(std::move(x448)); |
866 | | return BOTAN_FFI_SUCCESS; |
867 | | }); |
868 | | #else |
869 | 0 | BOTAN_UNUSED(key, privkey); |
870 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
871 | 0 | #endif |
872 | 0 | } |
873 | | |
874 | 0 | int botan_pubkey_load_x448(botan_pubkey_t* key, const uint8_t pubkey[56]) { |
875 | | #if defined(BOTAN_HAS_X448) |
876 | | *key = nullptr; |
877 | | return ffi_guard_thunk(__func__, [=]() -> int { |
878 | | auto x448 = std::make_unique<Botan::X448_PublicKey>(std::span(pubkey, 56)); |
879 | | *key = new botan_pubkey_struct(std::move(x448)); |
880 | | return BOTAN_FFI_SUCCESS; |
881 | | }); |
882 | | #else |
883 | 0 | BOTAN_UNUSED(key, pubkey); |
884 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
885 | 0 | #endif |
886 | 0 | } |
887 | | |
888 | 0 | int botan_privkey_x448_get_privkey(botan_privkey_t key, uint8_t output[56]) { |
889 | | #if defined(BOTAN_HAS_X448) |
890 | | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
891 | | if(auto x448 = dynamic_cast<const Botan::X448_PrivateKey*>(&k)) { |
892 | | const auto x448_key = x448->raw_private_key_bits(); |
893 | | Botan::copy_mem(std::span(output, 56), x448_key); |
894 | | return BOTAN_FFI_SUCCESS; |
895 | | } else { |
896 | | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
897 | | } |
898 | | }); |
899 | | #else |
900 | 0 | BOTAN_UNUSED(key, output); |
901 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
902 | 0 | #endif |
903 | 0 | } |
904 | | |
905 | 0 | int botan_pubkey_x448_get_pubkey(botan_pubkey_t key, uint8_t output[56]) { |
906 | | #if defined(BOTAN_HAS_X448) |
907 | | return BOTAN_FFI_VISIT(key, [=](const auto& k) { |
908 | | if(auto x448 = dynamic_cast<const Botan::X448_PublicKey*>(&k)) { |
909 | | const std::vector<uint8_t>& x448_key = x448->public_value(); |
910 | | Botan::copy_mem(std::span(output, 56), x448_key); |
911 | | return BOTAN_FFI_SUCCESS; |
912 | | } else { |
913 | | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
914 | | } |
915 | | }); |
916 | | #else |
917 | 0 | BOTAN_UNUSED(key, output); |
918 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
919 | 0 | #endif |
920 | 0 | } |
921 | | |
922 | | /* |
923 | | * Algorithm specific key operations: Kyber |
924 | | */ |
925 | | |
926 | 0 | int botan_privkey_load_kyber(botan_privkey_t* key, const uint8_t privkey[], size_t key_len) { |
927 | 0 | #if defined(BOTAN_HAS_KYBER) |
928 | 0 | *key = nullptr; |
929 | 0 | switch(key_len) { |
930 | 0 | case 1632: |
931 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
932 | 0 | const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 1632); |
933 | 0 | auto kyber512 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber512_R3); |
934 | 0 | *key = new botan_privkey_struct(std::move(kyber512)); |
935 | 0 | return BOTAN_FFI_SUCCESS; |
936 | 0 | }); |
937 | 0 | case 2400: |
938 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
939 | 0 | const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 2400); |
940 | 0 | auto kyber768 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber768_R3); |
941 | 0 | *key = new botan_privkey_struct(std::move(kyber768)); |
942 | 0 | return BOTAN_FFI_SUCCESS; |
943 | 0 | }); |
944 | 0 | case 3168: |
945 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
946 | 0 | const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 3168); |
947 | 0 | auto kyber1024 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber1024_R3); |
948 | 0 | *key = new botan_privkey_struct(std::move(kyber1024)); |
949 | 0 | return BOTAN_FFI_SUCCESS; |
950 | 0 | }); |
951 | 0 | default: |
952 | 0 | BOTAN_UNUSED(key, privkey, key_len); |
953 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
954 | 0 | } |
955 | | #else |
956 | | BOTAN_UNUSED(key, privkey); |
957 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
958 | | #endif |
959 | 0 | } |
960 | | |
961 | 0 | int botan_pubkey_load_kyber(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len) { |
962 | 0 | #if defined(BOTAN_HAS_KYBER) |
963 | 0 | *key = nullptr; |
964 | 0 | switch(key_len) { |
965 | 0 | case 800: |
966 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
967 | 0 | const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 800); |
968 | 0 | auto kyber512 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber512_R3); |
969 | 0 | *key = new botan_pubkey_struct(std::move(kyber512)); |
970 | 0 | return BOTAN_FFI_SUCCESS; |
971 | 0 | }); |
972 | 0 | case 1184: |
973 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
974 | 0 | const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1184); |
975 | 0 | auto kyber768 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber768_R3); |
976 | 0 | *key = new botan_pubkey_struct(std::move(kyber768)); |
977 | 0 | return BOTAN_FFI_SUCCESS; |
978 | 0 | }); |
979 | 0 | case 1568: |
980 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
981 | 0 | const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1568); |
982 | 0 | auto kyber1024 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber1024_R3); |
983 | 0 | *key = new botan_pubkey_struct(std::move(kyber1024)); |
984 | 0 | return BOTAN_FFI_SUCCESS; |
985 | 0 | }); |
986 | 0 | default: |
987 | 0 | BOTAN_UNUSED(key, pubkey, key_len); |
988 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
989 | 0 | } |
990 | | #else |
991 | | BOTAN_UNUSED(key, pubkey, key_len); |
992 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
993 | | #endif |
994 | 0 | } |
995 | | |
996 | 0 | int botan_privkey_view_kyber_raw_key(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) { |
997 | 0 | #if defined(BOTAN_HAS_KYBER) |
998 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int { |
999 | 0 | if(auto kyber = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k)) { |
1000 | 0 | return invoke_view_callback(view, ctx, kyber->raw_private_key_bits()); |
1001 | 0 | } else { |
1002 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
1003 | 0 | } |
1004 | 0 | }); |
1005 | | #else |
1006 | | BOTAN_UNUSED(key, ctx, view); |
1007 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
1008 | | #endif |
1009 | 0 | } |
1010 | | |
1011 | 0 | int botan_pubkey_view_kyber_raw_key(botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) { |
1012 | 0 | #if defined(BOTAN_HAS_KYBER) |
1013 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int { |
1014 | 0 | if(auto kyber = dynamic_cast<const Botan::Kyber_PublicKey*>(&k)) { |
1015 | 0 | return invoke_view_callback(view, ctx, kyber->public_key_bits()); |
1016 | 0 | } else { |
1017 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
1018 | 0 | } |
1019 | 0 | }); |
1020 | | #else |
1021 | | BOTAN_UNUSED(key, ctx, view); |
1022 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
1023 | | #endif |
1024 | 0 | } |
1025 | | |
1026 | 0 | int botan_pubkey_view_ec_public_point(const botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) { |
1027 | 0 | #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) |
1028 | 0 | return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int { |
1029 | 0 | if(auto ecc = dynamic_cast<const Botan::EC_PublicKey*>(&k)) { |
1030 | 0 | auto pt = ecc->public_point().encode(Botan::EC_Point_Format::Uncompressed); |
1031 | 0 | return invoke_view_callback(view, ctx, pt); |
1032 | 0 | } else { |
1033 | 0 | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
1034 | 0 | } |
1035 | 0 | }); |
1036 | | #else |
1037 | | BOTAN_UNUSED(key, view, ctx); |
1038 | | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
1039 | | #endif |
1040 | 0 | } |
1041 | | |
1042 | 0 | int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t) { |
1043 | 0 | const std::string mce_params = std::to_string(n) + "," + std::to_string(t); |
1044 | 0 | return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj); |
1045 | 0 | } |
1046 | | |
1047 | | int botan_mceies_decrypt(botan_privkey_t mce_key_obj, |
1048 | | const char* aead, |
1049 | | const uint8_t ct[], |
1050 | | size_t ct_len, |
1051 | | const uint8_t ad[], |
1052 | | size_t ad_len, |
1053 | | uint8_t out[], |
1054 | 0 | size_t* out_len) { |
1055 | 0 | BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len); |
1056 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
1057 | 0 | } |
1058 | | |
1059 | | int botan_mceies_encrypt(botan_pubkey_t mce_key_obj, |
1060 | | botan_rng_t rng_obj, |
1061 | | const char* aead, |
1062 | | const uint8_t pt[], |
1063 | | size_t pt_len, |
1064 | | const uint8_t ad[], |
1065 | | size_t ad_len, |
1066 | | uint8_t out[], |
1067 | 0 | size_t* out_len) { |
1068 | 0 | BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len); |
1069 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
1070 | 0 | } |
1071 | | } |