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

randombit / botan / 5036343463

22 May 2023 04:34PM UTC coverage: 91.682% (-0.04%) from 91.723%
5036343463

Pull #3546

github

Pull Request #3546: expose kyber 512/768/1024 in the ffi interface

77705 of 84755 relevant lines covered (91.68%)

12387067.83 hits per line

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

87.02
/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_util.h>
14
#include <botan/internal/ffi_pkey.h>
15
#include <botan/internal/ffi_rng.h>
16
#include <botan/internal/ffi_mp.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_ED25519)
55
  #include <botan/ed25519.h>
56
#endif
57

58
#if defined(BOTAN_HAS_MCELIECE)
59
  #include <botan/mceliece.h>
60
#endif
61

62
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
63
  #include <botan/dh.h>
64
#endif
65

66
#if defined(BOTAN_HAS_KYBER)
67
   #include <botan/kyber.h>
68
#endif
69

70
namespace {
71

72
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
73

74
// These are always called within an existing try/catch block
75

76
template<class ECPrivateKey_t>
77
int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
9✔
78
                    const Botan::BigInt& scalar,
79
                    const char* curve_name)
80
   {
81
   if(curve_name == nullptr)
9✔
82
      return BOTAN_FFI_ERROR_NULL_POINTER;
83

84
   Botan::Null_RNG null_rng;
9✔
85
   Botan::EC_Group grp(curve_name);
9✔
86
   key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
9✔
87
   return BOTAN_FFI_SUCCESS;
88
   }
9✔
89

90
template<class ECPublicKey_t>
91
int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
6✔
92
                   const Botan::BigInt& public_x,
93
                   const Botan::BigInt& public_y,
94
                   const char* curve_name)
95
   {
96
   if(curve_name == nullptr)
6✔
97
      return BOTAN_FFI_ERROR_NULL_POINTER;
98

99
   Botan::EC_Group grp(curve_name);
6✔
100
   Botan::EC_Point uncompressed_point = grp.point(public_x, public_y);
6✔
101
   key.reset(new ECPublicKey_t(grp, uncompressed_point));
6✔
102
   return BOTAN_FFI_SUCCESS;
103
   }
6✔
104

105
#endif
106

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

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

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

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

155
}
156

157
extern "C" {
158

159
using namespace Botan_FFI;
160

161
int botan_pubkey_get_field(botan_mp_t output,
40✔
162
                           botan_pubkey_t key,
163
                           const char* field_name_cstr)
164
   {
165
   if(field_name_cstr == nullptr)
40✔
166
      return BOTAN_FFI_ERROR_NULL_POINTER;
167

168
   const std::string field_name(field_name_cstr);
40✔
169

170
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
158✔
171
      safe_get(output) = pubkey_get_field(k, field_name);
172
      });
173
   }
40✔
174

175
int botan_privkey_get_field(botan_mp_t output,
35✔
176
                            botan_privkey_t key,
177
                            const char* field_name_cstr)
178
   {
179
   if(field_name_cstr == nullptr)
35✔
180
      return BOTAN_FFI_ERROR_NULL_POINTER;
181

182
   const std::string field_name(field_name_cstr);
35✔
183

184
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
140✔
185
      safe_get(output) = privkey_get_field(k, field_name);
186
      });
187
   }
35✔
188

189
/* RSA specific operations */
190

191
int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits)
1✔
192
   {
193
   if(n_bits < 1024 || n_bits > 16*1024)
1✔
194
      return BOTAN_FFI_ERROR_BAD_PARAMETER;
195

196
   std::string n_str = std::to_string(n_bits);
1✔
197

198
   return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
1✔
199
   }
1✔
200

201
int botan_privkey_load_rsa(botan_privkey_t* key,
2✔
202
                           botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
203
   {
204
#if defined(BOTAN_HAS_RSA)
205
   *key = nullptr;
2✔
206

207
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
208

209
      auto rsa = std::make_unique<Botan::RSA_PrivateKey>(safe_get(rsa_p),
4✔
210
                                                         safe_get(rsa_q),
2✔
211
                                                         safe_get(rsa_e));
2✔
212
      *key = new botan_privkey_struct(std::move(rsa));
2✔
213
      return BOTAN_FFI_SUCCESS;
2✔
214
      });
4✔
215
#else
216
   BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
217
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
218
#endif
219
   }
220

221
int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key,
1✔
222
                                 const uint8_t bits[],
223
                                 size_t len)
224
   {
225
#if defined(BOTAN_HAS_RSA)
226
   *key = nullptr;
1✔
227

228
   Botan::secure_vector<uint8_t> src(bits, bits + len);
1✔
229
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
230
      Botan::AlgorithmIdentifier alg_id("RSA", Botan::AlgorithmIdentifier::USE_NULL_PARAM);
1✔
231
      auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src);
1✔
232
      *key = new botan_privkey_struct(std::move(rsa));
1✔
233
      return BOTAN_FFI_SUCCESS;
1✔
234
      });
1✔
235
#else
236
   BOTAN_UNUSED(key, bits, len);
237
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
238
#endif
239
   }
1✔
240

241
int botan_pubkey_load_rsa(botan_pubkey_t* key,
4✔
242
                          botan_mp_t n, botan_mp_t e)
243
   {
244
#if defined(BOTAN_HAS_RSA)
245
   *key = nullptr;
4✔
246
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
247
      auto rsa = std::make_unique<Botan::RSA_PublicKey>(safe_get(n), safe_get(e));
4✔
248
      *key = new botan_pubkey_struct(std::move(rsa));
6✔
249
      return BOTAN_FFI_SUCCESS;
3✔
250
      });
7✔
251
#else
252
   BOTAN_UNUSED(key, n, e);
253
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
254
#endif
255
   }
256

257
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
1✔
258
   {
259
   return botan_privkey_get_field(p, key, "p");
1✔
260
   }
261

262
int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
1✔
263
   {
264
   return botan_privkey_get_field(q, key, "q");
1✔
265
   }
266

267
int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
1✔
268
   {
269
   return botan_privkey_get_field(n, key, "n");
1✔
270
   }
271

272
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
1✔
273
   {
274
   return botan_privkey_get_field(e, key, "e");
1✔
275
   }
276

277
int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
1✔
278
   {
279
   return botan_privkey_get_field(d, key, "d");
1✔
280
   }
281

282
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key)
1✔
283
   {
284
   return botan_pubkey_get_field(e, key, "e");
1✔
285
   }
286

287
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
1✔
288
   {
289
   return botan_pubkey_get_field(n, key, "n");
1✔
290
   }
291

292
int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key,
4✔
293
                                  uint8_t out[], size_t* out_len,
294
                                  uint32_t flags)
295
   {
296
#if defined(BOTAN_HAS_RSA)
297
   return BOTAN_FFI_VISIT(rsa_key, [=](const auto& k) -> int {
16✔
298
      if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k))
299
         {
300
         if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER)
301
            return write_vec_output(out, out_len, rsa->private_key_bits());
302
         else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
303
            return write_str_output(out, out_len, Botan::PEM_Code::encode(rsa->private_key_bits(),
304
                  "RSA PRIVATE KEY"));
305
         else
306
            return BOTAN_FFI_ERROR_BAD_FLAG;
307
         }
308
      else
309
         {
310
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
311
         }
312
      });
313
#else
314
   BOTAN_UNUSED(rsa_key, out, out_len, flags);
315
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
316
#endif
317
   }
318

319
/* DSA specific operations */
320
int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
1✔
321
   {
322
#if defined(BOTAN_HAS_DSA)
323

324
    if ((rng_obj == nullptr) || (key == nullptr))
1✔
325
      return BOTAN_FFI_ERROR_NULL_POINTER;
326

327
    if ((pbits % 64) || (qbits % 8) ||
1✔
328
        (pbits < 1024) || (pbits > 3072) ||
1✔
329
        (qbits < 160) || (qbits > 256)) {
1✔
330
      return BOTAN_FFI_ERROR_BAD_PARAMETER;
331
    }
332

333
    return ffi_guard_thunk(__func__, [=]() -> int {
2✔
334
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
1✔
335
      Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits);
1✔
336
      auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
1✔
337
      *key = new botan_privkey_struct(std::move(dsa));
2✔
338
      return BOTAN_FFI_SUCCESS;
2✔
339
    });
2✔
340
#else
341
    BOTAN_UNUSED(key, rng_obj, pbits, qbits);
342
    return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
343
#endif
344
   }
345

346
int botan_privkey_load_dsa(botan_privkey_t* key,
2✔
347
                           botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x)
348
   {
349
#if defined(BOTAN_HAS_DSA)
350
   *key = nullptr;
2✔
351

352
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
353
      Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
2✔
354
      auto dsa = std::make_unique<Botan::DSA_PrivateKey>(group, safe_get(x));
2✔
355
      *key = new botan_privkey_struct(std::move(dsa));
4✔
356
      return BOTAN_FFI_SUCCESS;
4✔
357
      });
6✔
358
#else
359
   BOTAN_UNUSED(key, p, q, g, x);
360
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
361
#endif
362
   }
363

364
int botan_pubkey_load_dsa(botan_pubkey_t* key,
2✔
365
                          botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y)
366
   {
367
#if defined(BOTAN_HAS_DSA)
368
   *key = nullptr;
2✔
369

370
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
371
      Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
2✔
372
      auto dsa = std::make_unique<Botan::DSA_PublicKey>(group, safe_get(y));
2✔
373
      *key = new botan_pubkey_struct(std::move(dsa));
4✔
374
      return BOTAN_FFI_SUCCESS;
2✔
375
      });
6✔
376
#else
377
   BOTAN_UNUSED(key, p, q, g, y);
378
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
379
#endif
380
   }
381

382
int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key)
2✔
383
   {
384
   return botan_privkey_get_field(x, key, "x");
2✔
385
   }
386

387
int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key)
2✔
388
   {
389
   return botan_pubkey_get_field(p, key, "p");
2✔
390
   }
391

392
int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key)
2✔
393
   {
394
   return botan_pubkey_get_field(q, key, "q");
2✔
395
   }
396

397
int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key)
2✔
398
   {
399
   return botan_pubkey_get_field(g, key, "g");
2✔
400
   }
401

402
int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
2✔
403
   {
404
   return botan_pubkey_get_field(y, key, "y");
2✔
405
   }
406

407
int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
1✔
408
   {
409
   return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
1✔
410
   }
411

412
/* ECDSA specific operations */
413

414
int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
2✔
415
                            const botan_mp_t public_x,
416
                            const botan_mp_t public_y,
417
                            const char* curve_name)
418
   {
419
#if defined(BOTAN_HAS_ECDSA)
420
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
421
      std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
2✔
422

423
      int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
2✔
424
      if(rc == BOTAN_FFI_SUCCESS)
2✔
425
         *key = new botan_pubkey_struct(std::move(p_key));
4✔
426

427
      return rc;
2✔
428
      });
4✔
429
#else
430
   BOTAN_UNUSED(key, public_x, public_y, curve_name);
431
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
432
#endif
433
   }
434

435
int botan_privkey_load_ecdsa(botan_privkey_t* key,
2✔
436
                             const botan_mp_t scalar,
437
                             const char* curve_name)
438
   {
439
#if defined(BOTAN_HAS_ECDSA)
440
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
441
      std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
2✔
442
      int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
2✔
443
      if(rc == BOTAN_FFI_SUCCESS)
2✔
444
         *key = new botan_privkey_struct(std::move(p_key));
4✔
445
      return rc;
2✔
446
      });
4✔
447
#else
448
   BOTAN_UNUSED(key, scalar, curve_name);
449
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
450
#endif
451
   }
452

453
/* ElGamal specific operations */
454
int botan_privkey_create_elgamal(botan_privkey_t* key,
1✔
455
                                 botan_rng_t rng_obj,
456
                                 size_t pbits,
457
                                 size_t qbits)
458
   {
459
#if defined(BOTAN_HAS_ELGAMAL)
460

461
    if ((rng_obj == nullptr) || (key == nullptr))
1✔
462
      return BOTAN_FFI_ERROR_NULL_POINTER;
463

464
    if ((pbits < 1024) || (qbits<160)) {
1✔
465
      return BOTAN_FFI_ERROR_BAD_PARAMETER;
466
    }
467

468
    Botan::DL_Group::PrimeType prime_type = ((pbits-1) == qbits)
1✔
469
      ? Botan::DL_Group::Strong
1✔
470
      : Botan::DL_Group::Prime_Subgroup;
471

472
    return ffi_guard_thunk(__func__, [=]() -> int {
2✔
473
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
1✔
474
      Botan::DL_Group group(rng, prime_type, pbits, qbits);
1✔
475
      auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
1✔
476
      *key = new botan_privkey_struct(std::move(elg));
2✔
477
      return BOTAN_FFI_SUCCESS;
2✔
478
    });
2✔
479
#else
480
    BOTAN_UNUSED(key, rng_obj, pbits, qbits);
481
    return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
482
#endif
483
   }
484

485
int botan_pubkey_load_elgamal(botan_pubkey_t* key,
2✔
486
                              botan_mp_t p, botan_mp_t g, botan_mp_t y)
487
   {
488
#if defined(BOTAN_HAS_ELGAMAL)
489
   *key = nullptr;
2✔
490
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
491
      Botan::DL_Group group(safe_get(p), safe_get(g));
2✔
492
      auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group, safe_get(y));
2✔
493
      *key = new botan_pubkey_struct(std::move(elg));
4✔
494
      return BOTAN_FFI_SUCCESS;
2✔
495
      });
6✔
496
#else
497
   BOTAN_UNUSED(key, p, g, y);
498
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
499
#endif
500
   }
501

502
int botan_privkey_load_elgamal(botan_privkey_t* key,
2✔
503
                               botan_mp_t p, botan_mp_t g, botan_mp_t x)
504
   {
505
#if defined(BOTAN_HAS_ELGAMAL)
506
   *key = nullptr;
2✔
507
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
508
      Botan::DL_Group group(safe_get(p), safe_get(g));
2✔
509
      auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(group, safe_get(x));
2✔
510
      *key = new botan_privkey_struct(std::move(elg));
4✔
511
      return BOTAN_FFI_SUCCESS;
4✔
512
      });
6✔
513
#else
514
   BOTAN_UNUSED(key, p, g, x);
515
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
516
#endif
517
   }
518

519
/* Diffie Hellman specific operations */
520

521
int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
2✔
522
   {
523
   return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
2✔
524
   }
525

526
int botan_privkey_load_dh(botan_privkey_t* key,
1✔
527
                          botan_mp_t p, botan_mp_t g, botan_mp_t x)
528
   {
529
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
530
   *key = nullptr;
1✔
531
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
532
      Botan::DL_Group group(safe_get(p), safe_get(g));
1✔
533
      auto dh = std::make_unique<Botan::DH_PrivateKey>(group, safe_get(x));
1✔
534
      *key = new botan_privkey_struct(std::move(dh));
2✔
535
      return BOTAN_FFI_SUCCESS;
2✔
536
      });
3✔
537
#else
538
   BOTAN_UNUSED(key, p, g, x);
539
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
540
#endif
541
   }
542

543
int botan_pubkey_load_dh(botan_pubkey_t* key,
1✔
544
                         botan_mp_t p, botan_mp_t g, botan_mp_t y)
545
   {
546
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
547
   *key = nullptr;
1✔
548
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
549
      Botan::DL_Group group(safe_get(p), safe_get(g));
1✔
550
      auto dh = std::make_unique<Botan::DH_PublicKey>(group, safe_get(y));
1✔
551
      *key = new botan_pubkey_struct(std::move(dh));
2✔
552
      return BOTAN_FFI_SUCCESS;
1✔
553
      });
3✔
554
#else
555
   BOTAN_UNUSED(key, p, g, y);
556
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
557
#endif
558
   }
559

560
/* ECDH + x25519 specific operations */
561

562
int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
2✔
563
   {
564
   if(param_str == nullptr)
2✔
565
      return BOTAN_FFI_ERROR_NULL_POINTER;
566

567
   const std::string params(param_str);
2✔
568

569
   if(params == "curve25519")
2✔
570
      return botan_privkey_create(key_obj, "Curve25519", "", rng_obj);
×
571

572
   return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
2✔
573
   }
2✔
574

575
int botan_pubkey_load_ecdh(botan_pubkey_t* key,
1✔
576
                           const botan_mp_t public_x,
577
                           const botan_mp_t public_y,
578
                           const char* curve_name)
579
   {
580
#if defined(BOTAN_HAS_ECDH)
581
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
582
      std::unique_ptr<Botan::ECDH_PublicKey> p_key;
1✔
583
      int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
1✔
584

585
      if(rc == BOTAN_FFI_SUCCESS)
1✔
586
         *key = new botan_pubkey_struct(std::move(p_key));
2✔
587
      return rc;
1✔
588
      });
2✔
589
#else
590
   BOTAN_UNUSED(key, public_x, public_y, curve_name);
591
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
592
#endif
593
   }
594

595
int botan_privkey_load_ecdh(botan_privkey_t* key,
4✔
596
                            const botan_mp_t scalar,
597
                            const char* curve_name)
598
   {
599
#if defined(BOTAN_HAS_ECDH)
600
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
601
      std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
4✔
602
      int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
4✔
603
      if(rc == BOTAN_FFI_SUCCESS)
4✔
604
         *key = new botan_privkey_struct(std::move(p_key));
8✔
605
      return rc;
4✔
606
      });
8✔
607
#else
608
   BOTAN_UNUSED(key, scalar, curve_name);
609
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
610
#endif
611
   }
612

613
/* SM2 specific operations */
614

615
int botan_pubkey_sm2_compute_za(uint8_t out[],
2✔
616
                                size_t* out_len,
617
                                const char* ident,
618
                                const char* hash_algo,
619
                                const botan_pubkey_t key)
620
   {
621
   if(out == nullptr || out_len == nullptr)
2✔
622
      return BOTAN_FFI_ERROR_NULL_POINTER;
623
   if(ident == nullptr || hash_algo == nullptr || key == nullptr)
2✔
624
      return BOTAN_FFI_ERROR_NULL_POINTER;
625

626
#if defined(BOTAN_HAS_SM2)
627
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
628
      const Botan::Public_Key& pub_key = safe_get(key);
2✔
629
      const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
2✔
630

631
      if(ec_key == nullptr)
2✔
632
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
633

634
      if(ec_key->algo_name() != "SM2")
2✔
635
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
636

637
      const std::string ident_str(ident);
2✔
638
      std::unique_ptr<Botan::HashFunction> hash =
2✔
639
         Botan::HashFunction::create_or_throw(hash_algo);
2✔
640

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

644
      return write_vec_output(out, out_len, za);
2✔
645
      });
6✔
646
#else
647
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
648
#endif
649
   }
650

651
int botan_pubkey_load_sm2(botan_pubkey_t* key,
3✔
652
                          const botan_mp_t public_x,
653
                          const botan_mp_t public_y,
654
                          const char* curve_name)
655
   {
656
#if defined(BOTAN_HAS_SM2)
657
   return ffi_guard_thunk(__func__, [=]() -> int {
3✔
658
      std::unique_ptr<Botan::SM2_PublicKey> p_key;
3✔
659
      if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
3✔
660
         {
661
         *key = new botan_pubkey_struct(std::move(p_key));
6✔
662
         return BOTAN_FFI_SUCCESS;
3✔
663
         }
664
      return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
665
      });
6✔
666
#else
667
   BOTAN_UNUSED(key, public_x, public_y, curve_name);
668
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
669
#endif
670
   }
671

672
int botan_privkey_load_sm2(botan_privkey_t* key,
3✔
673
                           const botan_mp_t scalar,
674
                           const char* curve_name)
675
   {
676
#if defined(BOTAN_HAS_SM2)
677
   return ffi_guard_thunk(__func__, [=]() -> int {
3✔
678
      std::unique_ptr<Botan::SM2_PrivateKey> p_key;
3✔
679
      int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
3✔
680

681
      if(rc == BOTAN_FFI_SUCCESS)
3✔
682
         *key = new botan_privkey_struct(std::move(p_key));
6✔
683
      return rc;
3✔
684
      });
6✔
685
#else
686
   BOTAN_UNUSED(key, scalar, curve_name);
687
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
688
#endif
689
   }
690

691
int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
1✔
692
                              const botan_mp_t public_x,
693
                              const botan_mp_t public_y,
694
                              const char* curve_name)
695
   {
696
   return botan_pubkey_load_sm2(key, public_x, public_y, curve_name);
1✔
697
   }
698

699
int botan_privkey_load_sm2_enc(botan_privkey_t* key,
1✔
700
                               const botan_mp_t scalar,
701
                               const char* curve_name)
702
   {
703
   return botan_privkey_load_sm2(key, scalar, curve_name);
1✔
704
   }
705

706
/* Ed25519 specific operations */
707

708
int botan_privkey_load_ed25519(botan_privkey_t* key,
1✔
709
                               const uint8_t privkey[32])
710
   {
711
#if defined(BOTAN_HAS_ED25519)
712
   *key = nullptr;
1✔
713
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
714
      const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
1✔
715
      auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec);
1✔
716
      *key = new botan_privkey_struct(std::move(ed25519));
2✔
717
      return BOTAN_FFI_SUCCESS;
2✔
718
      });
3✔
719
#else
720
   BOTAN_UNUSED(key, privkey);
721
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
722
#endif
723
   }
724

725
int botan_pubkey_load_ed25519(botan_pubkey_t* key,
1✔
726
                              const uint8_t pubkey[32])
727
   {
728
#if defined(BOTAN_HAS_ED25519)
729
   *key = nullptr;
1✔
730
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
731
      const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
1✔
732
      auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
1✔
733
      *key = new botan_pubkey_struct(std::move(ed25519));
2✔
734
      return BOTAN_FFI_SUCCESS;
1✔
735
      });
3✔
736
#else
737
   BOTAN_UNUSED(key, pubkey);
738
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
739
#endif
740
   }
741

742
int botan_privkey_ed25519_get_privkey(botan_privkey_t key,
1✔
743
                                      uint8_t output[64])
744
   {
745
#if defined(BOTAN_HAS_ED25519)
746
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
4✔
747
      if(auto ed = dynamic_cast<const Botan::Ed25519_PrivateKey*>(&k))
748
         {
749
         const auto ed_key = ed->raw_private_key_bits();
750
         if(ed_key.size() != 64)
751
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
752
         Botan::copy_mem(output, ed_key.data(), ed_key.size());
753
         return BOTAN_FFI_SUCCESS;
754
         }
755
      else
756
         {
757
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
758
         }
759
      });
760
#else
761
   BOTAN_UNUSED(key, output);
762
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
763
#endif
764
   }
765

766
int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
1✔
767
                                    uint8_t output[32])
768
   {
769
#if defined(BOTAN_HAS_ED25519)
770
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
2✔
771
      if(auto ed = dynamic_cast<const Botan::Ed25519_PublicKey*>(&k))
772
         {
773
         const std::vector<uint8_t>& ed_key = ed->get_public_key();
774
         if(ed_key.size() != 32)
775
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
776
         Botan::copy_mem(output, ed_key.data(), ed_key.size());
777
         return BOTAN_FFI_SUCCESS;
778
         }
779
      else
780
         {
781
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
782
         }
783
      });
784
#else
785
   BOTAN_UNUSED(key, output);
786
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
787
#endif
788
   }
789

790
/* X25519 specific operations */
791

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

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

826
int botan_privkey_x25519_get_privkey(botan_privkey_t key,
1✔
827
                                     uint8_t output[32])
828
   {
829
#if defined(BOTAN_HAS_X25519)
830
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
4✔
831
      if(auto x25519 = dynamic_cast<const Botan::X25519_PrivateKey*>(&k))
832
         {
833
         const auto x25519_key = x25519->raw_private_key_bits();
834
         if(x25519_key.size() != 32)
835
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
836
         Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
837
         return BOTAN_FFI_SUCCESS;
838
         }
839
      else
840
         {
841
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
842
         }
843
      });
844
#else
845
   BOTAN_UNUSED(key, output);
846
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
847
#endif
848
   }
849

850
int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key,
2✔
851
                                   uint8_t output[32])
852
   {
853
#if defined(BOTAN_HAS_X25519)
854
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
8✔
855
      if(auto x25519 = dynamic_cast<const Botan::X25519_PublicKey*>(&k))
856
         {
857
         const std::vector<uint8_t>& x25519_key = x25519->public_value();
858
         if(x25519_key.size() != 32)
859
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
860
         Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
861
         return BOTAN_FFI_SUCCESS;
862
         }
863
      else
864
         {
865
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
866
         }
867
      });
868
#else
869
   BOTAN_UNUSED(key, output);
870
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
871
#endif
872
   }
873

874
/*
875
* Algorithm specific key operations: Kyber
876
*/
877

878
int botan_privkey_load_kyber512(botan_privkey_t* key,
×
879
                                const uint8_t privkey[1632])
880
   {
881
#if defined(BOTAN_HAS_KYBER)
882
   *key = nullptr;
×
883
   return ffi_guard_thunk(__func__, [=]() -> int {
×
884
      const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 1632);
×
885
      auto kyber512 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber512);
×
886
      *key = new botan_privkey_struct(std::move(kyber512));
×
887
      return BOTAN_FFI_SUCCESS;
×
888
      });
×
889
#else
890
   BOTAN_UNUSED(key, privkey);
891
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
892
#endif
893
   }
894

895
int botan_pubkey_load_kyber512(botan_pubkey_t* key,
×
896
                               const uint8_t pubkey[800])
897
   {
898
#if defined(BOTAN_HAS_KYBER)
899
   *key = nullptr;
×
900
   return ffi_guard_thunk(__func__, [=]() -> int {
×
901
      const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 800);
×
902
      auto kyber512 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber512);
×
903
      *key = new botan_pubkey_struct(std::move(kyber512));
×
904
      return BOTAN_FFI_SUCCESS;
×
905
      });
×
906
#else
907
   BOTAN_UNUSED(key, pubkey);
908
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
909
#endif
910
   }
911

912
int botan_privkey_kyber512_get_privkey(botan_privkey_t key,
×
913
                                       uint8_t output[1632])
914
   {
915
#if defined(BOTAN_HAS_KYBER)
916
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
×
917
      if(auto kyber512 = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k))
918
         {
919
         const auto kyber512_key = kyber512->raw_private_key_bits();
920
         if(kyber512_key.size() != 1632)
921
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
922
         Botan::copy_mem(output, kyber512_key.data(), kyber512_key.size());
923
         return BOTAN_FFI_SUCCESS;
924
         }
925
      else
926
         {
927
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
928
         }
929
      });
930
#else
931
   BOTAN_UNUSED(key, output);
932
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
933
#endif
934
   }
935

936
int botan_pubkey_kyber512_get_pubkey(botan_pubkey_t key,
×
937
                                     uint8_t pubkey[800])
938
   {
939
#if defined(BOTAN_HAS_KYBER)
940
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
×
941
      if(auto kyber512 = dynamic_cast<const Botan::Kyber_PublicKey*>(&k))
942
         {
943
         const std::vector<uint8_t>& kyber512_key = kyber512->public_key_bits();
944
         if(kyber512_key.size() != 800)
945
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
946
         Botan::copy_mem(pubkey, kyber512_key.data(), kyber512_key.size());
947
         return BOTAN_FFI_SUCCESS;
948
         }
949
      else
950
         {
951
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
952
         }
953
      });
954
#else
955
   BOTAN_UNUSED(key, pubkey);
956
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
957
#endif
958
   }
959

960
int botan_privkey_load_kyber768(botan_privkey_t* key,
1✔
961
                                const uint8_t privkey[2400])
962
   {
963
#if defined(BOTAN_HAS_KYBER)
964
   *key = nullptr;
1✔
965
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
966
      const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 2400);
1✔
967
      auto kyber768 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber768);
1✔
968
      *key = new botan_privkey_struct(std::move(kyber768));
1✔
969
      return BOTAN_FFI_SUCCESS;
2✔
970
      });
3✔
971
#else
972
   BOTAN_UNUSED(key, privkey);
973
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
974
#endif
975
   }
976

977
int botan_pubkey_load_kyber768(botan_pubkey_t* key,
1✔
978
                               const uint8_t pubkey[1184])
979
   {
980
#if defined(BOTAN_HAS_KYBER)
981
   *key = nullptr;
1✔
982
   return ffi_guard_thunk(__func__, [=]() -> int {
1✔
983
      const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1184);
1✔
984
      auto kyber768 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber768);
1✔
985
      *key = new botan_pubkey_struct(std::move(kyber768));
2✔
986
      return BOTAN_FFI_SUCCESS;
1✔
987
      });
3✔
988
#else
989
   BOTAN_UNUSED(key, pubkey);
990
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
991
#endif
992
   }
993

994
int botan_privkey_kyber768_get_privkey(botan_privkey_t key,
1✔
995
                                       uint8_t output[2400])
996
   {
997
#if defined(BOTAN_HAS_KYBER)
998
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
3✔
999
      if(auto kyber768 = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k))
1000
         {
1001
         const auto kyber768_key = kyber768->raw_private_key_bits();
1002
         if(kyber768_key.size() != 2400)
1003
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
1004
         Botan::copy_mem(output, kyber768_key.data(), kyber768_key.size());
1005
         return BOTAN_FFI_SUCCESS;
1006
         }
1007
      else
1008
         {
1009
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1010
         }
1011
      });
1012
#else
1013
   BOTAN_UNUSED(key, output);
1014
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1015
#endif
1016
   }
1017

1018
int botan_pubkey_kyber768_get_pubkey(botan_pubkey_t key,
2✔
1019
                                     uint8_t pubkey[1184])
1020
   {
1021
#if defined(BOTAN_HAS_KYBER)
1022
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
6✔
1023
      if(auto kyber768 = dynamic_cast<const Botan::Kyber_PublicKey*>(&k))
1024
         {
1025
         const std::vector<uint8_t>& kyber768_key = kyber768->public_key_bits();
1026
         if(kyber768_key.size() != 1184)
1027
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
1028
         Botan::copy_mem(pubkey, kyber768_key.data(), kyber768_key.size());
1029
         return BOTAN_FFI_SUCCESS;
1030
         }
1031
      else
1032
         {
1033
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1034
         }
1035
      });
1036
#else
1037
   BOTAN_UNUSED(key, pubkey);
1038
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1039
#endif
1040
   }
1041

1042
int botan_privkey_load_kyber1024(botan_privkey_t* key,
×
1043
                                const uint8_t privkey[3168])
1044
   {
1045
#if defined(BOTAN_HAS_KYBER)
1046
   *key = nullptr;
×
1047
   return ffi_guard_thunk(__func__, [=]() -> int {
×
1048
      const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 3168);
×
1049
      auto kyber1024 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber1024);
×
1050
      *key = new botan_privkey_struct(std::move(kyber1024));
×
1051
      return BOTAN_FFI_SUCCESS;
×
1052
      });
×
1053
#else
1054
   BOTAN_UNUSED(key, privkey);
1055
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1056
#endif
1057
   }
1058

1059
int botan_pubkey_load_kyber1024(botan_pubkey_t* key,
×
1060
                               const uint8_t pubkey[1568])
1061
   {
1062
#if defined(BOTAN_HAS_KYBER)
1063
   *key = nullptr;
×
1064
   return ffi_guard_thunk(__func__, [=]() -> int {
×
1065
      const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1568);
×
1066
      auto kyber1024 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber1024);
×
1067
      *key = new botan_pubkey_struct(std::move(kyber1024));
×
1068
      return BOTAN_FFI_SUCCESS;
×
1069
      });
×
1070
#else
1071
   BOTAN_UNUSED(key, pubkey);
1072
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1073
#endif
1074
   }
1075

1076
int botan_privkey_kyber1024_get_privkey(botan_privkey_t key,
×
1077
                                       uint8_t output[3186])
1078
   {
1079
#if defined(BOTAN_HAS_KYBER)
1080
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
×
1081
      if(auto kyber1024 = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k))
1082
         {
1083
         const auto kyber1024_key = kyber1024->raw_private_key_bits();
1084
         if(kyber1024_key.size() != 3186)
1085
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
1086
         Botan::copy_mem(output, kyber1024_key.data(), kyber1024_key.size());
1087
         return BOTAN_FFI_SUCCESS;
1088
         }
1089
      else
1090
         {
1091
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1092
         }
1093
      });
1094
#else
1095
   BOTAN_UNUSED(key, output);
1096
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1097
#endif
1098
   }
1099

1100
int botan_pubkey_kyber1024_get_pubkey(botan_pubkey_t key,
×
1101
                                     uint8_t pubkey[1568])
1102
   {
1103
#if defined(BOTAN_HAS_KYBER)
1104
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
×
1105
      if(auto kyber1024 = dynamic_cast<const Botan::Kyber_PublicKey*>(&k))
1106
         {
1107
         const std::vector<uint8_t>& kyber1024_key = kyber1024->public_key_bits();
1108
         if(kyber1024_key.size() != 1568)
1109
            return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
1110
         Botan::copy_mem(pubkey, kyber1024_key.data(), kyber1024_key.size());
1111
         return BOTAN_FFI_SUCCESS;
1112
         }
1113
      else
1114
         {
1115
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1116
         }
1117
      });
1118
#else
1119
   BOTAN_UNUSED(key, pubkey);
1120
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1121
#endif
1122
   }
1123

1124
int botan_pubkey_view_ec_public_point(
6✔
1125
   const botan_pubkey_t key,
1126
   botan_view_ctx ctx,
1127
   botan_view_bin_fn view)
1128
   {
1129
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
1130
   return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
18✔
1131
      if(auto ecc = dynamic_cast<const Botan::EC_PublicKey*>(&k))
1132
         {
1133
         auto pt = ecc->public_point().encode(Botan::EC_Point_Format::Uncompressed);
1134
         return invoke_view_callback(view, ctx, pt);
1135
         }
1136
      else
1137
         {
1138
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
1139
         }
1140
      });
1141
#else
1142
   BOTAN_UNUSED(key, view, ctx);
1143
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
1144
#endif
1145
   }
1146

1147
int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
1✔
1148
   {
1149
   const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
2✔
1150
   return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
1✔
1151
   }
1✔
1152

1153
int botan_mceies_decrypt(botan_privkey_t mce_key_obj,
×
1154
                         const char* aead,
1155
                         const uint8_t ct[], size_t ct_len,
1156
                         const uint8_t ad[], size_t ad_len,
1157
                         uint8_t out[], size_t* out_len)
1158
   {
1159
   BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
×
1160
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
×
1161
   }
1162

1163
int botan_mceies_encrypt(botan_pubkey_t mce_key_obj,
×
1164
                         botan_rng_t rng_obj,
1165
                         const char* aead,
1166
                         const uint8_t pt[], size_t pt_len,
1167
                         const uint8_t ad[], size_t ad_len,
1168
                         uint8_t out[], size_t* out_len)
1169
   {
1170
   BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
×
1171
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
×
1172
   }
1173

1174
}
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