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

randombit / botan / 11087146043

28 Sep 2024 09:28PM UTC coverage: 92.003% (+0.7%) from 91.274%
11087146043

push

github

web-flow
Create terraform.yml

82959 of 90170 relevant lines covered (92.0%)

9376319.11 hits per line

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

97.96
/src/lib/ffi/ffi_pkey_algs.cpp
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_X25519)
51
   #include <botan/x25519.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
int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key, const Botan::BigInt& scalar, const char* curve_name) {
9✔
86
   if(curve_name == nullptr) {
9✔
87
      return BOTAN_FFI_ERROR_NULL_POINTER;
88
   }
89

90
   Botan::Null_RNG null_rng;
9✔
91
   Botan::EC_Group grp(curve_name);
9✔
92
   key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
9✔
93
   return BOTAN_FFI_SUCCESS;
94
}
9✔
95

96
template <class ECPublicKey_t>
97
int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
6✔
98
                   const Botan::BigInt& public_x,
99
                   const Botan::BigInt& public_y,
100
                   const char* curve_name) {
101
   if(curve_name == nullptr) {
6✔
102
      return BOTAN_FFI_ERROR_NULL_POINTER;
103
   }
104

105
   Botan::EC_Group grp(curve_name);
6✔
106
   Botan::EC_Point uncompressed_point = grp.point(public_x, public_y);
6✔
107
   key.reset(new ECPublicKey_t(grp, uncompressed_point));
6✔
108
   return BOTAN_FFI_SUCCESS;
109
}
6✔
110

111
#endif
112

113
Botan::BigInt pubkey_get_field(const Botan::Public_Key& key, std::string_view field) {
40✔
114
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
115
   // Not currently handled by get_int_field
116
   if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) {
40✔
117
      if(field == "public_x") {
21✔
118
         return ecc->public_point().get_affine_x();
8✔
119
      } else if(field == "public_y") {
7✔
120
         return ecc->public_point().get_affine_y();
6✔
121
      }
122
   }
123
#endif
124

125
   try {
26✔
126
      return key.get_int_field(field);
64✔
127
   } catch(Botan::Unknown_PK_Field_Name&) {
2✔
128
      throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER);
2✔
129
   }
2✔
130
}
131

132
Botan::BigInt privkey_get_field(const Botan::Private_Key& key, std::string_view field) {
35✔
133
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
134
   // Not currently handled by get_int_field
135
   if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) {
35✔
136
      if(field == "public_x") {
20✔
137
         return ecc->public_point().get_affine_x();
2✔
138
      } else if(field == "public_y") {
14✔
139
         return ecc->public_point().get_affine_y();
4✔
140
      }
141
   }
142
#endif
143

144
   try {
29✔
145
      return key.get_int_field(field);
60✔
146
   } catch(Botan::Unknown_PK_Field_Name&) {
4✔
147
      throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER);
4✔
148
   }
4✔
149
}
150

151
}  // namespace
152

153
extern "C" {
154

155
using namespace Botan_FFI;
156

157
int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char* field_name_cstr) {
40✔
158
   if(field_name_cstr == nullptr) {
40✔
159
      return BOTAN_FFI_ERROR_NULL_POINTER;
160
   }
161

162
   const std::string field_name(field_name_cstr);
40✔
163

164
   return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = pubkey_get_field(k, field_name); });
158✔
165
}
40✔
166

167
int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char* field_name_cstr) {
35✔
168
   if(field_name_cstr == nullptr) {
35✔
169
      return BOTAN_FFI_ERROR_NULL_POINTER;
170
   }
171

172
   const std::string field_name(field_name_cstr);
35✔
173

174
   return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = privkey_get_field(k, field_name); });
140✔
175
}
35✔
176

177
/* RSA specific operations */
178

179
int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits) {
1✔
180
   if(n_bits < 1024 || n_bits > 16 * 1024) {
1✔
181
      return BOTAN_FFI_ERROR_BAD_PARAMETER;
182
   }
183

184
   std::string n_str = std::to_string(n_bits);
1✔
185

186
   return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
1✔
187
}
1✔
188

189
int botan_privkey_load_rsa(botan_privkey_t* key, botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e) {
2✔
190
#if defined(BOTAN_HAS_RSA)
191
   *key = nullptr;
2✔
192

193
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
194
      auto rsa = std::make_unique<Botan::RSA_PrivateKey>(safe_get(rsa_p), safe_get(rsa_q), safe_get(rsa_e));
2✔
195
      *key = new botan_privkey_struct(std::move(rsa));
2✔
196
      return BOTAN_FFI_SUCCESS;
2✔
197
   });
4✔
198
#else
199
   BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
200
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
201
#endif
202
}
203

204
int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key, const uint8_t bits[], size_t len) {
1✔
205
#if defined(BOTAN_HAS_RSA)
206
   *key = nullptr;
1✔
207

208
   Botan::secure_vector<uint8_t> src(bits, bits + len);
1✔
209
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
210
      Botan::AlgorithmIdentifier alg_id("RSA", Botan::AlgorithmIdentifier::USE_NULL_PARAM);
1✔
211
      auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src);
1✔
212
      *key = new botan_privkey_struct(std::move(rsa));
1✔
213
      return BOTAN_FFI_SUCCESS;
1✔
214
   });
1✔
215
#else
216
   BOTAN_UNUSED(key, bits, len);
217
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
218
#endif
219
}
1✔
220

221
int botan_pubkey_load_rsa(botan_pubkey_t* key, botan_mp_t n, botan_mp_t e) {
4✔
222
#if defined(BOTAN_HAS_RSA)
223
   *key = nullptr;
4✔
224
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
225
      auto rsa = std::make_unique<Botan::RSA_PublicKey>(safe_get(n), safe_get(e));
4✔
226
      *key = new botan_pubkey_struct(std::move(rsa));
6✔
227
      return BOTAN_FFI_SUCCESS;
3✔
228
   });
7✔
229
#else
230
   BOTAN_UNUSED(key, n, e);
231
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
232
#endif
233
}
234

235
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key) {
1✔
236
   return botan_privkey_get_field(p, key, "p");
1✔
237
}
238

239
int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key) {
1✔
240
   return botan_privkey_get_field(q, key, "q");
1✔
241
}
242

243
int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key) {
1✔
244
   return botan_privkey_get_field(n, key, "n");
1✔
245
}
246

247
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key) {
1✔
248
   return botan_privkey_get_field(e, key, "e");
1✔
249
}
250

251
int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key) {
1✔
252
   return botan_privkey_get_field(d, key, "d");
1✔
253
}
254

255
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key) {
1✔
256
   return botan_pubkey_get_field(e, key, "e");
1✔
257
}
258

259
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key) {
1✔
260
   return botan_pubkey_get_field(n, key, "n");
1✔
261
}
262

263
int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t* out_len, uint32_t flags) {
4✔
264
#if defined(BOTAN_HAS_RSA)
265
   return BOTAN_FFI_VISIT(rsa_key, [=](const auto& k) -> int {
16✔
266
      if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k)) {
267
         if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER)
268
            return write_vec_output(out, out_len, rsa->private_key_bits());
269
         else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
270
            return write_str_output(out, out_len, Botan::PEM_Code::encode(rsa->private_key_bits(), "RSA PRIVATE KEY"));
271
         else
272
            return BOTAN_FFI_ERROR_BAD_FLAG;
273
      } else {
274
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
275
      }
276
   });
277
#else
278
   BOTAN_UNUSED(rsa_key, out, out_len, flags);
279
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
280
#endif
281
}
282

283
/* DSA specific operations */
284
int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) {
1✔
285
#if defined(BOTAN_HAS_DSA)
286

287
   if((rng_obj == nullptr) || (key == nullptr)) {
1✔
288
      return BOTAN_FFI_ERROR_NULL_POINTER;
289
   }
290

291
   if((pbits % 64) || (qbits % 8) || (pbits < 1024) || (pbits > 3072) || (qbits < 160) || (qbits > 256)) {
1✔
292
      return BOTAN_FFI_ERROR_BAD_PARAMETER;
293
   }
294

295
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
296
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
1✔
297
      Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits);
1✔
298
      auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
1✔
299
      *key = new botan_privkey_struct(std::move(dsa));
2✔
300
      return BOTAN_FFI_SUCCESS;
2✔
301
   });
2✔
302
#else
303
   BOTAN_UNUSED(key, rng_obj, pbits, qbits);
304
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
305
#endif
306
}
307

308
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) {
2✔
309
#if defined(BOTAN_HAS_DSA)
310
   *key = nullptr;
2✔
311

312
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
313
      Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
2✔
314
      auto dsa = std::make_unique<Botan::DSA_PrivateKey>(group, safe_get(x));
2✔
315
      *key = new botan_privkey_struct(std::move(dsa));
4✔
316
      return BOTAN_FFI_SUCCESS;
4✔
317
   });
6✔
318
#else
319
   BOTAN_UNUSED(key, p, q, g, x);
320
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
321
#endif
322
}
323

324
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) {
2✔
325
#if defined(BOTAN_HAS_DSA)
326
   *key = nullptr;
2✔
327

328
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
329
      Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
2✔
330
      auto dsa = std::make_unique<Botan::DSA_PublicKey>(group, safe_get(y));
2✔
331
      *key = new botan_pubkey_struct(std::move(dsa));
4✔
332
      return BOTAN_FFI_SUCCESS;
2✔
333
   });
6✔
334
#else
335
   BOTAN_UNUSED(key, p, q, g, y);
336
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
337
#endif
338
}
339

340
int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key) {
2✔
341
   return botan_privkey_get_field(x, key, "x");
2✔
342
}
343

344
int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key) {
2✔
345
   return botan_pubkey_get_field(p, key, "p");
2✔
346
}
347

348
int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key) {
2✔
349
   return botan_pubkey_get_field(q, key, "q");
2✔
350
}
351

352
int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key) {
2✔
353
   return botan_pubkey_get_field(g, key, "g");
2✔
354
}
355

356
int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key) {
2✔
357
   return botan_pubkey_get_field(y, key, "y");
2✔
358
}
359

360
int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
1✔
361
   return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
1✔
362
}
363

364
/* ECDSA specific operations */
365

366
int botan_pubkey_ecc_key_used_explicit_encoding(botan_pubkey_t key) {
1✔
367
#if defined(BOTAN_HAS_ECC_KEY)
368
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
369
      const Botan::Public_Key& pub_key = safe_get(key);
1✔
370
      const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
1✔
371

372
      if(ec_key == nullptr) {
1✔
373
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
374
      }
375

376
      return ec_key->domain().used_explicit_encoding() ? 1 : 0;
1✔
377
   });
1✔
378
#else
379
   BOTAN_UNUSED(key);
380
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
381
#endif
382
}
383

384
int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
2✔
385
                            const botan_mp_t public_x,
386
                            const botan_mp_t public_y,
387
                            const char* curve_name) {
388
#if defined(BOTAN_HAS_ECDSA)
389
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
390
      std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
2✔
391

392
      int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
2✔
393
      if(rc == BOTAN_FFI_SUCCESS) {
2✔
394
         *key = new botan_pubkey_struct(std::move(p_key));
4✔
395
      }
396

397
      return rc;
2✔
398
   });
4✔
399
#else
400
   BOTAN_UNUSED(key, public_x, public_y, curve_name);
401
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
402
#endif
403
}
404

405
int botan_privkey_load_ecdsa(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
2✔
406
#if defined(BOTAN_HAS_ECDSA)
407
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
408
      std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
2✔
409
      int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
2✔
410
      if(rc == BOTAN_FFI_SUCCESS) {
2✔
411
         *key = new botan_privkey_struct(std::move(p_key));
4✔
412
      }
413
      return rc;
2✔
414
   });
4✔
415
#else
416
   BOTAN_UNUSED(key, scalar, curve_name);
417
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
418
#endif
419
}
420

421
/* ElGamal specific operations */
422
int botan_privkey_create_elgamal(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) {
1✔
423
#if defined(BOTAN_HAS_ELGAMAL)
424

425
   if((rng_obj == nullptr) || (key == nullptr)) {
1✔
426
      return BOTAN_FFI_ERROR_NULL_POINTER;
427
   }
428

429
   if((pbits < 1024) || (qbits < 160)) {
1✔
430
      return BOTAN_FFI_ERROR_BAD_PARAMETER;
431
   }
432

433
   Botan::DL_Group::PrimeType prime_type =
1✔
434
      ((pbits - 1) == qbits) ? Botan::DL_Group::Strong : Botan::DL_Group::Prime_Subgroup;
1✔
435

436
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
437
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
1✔
438
      Botan::DL_Group group(rng, prime_type, pbits, qbits);
1✔
439
      auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
1✔
440
      *key = new botan_privkey_struct(std::move(elg));
2✔
441
      return BOTAN_FFI_SUCCESS;
2✔
442
   });
2✔
443
#else
444
   BOTAN_UNUSED(key, rng_obj, pbits, qbits);
445
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
446
#endif
447
}
448

449
int botan_pubkey_load_elgamal(botan_pubkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t y) {
2✔
450
#if defined(BOTAN_HAS_ELGAMAL)
451
   *key = nullptr;
2✔
452
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
453
      Botan::DL_Group group(safe_get(p), safe_get(g));
2✔
454
      auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group, safe_get(y));
2✔
455
      *key = new botan_pubkey_struct(std::move(elg));
4✔
456
      return BOTAN_FFI_SUCCESS;
2✔
457
   });
6✔
458
#else
459
   BOTAN_UNUSED(key, p, g, y);
460
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
461
#endif
462
}
463

464
int botan_privkey_load_elgamal(botan_privkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t x) {
2✔
465
#if defined(BOTAN_HAS_ELGAMAL)
466
   *key = nullptr;
2✔
467
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
468
      Botan::DL_Group group(safe_get(p), safe_get(g));
2✔
469
      auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(group, safe_get(x));
2✔
470
      *key = new botan_privkey_struct(std::move(elg));
4✔
471
      return BOTAN_FFI_SUCCESS;
4✔
472
   });
6✔
473
#else
474
   BOTAN_UNUSED(key, p, g, x);
475
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
476
#endif
477
}
478

479
/* Diffie Hellman specific operations */
480

481
int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
2✔
482
   return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
2✔
483
}
484

485
int botan_privkey_load_dh(botan_privkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t x) {
1✔
486
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
487
   *key = nullptr;
1✔
488
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
489
      Botan::DL_Group group(safe_get(p), safe_get(g));
1✔
490
      auto dh = std::make_unique<Botan::DH_PrivateKey>(group, safe_get(x));
1✔
491
      *key = new botan_privkey_struct(std::move(dh));
2✔
492
      return BOTAN_FFI_SUCCESS;
2✔
493
   });
3✔
494
#else
495
   BOTAN_UNUSED(key, p, g, x);
496
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
497
#endif
498
}
499

500
int botan_pubkey_load_dh(botan_pubkey_t* key, botan_mp_t p, botan_mp_t g, botan_mp_t y) {
1✔
501
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
502
   *key = nullptr;
1✔
503
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
504
      Botan::DL_Group group(safe_get(p), safe_get(g));
1✔
505
      auto dh = std::make_unique<Botan::DH_PublicKey>(group, safe_get(y));
1✔
506
      *key = new botan_pubkey_struct(std::move(dh));
2✔
507
      return BOTAN_FFI_SUCCESS;
1✔
508
   });
3✔
509
#else
510
   BOTAN_UNUSED(key, p, g, y);
511
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
512
#endif
513
}
514

515
/* ECDH + x25519/x448 specific operations */
516

517
int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
2✔
518
   if(param_str == nullptr) {
2✔
519
      return BOTAN_FFI_ERROR_NULL_POINTER;
520
   }
521

522
   const std::string params(param_str);
2✔
523

524
   if(params == "x25519" || params == "curve25519") {
2✔
525
      return botan_privkey_create(key_obj, "X25519", "", rng_obj);
×
526
   }
527

528
   if(params == "x448") {
2✔
529
      return botan_privkey_create(key_obj, "X448", "", rng_obj);
×
530
   }
531

532
   return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
2✔
533
}
2✔
534

535
int botan_pubkey_load_ecdh(botan_pubkey_t* key,
1✔
536
                           const botan_mp_t public_x,
537
                           const botan_mp_t public_y,
538
                           const char* curve_name) {
539
#if defined(BOTAN_HAS_ECDH)
540
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
541
      std::unique_ptr<Botan::ECDH_PublicKey> p_key;
1✔
542
      int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
1✔
543

544
      if(rc == BOTAN_FFI_SUCCESS) {
1✔
545
         *key = new botan_pubkey_struct(std::move(p_key));
2✔
546
      }
547
      return rc;
1✔
548
   });
2✔
549
#else
550
   BOTAN_UNUSED(key, public_x, public_y, curve_name);
551
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
552
#endif
553
}
554

555
int botan_privkey_load_ecdh(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
4✔
556
#if defined(BOTAN_HAS_ECDH)
557
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
558
      std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
4✔
559
      int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
4✔
560
      if(rc == BOTAN_FFI_SUCCESS) {
4✔
561
         *key = new botan_privkey_struct(std::move(p_key));
8✔
562
      }
563
      return rc;
4✔
564
   });
8✔
565
#else
566
   BOTAN_UNUSED(key, scalar, curve_name);
567
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
568
#endif
569
}
570

571
/* SM2 specific operations */
572

573
int botan_pubkey_sm2_compute_za(
2✔
574
   uint8_t out[], size_t* out_len, const char* ident, const char* hash_algo, const botan_pubkey_t key) {
575
   if(out == nullptr || out_len == nullptr) {
2✔
576
      return BOTAN_FFI_ERROR_NULL_POINTER;
577
   }
578
   if(ident == nullptr || hash_algo == nullptr || key == nullptr) {
2✔
579
      return BOTAN_FFI_ERROR_NULL_POINTER;
580
   }
581

582
#if defined(BOTAN_HAS_SM2)
583
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
584
      const Botan::Public_Key& pub_key = safe_get(key);
2✔
585
      const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
2✔
586

587
      if(ec_key == nullptr) {
2✔
588
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
589
      }
590

591
      if(ec_key->algo_name() != "SM2") {
2✔
592
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
593
      }
594

595
      const std::string ident_str(ident);
2✔
596
      std::unique_ptr<Botan::HashFunction> hash = Botan::HashFunction::create_or_throw(hash_algo);
2✔
597

598
      const std::vector<uint8_t> za = Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
2✔
599

600
      return write_vec_output(out, out_len, za);
2✔
601
   });
6✔
602
#else
603
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
604
#endif
605
}
606

607
int botan_pubkey_load_sm2(botan_pubkey_t* key,
3✔
608
                          const botan_mp_t public_x,
609
                          const botan_mp_t public_y,
610
                          const char* curve_name) {
611
#if defined(BOTAN_HAS_SM2)
612
   return ffi_guard_thunk(__func__, [=]() -> int {
3✔
613
      std::unique_ptr<Botan::SM2_PublicKey> p_key;
3✔
614
      if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name)) {
3✔
615
         *key = new botan_pubkey_struct(std::move(p_key));
6✔
616
         return BOTAN_FFI_SUCCESS;
3✔
617
      }
618
      return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
619
   });
6✔
620
#else
621
   BOTAN_UNUSED(key, public_x, public_y, curve_name);
622
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
623
#endif
624
}
625

626
int botan_privkey_load_sm2(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
3✔
627
#if defined(BOTAN_HAS_SM2)
628
   return ffi_guard_thunk(__func__, [=]() -> int {
3✔
629
      std::unique_ptr<Botan::SM2_PrivateKey> p_key;
3✔
630
      int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
3✔
631

632
      if(rc == BOTAN_FFI_SUCCESS) {
3✔
633
         *key = new botan_privkey_struct(std::move(p_key));
6✔
634
      }
635
      return rc;
3✔
636
   });
6✔
637
#else
638
   BOTAN_UNUSED(key, scalar, curve_name);
639
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
640
#endif
641
}
642

643
int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
1✔
644
                              const botan_mp_t public_x,
645
                              const botan_mp_t public_y,
646
                              const char* curve_name) {
647
   return botan_pubkey_load_sm2(key, public_x, public_y, curve_name);
1✔
648
}
649

650
int botan_privkey_load_sm2_enc(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
1✔
651
   return botan_privkey_load_sm2(key, scalar, curve_name);
1✔
652
}
653

654
/* Ed25519 specific operations */
655

656
int botan_privkey_load_ed25519(botan_privkey_t* key, const uint8_t privkey[32]) {
1✔
657
#if defined(BOTAN_HAS_ED25519)
658
   *key = nullptr;
1✔
659
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
660
      const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
1✔
661
      auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec);
1✔
662
      *key = new botan_privkey_struct(std::move(ed25519));
2✔
663
      return BOTAN_FFI_SUCCESS;
2✔
664
   });
3✔
665
#else
666
   BOTAN_UNUSED(key, privkey);
667
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
668
#endif
669
}
670

671
int botan_pubkey_load_ed25519(botan_pubkey_t* key, const uint8_t pubkey[32]) {
1✔
672
#if defined(BOTAN_HAS_ED25519)
673
   *key = nullptr;
1✔
674
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
675
      const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
1✔
676
      auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
1✔
677
      *key = new botan_pubkey_struct(std::move(ed25519));
2✔
678
      return BOTAN_FFI_SUCCESS;
1✔
679
   });
3✔
680
#else
681
   BOTAN_UNUSED(key, pubkey);
682
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
683
#endif
684
}
685

686
int botan_privkey_ed25519_get_privkey(botan_privkey_t key, uint8_t output[64]) {
1✔
687
#if defined(BOTAN_HAS_ED25519)
688
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
4✔
689
      if(auto ed = dynamic_cast<const Botan::Ed25519_PrivateKey*>(&k)) {
690
         const auto ed_key = ed->raw_private_key_bits();
691
         if(ed_key.size() != 64)
692
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
693
         Botan::copy_mem(output, ed_key.data(), ed_key.size());
694
         return BOTAN_FFI_SUCCESS;
695
      } else {
696
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
697
      }
698
   });
699
#else
700
   BOTAN_UNUSED(key, output);
701
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
702
#endif
703
}
704

705
int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key, uint8_t output[32]) {
1✔
706
#if defined(BOTAN_HAS_ED25519)
707
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
2✔
708
      if(auto ed = dynamic_cast<const Botan::Ed25519_PublicKey*>(&k)) {
709
         const std::vector<uint8_t>& ed_key = ed->get_public_key();
710
         if(ed_key.size() != 32)
711
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
712
         Botan::copy_mem(output, ed_key.data(), ed_key.size());
713
         return BOTAN_FFI_SUCCESS;
714
      } else {
715
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
716
      }
717
   });
718
#else
719
   BOTAN_UNUSED(key, output);
720
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
721
#endif
722
}
723

724
/* Ed448 specific operations */
725

726
int botan_privkey_load_ed448(botan_privkey_t* key, const uint8_t privkey[57]) {
1✔
727
#if defined(BOTAN_HAS_ED448)
728
   *key = nullptr;
1✔
729
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
730
      auto ed448 = std::make_unique<Botan::Ed448_PrivateKey>(std::span(privkey, 57));
1✔
731
      *key = new botan_privkey_struct(std::move(ed448));
2✔
732
      return BOTAN_FFI_SUCCESS;
1✔
733
   });
2✔
734
#else
735
   BOTAN_UNUSED(key, privkey);
736
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
737
#endif
738
}
739

740
int botan_pubkey_load_ed448(botan_pubkey_t* key, const uint8_t pubkey[57]) {
1✔
741
#if defined(BOTAN_HAS_ED448)
742
   *key = nullptr;
1✔
743
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
744
      auto ed448 = std::make_unique<Botan::Ed448_PublicKey>(std::span(pubkey, 57));
1✔
745
      *key = new botan_pubkey_struct(std::move(ed448));
2✔
746
      return BOTAN_FFI_SUCCESS;
1✔
747
   });
2✔
748
#else
749
   BOTAN_UNUSED(key, pubkey);
750
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
751
#endif
752
}
753

754
int botan_privkey_ed448_get_privkey(botan_privkey_t key, uint8_t output[57]) {
1✔
755
#if defined(BOTAN_HAS_ED448)
756
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
4✔
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
   BOTAN_UNUSED(key, output);
767
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
768
#endif
769
}
770

771
int botan_pubkey_ed448_get_pubkey(botan_pubkey_t key, uint8_t output[57]) {
1✔
772
#if defined(BOTAN_HAS_ED448)
773
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
3✔
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
   BOTAN_UNUSED(key, output);
784
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
785
#endif
786
}
787

788
/* X25519 specific operations */
789

790
int botan_privkey_load_x25519(botan_privkey_t* key, const uint8_t privkey[32]) {
1✔
791
#if defined(BOTAN_HAS_X25519)
792
   *key = nullptr;
1✔
793
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
794
      const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
1✔
795
      auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(privkey_vec);
1✔
796
      *key = new botan_privkey_struct(std::move(x25519));
2✔
797
      return BOTAN_FFI_SUCCESS;
2✔
798
   });
3✔
799
#else
800
   BOTAN_UNUSED(key, privkey);
801
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
802
#endif
803
}
804

805
int botan_pubkey_load_x25519(botan_pubkey_t* key, const uint8_t pubkey[32]) {
1✔
806
#if defined(BOTAN_HAS_X25519)
807
   *key = nullptr;
1✔
808
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
809
      const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
1✔
810
      auto x25519 = std::make_unique<Botan::X25519_PublicKey>(pubkey_vec);
1✔
811
      *key = new botan_pubkey_struct(std::move(x25519));
2✔
812
      return BOTAN_FFI_SUCCESS;
1✔
813
   });
3✔
814
#else
815
   BOTAN_UNUSED(key, pubkey);
816
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
817
#endif
818
}
819

820
int botan_privkey_x25519_get_privkey(botan_privkey_t key, uint8_t output[32]) {
1✔
821
#if defined(BOTAN_HAS_X25519)
822
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
4✔
823
      if(auto x25519 = dynamic_cast<const Botan::X25519_PrivateKey*>(&k)) {
824
         const auto x25519_key = x25519->raw_private_key_bits();
825
         if(x25519_key.size() != 32)
826
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
827
         Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
828
         return BOTAN_FFI_SUCCESS;
829
      } else {
830
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
831
      }
832
   });
833
#else
834
   BOTAN_UNUSED(key, output);
835
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
836
#endif
837
}
838

839
int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key, uint8_t output[32]) {
2✔
840
#if defined(BOTAN_HAS_X25519)
841
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
8✔
842
      if(auto x25519 = dynamic_cast<const Botan::X25519_PublicKey*>(&k)) {
843
         const std::vector<uint8_t>& x25519_key = x25519->public_value();
844
         if(x25519_key.size() != 32)
845
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
846
         Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
847
         return BOTAN_FFI_SUCCESS;
848
      } else {
849
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
850
      }
851
   });
852
#else
853
   BOTAN_UNUSED(key, output);
854
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
855
#endif
856
}
857

858
/* X448 specific operations */
859

860
int botan_privkey_load_x448(botan_privkey_t* key, const uint8_t privkey[56]) {
1✔
861
#if defined(BOTAN_HAS_X448)
862
   *key = nullptr;
1✔
863
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
864
      auto x448 = std::make_unique<Botan::X448_PrivateKey>(std::span(privkey, 56));
1✔
865
      *key = new botan_privkey_struct(std::move(x448));
2✔
866
      return BOTAN_FFI_SUCCESS;
1✔
867
   });
2✔
868
#else
869
   BOTAN_UNUSED(key, privkey);
870
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
871
#endif
872
}
873

874
int botan_pubkey_load_x448(botan_pubkey_t* key, const uint8_t pubkey[56]) {
1✔
875
#if defined(BOTAN_HAS_X448)
876
   *key = nullptr;
1✔
877
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
878
      auto x448 = std::make_unique<Botan::X448_PublicKey>(std::span(pubkey, 56));
1✔
879
      *key = new botan_pubkey_struct(std::move(x448));
2✔
880
      return BOTAN_FFI_SUCCESS;
1✔
881
   });
2✔
882
#else
883
   BOTAN_UNUSED(key, pubkey);
884
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
885
#endif
886
}
887

888
int botan_privkey_x448_get_privkey(botan_privkey_t key, uint8_t output[56]) {
1✔
889
#if defined(BOTAN_HAS_X448)
890
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
4✔
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
   BOTAN_UNUSED(key, output);
901
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
902
#endif
903
}
904

905
int botan_pubkey_x448_get_pubkey(botan_pubkey_t key, uint8_t output[56]) {
2✔
906
#if defined(BOTAN_HAS_X448)
907
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
8✔
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
   BOTAN_UNUSED(key, output);
918
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
919
#endif
920
}
921

922
/*
923
* Algorithm specific key operations: Kyber
924
*/
925

926
int botan_privkey_load_kyber(botan_privkey_t* key, const uint8_t privkey[], size_t key_len) {
4✔
927
#if defined(BOTAN_HAS_KYBER)
928
   *key = nullptr;
4✔
929
   switch(key_len) {
4✔
930
      case 1632:
1✔
931
         return ffi_guard_thunk(__func__, [=]() -> int {
2✔
932
            const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 1632);
1✔
933
            auto kyber512 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber512_R3);
1✔
934
            *key = new botan_privkey_struct(std::move(kyber512));
1✔
935
            return BOTAN_FFI_SUCCESS;
2✔
936
         });
2✔
937
      case 2400:
2✔
938
         return ffi_guard_thunk(__func__, [=]() -> int {
4✔
939
            const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 2400);
2✔
940
            auto kyber768 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber768_R3);
2✔
941
            *key = new botan_privkey_struct(std::move(kyber768));
2✔
942
            return BOTAN_FFI_SUCCESS;
4✔
943
         });
4✔
944
      case 3168:
1✔
945
         return ffi_guard_thunk(__func__, [=]() -> int {
2✔
946
            const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 3168);
1✔
947
            auto kyber1024 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber1024_R3);
1✔
948
            *key = new botan_privkey_struct(std::move(kyber1024));
1✔
949
            return BOTAN_FFI_SUCCESS;
2✔
950
         });
2✔
951
      default:
952
         BOTAN_UNUSED(key, privkey, key_len);
953
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
954
   }
955
#else
956
   BOTAN_UNUSED(key, privkey);
957
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
958
#endif
959
}
960

961
int botan_pubkey_load_kyber(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len) {
4✔
962
#if defined(BOTAN_HAS_KYBER)
963
   *key = nullptr;
4✔
964
   switch(key_len) {
4✔
965
      case 800:
1✔
966
         return ffi_guard_thunk(__func__, [=]() -> int {
2✔
967
            const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 800);
1✔
968
            auto kyber512 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber512_R3);
1✔
969
            *key = new botan_pubkey_struct(std::move(kyber512));
2✔
970
            return BOTAN_FFI_SUCCESS;
1✔
971
         });
2✔
972
      case 1184:
2✔
973
         return ffi_guard_thunk(__func__, [=]() -> int {
4✔
974
            const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1184);
2✔
975
            auto kyber768 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber768_R3);
2✔
976
            *key = new botan_pubkey_struct(std::move(kyber768));
4✔
977
            return BOTAN_FFI_SUCCESS;
2✔
978
         });
4✔
979
      case 1568:
1✔
980
         return ffi_guard_thunk(__func__, [=]() -> int {
2✔
981
            const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1568);
1✔
982
            auto kyber1024 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber1024_R3);
1✔
983
            *key = new botan_pubkey_struct(std::move(kyber1024));
2✔
984
            return BOTAN_FFI_SUCCESS;
1✔
985
         });
2✔
986
      default:
987
         BOTAN_UNUSED(key, pubkey, key_len);
988
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
989
   }
990
#else
991
   BOTAN_UNUSED(key, pubkey, key_len);
992
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
993
#endif
994
}
995

996
int botan_privkey_view_kyber_raw_key(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
4✔
997
#if defined(BOTAN_HAS_KYBER)
998
   return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
12✔
999
      if(auto kyber = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k)) {
1000
         return invoke_view_callback(view, ctx, kyber->raw_private_key_bits());
1001
      } else {
1002
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1003
      }
1004
   });
1005
#else
1006
   BOTAN_UNUSED(key, ctx, view);
1007
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1008
#endif
1009
}
1010

1011
int botan_pubkey_view_kyber_raw_key(botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
8✔
1012
#if defined(BOTAN_HAS_KYBER)
1013
   return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
24✔
1014
      if(auto kyber = dynamic_cast<const Botan::Kyber_PublicKey*>(&k)) {
1015
         return invoke_view_callback(view, ctx, kyber->public_key_bits());
1016
      } else {
1017
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1018
      }
1019
   });
1020
#else
1021
   BOTAN_UNUSED(key, ctx, view);
1022
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1023
#endif
1024
}
1025

1026
int botan_pubkey_view_ec_public_point(const botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
6✔
1027
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
1028
   return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
18✔
1029
      if(auto ecc = dynamic_cast<const Botan::EC_PublicKey*>(&k)) {
1030
         auto pt = ecc->public_point().encode(Botan::EC_Point_Format::Uncompressed);
1031
         return invoke_view_callback(view, ctx, pt);
1032
      } else {
1033
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1034
      }
1035
   });
1036
#else
1037
   BOTAN_UNUSED(key, view, ctx);
1038
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1039
#endif
1040
}
1041

1042
int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t) {
1✔
1043
   const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
2✔
1044
   return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
1✔
1045
}
1✔
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
                         size_t* out_len) {
1055
   BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
×
1056
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
×
1057
}
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
                         size_t* out_len) {
1068
   BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
×
1069
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
×
1070
}
1071
}
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