2
* (C) 2015,2017 Jack Lloyd
5
* Botan is released under the Simplified BSD License (see license.txt)
9
#include <botan/hash.h>
10
#include <botan/internal/ffi_util.h>
11
#include <botan/internal/ffi_pkey.h>
12
#include <botan/internal/ffi_rng.h>
13
#include <botan/internal/ffi_mp.h>
15
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
16
#include <botan/ecc_key.h>
19
#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
20
#include <botan/dl_algo.h>
23
#if defined(BOTAN_HAS_RSA)
24
#include <botan/rsa.h>
27
#if defined(BOTAN_HAS_ELGAMAL)
28
#include <botan/elgamal.h>
31
#if defined(BOTAN_HAS_DSA)
32
#include <botan/dsa.h>
35
#if defined(BOTAN_HAS_ECDSA)
36
#include <botan/ecdsa.h>
39
#if defined(BOTAN_HAS_SM2)
40
#include <botan/sm2.h>
41
#include <botan/sm2_enc.h>
44
#if defined(BOTAN_HAS_ECDH)
45
#include <botan/ecdh.h>
48
#if defined(BOTAN_HAS_CURVE_25519)
49
#include <botan/curve25519.h>
52
#if defined(BOTAN_HAS_ED25519)
53
#include <botan/ed25519.h>
56
#if defined(BOTAN_HAS_MCELIECE)
57
#include <botan/mceliece.h>
60
#if defined(BOTAN_HAS_MCEIES)
61
#include <botan/mceies.h>
64
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
71
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
73
// These are always called within an existing try/catch block
75
template<class ECPrivateKey_t>
76
int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
77
const Botan::BigInt& scalar,
78
const char* curve_name)
80
if(curve_name == nullptr)
81
return BOTAN_FFI_ERROR_NULL_POINTER;
83
Botan::Null_RNG null_rng;
84
Botan::EC_Group grp(curve_name);
85
key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
86
return BOTAN_FFI_SUCCESS;
89
template<class ECPublicKey_t>
90
int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
91
const Botan::BigInt& public_x,
92
const Botan::BigInt& public_y,
93
const char* curve_name)
95
if(curve_name == nullptr)
96
return BOTAN_FFI_ERROR_NULL_POINTER;
98
Botan::EC_Group grp(curve_name);
99
Botan::PointGFp uncompressed_point(grp.get_curve(), public_x, public_y);
100
key.reset(new ECPublicKey_t(grp, uncompressed_point));
101
return BOTAN_FFI_SUCCESS;
106
Botan::BigInt pubkey_get_field(const Botan::Public_Key& key,
107
const std::string& field)
109
// Maybe this should be `return key.get_integer_field(field_name)`?
111
#if defined(BOTAN_HAS_RSA)
112
if(const Botan::RSA_PublicKey* rsa = dynamic_cast<const Botan::RSA_PublicKey*>(&key))
116
else if(field == "e")
119
throw Botan::Exception("Field not supported");
123
#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
124
// Handles DSA, ElGamal, etc
125
if(const Botan::DL_Scheme_PublicKey* dl = dynamic_cast<const Botan::DL_Scheme_PublicKey*>(&key))
128
return dl->group_p();
129
else if(field == "q")
130
return dl->group_q();
131
else if(field == "g")
132
return dl->group_g();
133
else if(field == "y")
136
throw Botan::Exception("Field not supported");
140
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
141
if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key))
143
if(field == "public_x")
144
return ecc->public_point().get_affine_x();
145
else if(field == "public_y")
146
return ecc->public_point().get_affine_y();
147
else if(field == "base_x")
148
return ecc->domain().get_base_point().get_affine_x();
149
else if(field == "base_y")
150
return ecc->domain().get_base_point().get_affine_y();
151
else if(field == "p")
152
return ecc->domain().get_curve().get_p();
153
else if(field == "a")
154
return ecc->domain().get_curve().get_a();
155
else if(field == "b")
156
return ecc->domain().get_curve().get_b();
157
else if(field == "cofactor")
158
return ecc->domain().get_cofactor();
159
else if(field == "order")
160
return ecc->domain().get_order();
162
throw Botan::Exception("Field not supported");
166
// Some other algorithm type not supported by this function
167
throw Botan::Exception("Unsupported algorithm type for botan_pubkey_get_field");
170
Botan::BigInt privkey_get_field(const Botan::Private_Key& key,
171
const std::string& field)
173
//return key.get_integer_field(field);
175
#if defined(BOTAN_HAS_RSA)
177
if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&key))
181
else if(field == "q")
183
else if(field == "d")
185
else if(field == "c")
187
else if(field == "d1")
188
return rsa->get_d1();
189
else if(field == "d2")
190
return rsa->get_d2();
192
return pubkey_get_field(key, field);
196
#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
197
// Handles DSA, ElGamal, etc
198
if(const Botan::DL_Scheme_PrivateKey* dl = dynamic_cast<const Botan::DL_Scheme_PrivateKey*>(&key))
203
return pubkey_get_field(key, field);
207
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
208
if(const Botan::EC_PrivateKey* ecc = dynamic_cast<const Botan::EC_PrivateKey*>(&key))
211
return ecc->private_value();
213
return pubkey_get_field(key, field);
217
// Some other algorithm type not supported by this function
218
throw Botan::Exception("Unsupported algorithm type for botan_privkey_get_field");
225
using namespace Botan_FFI;
227
int botan_pubkey_get_field(botan_mp_t output,
229
const char* field_name_cstr)
231
if(field_name_cstr == nullptr)
232
return BOTAN_FFI_ERROR_NULL_POINTER;
234
const std::string field_name(field_name_cstr);
236
return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
237
safe_get(output) = pubkey_get_field(k, field_name);
241
int botan_privkey_get_field(botan_mp_t output,
243
const char* field_name_cstr)
245
if(field_name_cstr == nullptr)
246
return BOTAN_FFI_ERROR_NULL_POINTER;
248
const std::string field_name(field_name_cstr);
250
return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
251
safe_get(output) = privkey_get_field(k, field_name);
255
/* RSA specific operations */
257
int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits)
259
if(n_bits < 1024 || n_bits > 16*1024)
260
return BOTAN_FFI_ERROR_BAD_PARAMETER;
262
std::string n_str = std::to_string(n_bits);
264
return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
267
int botan_privkey_load_rsa(botan_privkey_t* key,
268
botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
270
#if defined(BOTAN_HAS_RSA)
273
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
274
*key = new botan_privkey_struct(new Botan::RSA_PrivateKey(safe_get(rsa_p),
277
return BOTAN_FFI_SUCCESS;
280
BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
281
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
285
int botan_pubkey_load_rsa(botan_pubkey_t* key,
286
botan_mp_t n, botan_mp_t e)
288
#if defined(BOTAN_HAS_RSA)
290
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
291
*key = new botan_pubkey_struct(new Botan::RSA_PublicKey(safe_get(n), safe_get(e)));
292
return BOTAN_FFI_SUCCESS;
295
BOTAN_UNUSED(key, n, e);
296
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
300
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
302
return botan_privkey_get_field(p, key, "p");
305
int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
307
return botan_privkey_get_field(q, key, "q");
310
int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
312
return botan_privkey_get_field(n, key, "n");
315
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
317
return botan_privkey_get_field(e, key, "e");
320
int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
322
return botan_privkey_get_field(d, key, "d");
325
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key)
327
return botan_pubkey_get_field(e, key, "e");
330
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
332
return botan_pubkey_get_field(n, key, "n");
335
/* DSA specific operations */
337
int botan_privkey_load_dsa(botan_privkey_t* key,
338
botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x)
340
#if defined(BOTAN_HAS_DSA)
343
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
344
Botan::Null_RNG null_rng;
345
Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
346
*key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x)));
347
return BOTAN_FFI_SUCCESS;
350
BOTAN_UNUSED(key, p, q, g, x);
351
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
355
int botan_pubkey_load_dsa(botan_pubkey_t* key,
356
botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y)
358
#if defined(BOTAN_HAS_DSA)
361
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
362
Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
363
*key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y)));
364
return BOTAN_FFI_SUCCESS;
367
BOTAN_UNUSED(key, p, q, g, y);
368
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
372
int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key)
374
return botan_privkey_get_field(x, key, "x");
377
int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key)
379
return botan_pubkey_get_field(p, key, "p");
382
int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key)
384
return botan_pubkey_get_field(q, key, "q");
387
int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key)
389
return botan_pubkey_get_field(g, key, "g");
392
int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
394
return botan_pubkey_get_field(y, key, "y");
397
int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
399
return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
402
/* ECDSA specific operations */
404
int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
405
const botan_mp_t public_x,
406
const botan_mp_t public_y,
407
const char* curve_name)
409
#if defined(BOTAN_HAS_ECDSA)
410
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
411
std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
413
int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
414
if(rc == BOTAN_FFI_SUCCESS)
415
*key = new botan_pubkey_struct(p_key.release());
420
BOTAN_UNUSED(key, public_x, public_y, curve_name);
421
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
425
int botan_privkey_load_ecdsa(botan_privkey_t* key,
426
const botan_mp_t scalar,
427
const char* curve_name)
429
#if defined(BOTAN_HAS_ECDSA)
430
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
431
std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
432
int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
433
if(rc == BOTAN_FFI_SUCCESS)
434
*key = new botan_privkey_struct(p_key.release());
438
BOTAN_UNUSED(key, scalar, curve_name);
439
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
443
/* ElGamal specific operations */
445
int botan_pubkey_load_elgamal(botan_pubkey_t* key,
446
botan_mp_t p, botan_mp_t g, botan_mp_t y)
448
#if defined(BOTAN_HAS_ELGAMAL)
450
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
451
Botan::DL_Group group(safe_get(p), safe_get(g));
452
*key = new botan_pubkey_struct(new Botan::ElGamal_PublicKey(group, safe_get(y)));
453
return BOTAN_FFI_SUCCESS;
456
BOTAN_UNUSED(key, p, g, y);
457
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
461
int botan_privkey_load_elgamal(botan_privkey_t* key,
462
botan_mp_t p, botan_mp_t g, botan_mp_t x)
464
#if defined(BOTAN_HAS_ELGAMAL)
466
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
467
Botan::Null_RNG null_rng;
468
Botan::DL_Group group(safe_get(p), safe_get(g));
469
*key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(null_rng, group, safe_get(x)));
470
return BOTAN_FFI_SUCCESS;
473
BOTAN_UNUSED(key, p, g, x);
474
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
478
/* Diffie Hellman specific operations */
480
int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
482
return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
485
int botan_privkey_load_dh(botan_privkey_t* key,
486
botan_mp_t p, botan_mp_t g, botan_mp_t x)
488
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
490
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
491
Botan::Null_RNG null_rng;
492
Botan::DL_Group group(safe_get(p), safe_get(g));
493
*key = new botan_privkey_struct(new Botan::DH_PrivateKey(null_rng, group, safe_get(x)));
494
return BOTAN_FFI_SUCCESS;
497
BOTAN_UNUSED(key, p, g, x);
498
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
502
int botan_pubkey_load_dh(botan_pubkey_t* key,
503
botan_mp_t p, botan_mp_t g, botan_mp_t y)
505
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
507
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
508
Botan::DL_Group group(safe_get(p), safe_get(g));
509
*key = new botan_pubkey_struct(new Botan::DH_PublicKey(group, safe_get(y)));
510
return BOTAN_FFI_SUCCESS;
513
BOTAN_UNUSED(key, p, g, y);
514
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
518
/* ECDH + x25519 specific operations */
520
int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
522
if(param_str == nullptr)
523
return BOTAN_FFI_ERROR_NULL_POINTER;
525
const std::string params(param_str);
527
if(params == "curve25519")
528
return botan_privkey_create(key_obj, "Curve25519", "", rng_obj);
530
return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
533
int botan_pubkey_load_ecdh(botan_pubkey_t* key,
534
const botan_mp_t public_x,
535
const botan_mp_t public_y,
536
const char* curve_name)
538
#if defined(BOTAN_HAS_ECDH)
539
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
540
std::unique_ptr<Botan::ECDH_PublicKey> p_key;
541
int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
543
if(rc == BOTAN_FFI_SUCCESS)
544
*key = new botan_pubkey_struct(p_key.release());
548
BOTAN_UNUSED(key, public_x, public_y, curve_name);
549
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
553
int botan_privkey_load_ecdh(botan_privkey_t* key,
554
const botan_mp_t scalar,
555
const char* curve_name)
557
#if defined(BOTAN_HAS_ECDH)
558
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
559
std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
560
int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
561
if(rc == BOTAN_FFI_SUCCESS)
562
*key = new botan_privkey_struct(p_key.release());
566
BOTAN_UNUSED(key, scalar, curve_name);
567
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
571
/* SM2 specific operations */
573
int botan_pubkey_sm2_compute_za(uint8_t out[],
576
const char* hash_algo,
577
const botan_pubkey_t key)
579
if(out == nullptr || out_len == nullptr)
580
return BOTAN_FFI_ERROR_NULL_POINTER;
581
if(ident == nullptr || hash_algo == nullptr || key == nullptr)
582
return BOTAN_FFI_ERROR_NULL_POINTER;
584
#if defined(BOTAN_HAS_SM2)
585
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
586
const Botan::Public_Key& pub_key = safe_get(key);
587
const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
589
if(ec_key == nullptr)
590
return BOTAN_FFI_ERROR_BAD_PARAMETER;
592
if(ec_key->algo_name() != "SM2_Sig" && ec_key->algo_name() != "SM2_Enc")
593
return BOTAN_FFI_ERROR_BAD_PARAMETER;
595
const std::string ident_str(ident);
596
std::unique_ptr<Botan::HashFunction> hash =
597
Botan::HashFunction::create_or_throw(hash_algo);
599
const std::vector<uint8_t> za =
600
Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
602
return write_vec_output(out, out_len, za);
605
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
609
int botan_pubkey_load_sm2(botan_pubkey_t* key,
610
const botan_mp_t public_x,
611
const botan_mp_t public_y,
612
const char* curve_name)
614
#if defined(BOTAN_HAS_SM2)
615
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
616
std::unique_ptr<Botan::SM2_Signature_PublicKey> p_key;
617
if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
619
*key = new botan_pubkey_struct(p_key.release());
620
return BOTAN_FFI_SUCCESS;
622
return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
625
BOTAN_UNUSED(key, public_x, public_y, curve_name);
626
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
630
int botan_privkey_load_sm2(botan_privkey_t* key,
631
const botan_mp_t scalar,
632
const char* curve_name)
634
#if defined(BOTAN_HAS_SM2)
635
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
636
std::unique_ptr<Botan::SM2_Signature_PrivateKey> p_key;
637
int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
639
if(rc == BOTAN_FFI_SUCCESS)
640
*key = new botan_privkey_struct(p_key.release());
644
BOTAN_UNUSED(key, scalar, curve_name);
645
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
649
int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
650
const botan_mp_t public_x,
651
const botan_mp_t public_y,
652
const char* curve_name)
654
#if defined(BOTAN_HAS_SM2)
655
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
656
std::unique_ptr<Botan::SM2_Encryption_PublicKey> p_key;
657
if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
659
*key = new botan_pubkey_struct(p_key.release());
660
return BOTAN_FFI_SUCCESS;
662
return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
665
BOTAN_UNUSED(key, public_x, public_y, curve_name);
666
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
670
int botan_privkey_load_sm2_enc(botan_privkey_t* key,
671
const botan_mp_t scalar,
672
const char* curve_name)
674
#if defined(BOTAN_HAS_SM2)
675
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
676
std::unique_ptr<Botan::SM2_Encryption_PrivateKey> p_key;
677
int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
679
if(rc == BOTAN_FFI_SUCCESS)
680
*key = new botan_privkey_struct(p_key.release());
684
BOTAN_UNUSED(key, scalar, curve_name);
685
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
689
/* Ed25519 specific operations */
691
int botan_privkey_load_ed25519(botan_privkey_t* key,
692
const uint8_t privkey[32])
694
#if defined(BOTAN_HAS_ED25519)
696
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
697
const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
698
*key = new botan_privkey_struct(new Botan::Ed25519_PrivateKey(privkey_vec));
699
return BOTAN_FFI_SUCCESS;
702
BOTAN_UNUSED(key, privkey);
703
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
707
int botan_pubkey_load_ed25519(botan_pubkey_t* key,
708
const uint8_t pubkey[32])
710
#if defined(BOTAN_HAS_ED25519)
712
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
713
const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
714
*key = new botan_pubkey_struct(new Botan::Ed25519_PublicKey(pubkey_vec));
715
return BOTAN_FFI_SUCCESS;
718
BOTAN_UNUSED(key, pubkey);
719
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
723
int botan_privkey_ed25519_get_privkey(botan_privkey_t key,
726
#if defined(BOTAN_HAS_ED25519)
727
return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
728
if(Botan::Ed25519_PrivateKey* ed = dynamic_cast<Botan::Ed25519_PrivateKey*>(&k))
730
const Botan::secure_vector<uint8_t>& ed_key = ed->get_private_key();
731
if(ed_key.size() != 64)
732
return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
733
Botan::copy_mem(output, ed_key.data(), ed_key.size());
734
return BOTAN_FFI_SUCCESS;
738
return BOTAN_FFI_ERROR_BAD_PARAMETER;
742
BOTAN_UNUSED(key, output);
743
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
747
int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
750
#if defined(BOTAN_HAS_ED25519)
751
return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
752
if(Botan::Ed25519_PublicKey* ed = dynamic_cast<Botan::Ed25519_PublicKey*>(&k))
754
const std::vector<uint8_t>& ed_key = ed->get_public_key();
755
if(ed_key.size() != 32)
756
return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
757
Botan::copy_mem(output, ed_key.data(), ed_key.size());
758
return BOTAN_FFI_SUCCESS;
762
return BOTAN_FFI_ERROR_BAD_PARAMETER;
766
BOTAN_UNUSED(key, output);
767
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
771
int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
773
const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
774
return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
777
int botan_mceies_decrypt(botan_privkey_t mce_key_obj,
779
const uint8_t ct[], size_t ct_len,
780
const uint8_t ad[], size_t ad_len,
781
uint8_t out[], size_t* out_len)
783
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
784
Botan::Private_Key& key = safe_get(mce_key_obj);
786
#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
787
Botan::McEliece_PrivateKey* mce = dynamic_cast<Botan::McEliece_PrivateKey*>(&key);
789
return BOTAN_FFI_ERROR_BAD_PARAMETER;
791
const Botan::secure_vector<uint8_t> pt = mceies_decrypt(*mce, ct, ct_len, ad, ad_len, aead);
792
return write_vec_output(out, out_len, pt);
794
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
799
int botan_mceies_encrypt(botan_pubkey_t mce_key_obj,
802
const uint8_t pt[], size_t pt_len,
803
const uint8_t ad[], size_t ad_len,
804
uint8_t out[], size_t* out_len)
806
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
807
Botan::Public_Key& key = safe_get(mce_key_obj);
808
Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
810
#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
811
Botan::McEliece_PublicKey* mce = dynamic_cast<Botan::McEliece_PublicKey*>(&key);
813
return BOTAN_FFI_ERROR_BAD_PARAMETER;
815
Botan::secure_vector<uint8_t> ct = mceies_encrypt(*mce, pt, pt_len, ad, ad_len, rng, aead);
816
return write_vec_output(out, out_len, ct);
818
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;