2
* (C) 2015,2017 Jack Lloyd
4
* Botan is released under the Simplified BSD License (see license.txt)
8
#include <botan/internal/ffi_util.h>
9
#include <botan/internal/ffi_pkey.h>
10
#include <botan/internal/ffi_rng.h>
11
#include <botan/pubkey.h>
15
using namespace Botan_FFI;
17
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_encrypt_struct, Botan::PK_Encryptor, 0x891F3FC3);
18
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_decrypt_struct, Botan::PK_Decryptor, 0x912F3C37);
19
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_sign_struct, Botan::PK_Signer, 0x1AF0C39F);
20
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F936);
21
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_ka_struct, Botan::PK_Key_Agreement, 0x2939CAB1);
23
int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
24
botan_pubkey_t key_obj,
28
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
29
BOTAN_ASSERT_NONNULL(op);
34
return BOTAN_FFI_ERROR_BAD_FLAG;
36
std::unique_ptr<Botan::PK_Encryptor> pk(new Botan::PK_Encryptor_EME(safe_get(key_obj), Botan::system_rng(), padding));
37
*op = new botan_pk_op_encrypt_struct(pk.release());
38
return BOTAN_FFI_SUCCESS;
42
int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op)
44
return BOTAN_FFI_CHECKED_DELETE(op);
47
int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
49
uint8_t out[], size_t* out_len,
50
const uint8_t plaintext[], size_t plaintext_len)
52
return BOTAN_FFI_DO(Botan::PK_Encryptor, op, o, {
53
return write_vec_output(out, out_len, o.encrypt(plaintext, plaintext_len, safe_get(rng_obj)));
58
* Public Key Decryption
60
int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
61
botan_privkey_t key_obj,
65
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
66
BOTAN_ASSERT_NONNULL(op);
71
return BOTAN_FFI_ERROR_BAD_FLAG;
73
std::unique_ptr<Botan::PK_Decryptor> pk(new Botan::PK_Decryptor_EME(safe_get(key_obj), Botan::system_rng(), padding));
74
*op = new botan_pk_op_decrypt_struct(pk.release());
75
return BOTAN_FFI_SUCCESS;
79
int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op)
81
return BOTAN_FFI_CHECKED_DELETE(op);
84
int botan_pk_op_decrypt(botan_pk_op_decrypt_t op,
85
uint8_t out[], size_t* out_len,
86
const uint8_t ciphertext[], size_t ciphertext_len)
88
return BOTAN_FFI_DO(Botan::PK_Decryptor, op, o, {
89
return write_vec_output(out, out_len, o.decrypt(ciphertext, ciphertext_len));
94
* Signature Generation
96
int botan_pk_op_sign_create(botan_pk_op_sign_t* op,
97
botan_privkey_t key_obj,
101
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
102
BOTAN_ASSERT_NONNULL(op);
107
return BOTAN_FFI_ERROR_BAD_FLAG;
109
std::unique_ptr<Botan::PK_Signer> pk(new Botan::PK_Signer(safe_get(key_obj),Botan::system_rng(), hash));
110
*op = new botan_pk_op_sign_struct(pk.release());
111
return BOTAN_FFI_SUCCESS;
115
int botan_pk_op_sign_destroy(botan_pk_op_sign_t op)
117
return BOTAN_FFI_CHECKED_DELETE(op);
120
int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len)
122
return BOTAN_FFI_DO(Botan::PK_Signer, op, o, { o.update(in, in_len); });
125
int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng_obj, uint8_t out[], size_t* out_len)
127
return BOTAN_FFI_DO(Botan::PK_Signer, op, o, {
128
return write_vec_output(out, out_len, o.signature(safe_get(rng_obj)));
132
int botan_pk_op_verify_create(botan_pk_op_verify_t* op,
133
botan_pubkey_t key_obj,
137
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
138
BOTAN_ASSERT_NONNULL(op);
141
return BOTAN_FFI_ERROR_BAD_FLAG;
143
std::unique_ptr<Botan::PK_Verifier> pk(new Botan::PK_Verifier(safe_get(key_obj), hash));
144
*op = new botan_pk_op_verify_struct(pk.release());
145
return BOTAN_FFI_SUCCESS;
149
int botan_pk_op_verify_destroy(botan_pk_op_verify_t op)
151
return BOTAN_FFI_CHECKED_DELETE(op);
154
int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len)
156
return BOTAN_FFI_DO(Botan::PK_Verifier, op, o, { o.update(in, in_len); });
159
int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len)
161
return BOTAN_FFI_DO(Botan::PK_Verifier, op, o, {
162
const bool legit = o.check_signature(sig, sig_len);
165
return BOTAN_FFI_SUCCESS;
167
return BOTAN_FFI_INVALID_VERIFIER;
171
int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op,
172
botan_privkey_t key_obj,
176
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
177
BOTAN_ASSERT_NONNULL(op);
182
return BOTAN_FFI_ERROR_BAD_FLAG;
184
std::unique_ptr<Botan::PK_Key_Agreement> pk(new Botan::PK_Key_Agreement(safe_get(key_obj), Botan::system_rng(), kdf));
185
*op = new botan_pk_op_ka_struct(pk.release());
186
return BOTAN_FFI_SUCCESS;
190
int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op)
192
return BOTAN_FFI_CHECKED_DELETE(op);
195
int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
196
uint8_t out[], size_t* out_len)
198
return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
199
if(auto kak = dynamic_cast<const Botan::PK_Key_Agreement_Key*>(&k))
200
return write_vec_output(out, out_len, kak->public_value());
201
return BOTAN_FFI_ERROR_BAD_FLAG;
205
int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
206
uint8_t out[], size_t* out_len,
207
const uint8_t other_key[], size_t other_key_len,
208
const uint8_t salt[], size_t salt_len)
210
return BOTAN_FFI_DO(Botan::PK_Key_Agreement, op, o, {
211
auto k = o.derive_key(*out_len, other_key, other_key_len, salt, salt_len).bits_of();
212
return write_vec_output(out, out_len, k);