Botan 3.4.0
Crypto and TLS for C&
ffi_pk_op.cpp
Go to the documentation of this file.
1/*
2* (C) 2015,2017 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/ffi.h>
8
9#include <botan/pubkey.h>
10#include <botan/system_rng.h>
11#include <botan/internal/ffi_pkey.h>
12#include <botan/internal/ffi_rng.h>
13#include <botan/internal/ffi_util.h>
14
15extern "C" {
16
17using namespace Botan_FFI;
18
19BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_encrypt_struct, Botan::PK_Encryptor, 0x891F3FC3);
20BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_decrypt_struct, Botan::PK_Decryptor, 0x912F3C37);
21BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_sign_struct, Botan::PK_Signer, 0x1AF0C39F);
22BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F936);
23BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_ka_struct, Botan::PK_Key_Agreement, 0x2939CAB1);
24
25BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_kem_encrypt_struct, Botan::PK_KEM_Encryptor, 0x1D13A446);
26BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_kem_decrypt_struct, Botan::PK_KEM_Decryptor, 0x1743D8E6);
27
28int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op, botan_pubkey_t key_obj, const char* padding, uint32_t flags) {
29 if(op == nullptr) {
31 }
32
33 if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) {
35 }
36
37 return ffi_guard_thunk(__func__, [=]() -> int {
38 *op = nullptr;
39
40 auto pk = std::make_unique<Botan::PK_Encryptor_EME>(safe_get(key_obj), Botan::system_rng(), padding);
41 *op = new botan_pk_op_encrypt_struct(std::move(pk));
42 return BOTAN_FFI_SUCCESS;
43 });
44}
45
49
50int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op, size_t ptext_len, size_t* ctext_len) {
51 if(ctext_len == nullptr) {
53 }
54 return BOTAN_FFI_VISIT(op, [=](const auto& o) { *ctext_len = o.ciphertext_length(ptext_len); });
55}
56
58 botan_rng_t rng_obj,
59 uint8_t out[],
60 size_t* out_len,
61 const uint8_t plaintext[],
62 size_t plaintext_len) {
63 return BOTAN_FFI_VISIT(op, [=](const auto& o) {
64 return write_vec_output(out, out_len, o.encrypt(plaintext, plaintext_len, safe_get(rng_obj)));
65 });
66}
67
68/*
69* Public Key Decryption
70*/
72 botan_privkey_t key_obj,
73 const char* padding,
74 uint32_t flags) {
75 if(op == nullptr) {
77 }
78
79 if(flags != 0) {
81 }
82
83 return ffi_guard_thunk(__func__, [=]() -> int {
84 *op = nullptr;
85
86 auto pk = std::make_unique<Botan::PK_Decryptor_EME>(safe_get(key_obj), Botan::system_rng(), padding);
87 *op = new botan_pk_op_decrypt_struct(std::move(pk));
88 return BOTAN_FFI_SUCCESS;
89 });
90}
91
95
96int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op, size_t ctext_len, size_t* ptext_len) {
97 if(ptext_len == nullptr) {
99 }
100 return BOTAN_FFI_VISIT(op, [=](const auto& o) { *ptext_len = o.plaintext_length(ctext_len); });
101}
102
104 botan_pk_op_decrypt_t op, uint8_t out[], size_t* out_len, const uint8_t ciphertext[], size_t ciphertext_len) {
105 return BOTAN_FFI_VISIT(
106 op, [=](const auto& o) { return write_vec_output(out, out_len, o.decrypt(ciphertext, ciphertext_len)); });
107}
108
109/*
110* Signature Generation
111*/
112int botan_pk_op_sign_create(botan_pk_op_sign_t* op, botan_privkey_t key_obj, const char* hash, uint32_t flags) {
113 if(op == nullptr) {
115 }
116
117 if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) {
119 }
120
121 return ffi_guard_thunk(__func__, [=]() -> int {
122 *op = nullptr;
123
126
127 auto pk = std::make_unique<Botan::PK_Signer>(safe_get(key_obj), Botan::system_rng(), hash, format);
128 *op = new botan_pk_op_sign_struct(std::move(pk));
129 return BOTAN_FFI_SUCCESS;
130 });
131}
132
136
138 if(sig_len == nullptr) {
140 }
141
142 return BOTAN_FFI_VISIT(op, [=](const auto& o) { *sig_len = o.signature_length(); });
143}
144
145int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len) {
146 return BOTAN_FFI_VISIT(op, [=](auto& o) { o.update(in, in_len); });
147}
148
149int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng_obj, uint8_t out[], size_t* out_len) {
150 return BOTAN_FFI_VISIT(op, [=](auto& o) { return write_vec_output(out, out_len, o.signature(safe_get(rng_obj))); });
151}
152
153int botan_pk_op_verify_create(botan_pk_op_verify_t* op, botan_pubkey_t key_obj, const char* hash, uint32_t flags) {
154 if(op == nullptr) {
156 }
157
158 if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) {
160 }
161
162 return ffi_guard_thunk(__func__, [=]() -> int {
163 *op = nullptr;
166 auto pk = std::make_unique<Botan::PK_Verifier>(safe_get(key_obj), hash, format);
167 *op = new botan_pk_op_verify_struct(std::move(pk));
168 return BOTAN_FFI_SUCCESS;
169 });
170}
171
175
176int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len) {
177 return BOTAN_FFI_VISIT(op, [=](auto& o) { o.update(in, in_len); });
178}
179
180int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len) {
181 return BOTAN_FFI_VISIT(op, [=](auto& o) {
182 const bool legit = o.check_signature(sig, sig_len);
183
184 if(legit)
185 return BOTAN_FFI_SUCCESS;
186 else
188 });
189}
190
191int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, botan_privkey_t key_obj, const char* kdf, uint32_t flags) {
192 if(op == nullptr) {
194 }
195
196 if(flags != 0) {
198 }
199
200 return ffi_guard_thunk(__func__, [=]() -> int {
201 *op = nullptr;
202 auto pk = std::make_unique<Botan::PK_Key_Agreement>(safe_get(key_obj), Botan::system_rng(), kdf);
203 *op = new botan_pk_op_ka_struct(std::move(pk));
204 return BOTAN_FFI_SUCCESS;
205 });
206}
207
211
212int botan_pk_op_key_agreement_export_public(botan_privkey_t key, uint8_t out[], size_t* out_len) {
213 return copy_view_bin(out, out_len, botan_pk_op_key_agreement_view_public, key);
214}
215
217 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
218 if(auto kak = dynamic_cast<const Botan::PK_Key_Agreement_Key*>(&k))
219 return invoke_view_callback(view, ctx, kak->public_value());
220 else
222 });
223}
224
226 return BOTAN_FFI_VISIT(op, [=](const auto& o) {
227 if(out_len == nullptr)
229 *out_len = o.agreed_value_size();
230 return BOTAN_FFI_SUCCESS;
231 });
232}
233
235 uint8_t out[],
236 size_t* out_len,
237 const uint8_t other_key[],
238 size_t other_key_len,
239 const uint8_t salt[],
240 size_t salt_len) {
241 return BOTAN_FFI_VISIT(op, [=](const auto& o) {
242 auto k = o.derive_key(*out_len, other_key, other_key_len, salt, salt_len).bits_of();
243 return write_vec_output(out, out_len, k);
244 });
245}
246
248 if(op == nullptr || padding == nullptr) {
250 }
251
252 return ffi_guard_thunk(__func__, [=]() -> int {
253 auto pk = std::make_unique<Botan::PK_KEM_Encryptor>(safe_get(key_obj), padding);
254 *op = new botan_pk_op_kem_encrypt_struct(std::move(pk));
255 return BOTAN_FFI_SUCCESS;
256 });
257}
258
262
264 size_t desired_shared_key_length,
265 size_t* output_shared_key_length) {
266 if(output_shared_key_length == nullptr) {
268 }
269
270 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
271 *output_shared_key_length = kem.shared_key_length(desired_shared_key_length);
272 return BOTAN_FFI_SUCCESS;
273 });
274}
275
277 size_t* output_encapsulated_key_length) {
278 if(output_encapsulated_key_length == nullptr) {
280 }
281
282 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
283 *output_encapsulated_key_length = kem.encapsulated_key_length();
284 return BOTAN_FFI_SUCCESS;
285 });
286}
287
289 botan_rng_t rng,
290 const uint8_t salt[],
291 size_t salt_len,
292 size_t desired_shared_key_len,
293 uint8_t shared_key_out[],
294 size_t* shared_key_len,
295 uint8_t encapsulated_key_out[],
296 size_t* encapsulated_key_len) {
297 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
298 const auto result = kem.encrypt(safe_get(rng), desired_shared_key_len, {salt, salt_len});
299
300 int rc = write_vec_output(encapsulated_key_out, encapsulated_key_len, result.encapsulated_shared_key());
301
302 if(rc != 0)
303 return rc;
304
305 return write_vec_output(shared_key_out, shared_key_len, result.shared_key());
306 });
307}
308
310 if(op == nullptr || padding == nullptr) {
312 }
313
314 return ffi_guard_thunk(__func__, [=]() -> int {
315 auto pk = std::make_unique<Botan::PK_KEM_Decryptor>(safe_get(key_obj), Botan::system_rng(), padding);
316 *op = new botan_pk_op_kem_decrypt_struct(std::move(pk));
317 return BOTAN_FFI_SUCCESS;
318 });
319}
320
322 size_t desired_shared_key_length,
323 size_t* output_shared_key_length) {
324 if(output_shared_key_length == nullptr) {
326 }
327
328 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
329 *output_shared_key_length = kem.shared_key_length(desired_shared_key_length);
330 return BOTAN_FFI_SUCCESS;
331 });
332}
333
335 const uint8_t salt[],
336 size_t salt_len,
337 const uint8_t encapsulated_key[],
338 size_t encapsulated_key_len,
339 size_t desired_shared_key_len,
340 uint8_t shared_key_out[],
341 size_t* shared_key_len) {
342 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
343 const auto shared_key =
344 kem.decrypt(encapsulated_key, encapsulated_key_len, desired_shared_key_len, salt, salt_len);
345
346 write_vec_output(shared_key_out, shared_key_len, shared_key);
347 });
348}
349
353}
struct botan_pk_op_kem_decrypt_struct * botan_pk_op_kem_decrypt_t
Definition ffi.h:1685
struct botan_pubkey_struct * botan_pubkey_t
Definition ffi.h:1280
#define BOTAN_PUBKEY_DER_FORMAT_SIGNATURE
Definition ffi.h:1585
struct botan_pk_op_decrypt_struct * botan_pk_op_decrypt_t
Definition ffi.h:1564
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1066
struct botan_pk_op_encrypt_struct * botan_pk_op_encrypt_t
Definition ffi.h:1540
struct botan_pk_op_kem_encrypt_struct * botan_pk_op_kem_encrypt_t
Definition ffi.h:1655
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:143
struct botan_pk_op_ka_struct * botan_pk_op_ka_t
Definition ffi.h:1626
struct botan_pk_op_sign_struct * botan_pk_op_sign_t
Definition ffi.h:1587
void * botan_view_ctx
Definition ffi.h:134
struct botan_rng_struct * botan_rng_t
Definition ffi.h:260
@ BOTAN_FFI_INVALID_VERIFIER
Definition ffi.h:104
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition ffi.h:117
@ BOTAN_FFI_ERROR_INVALID_INPUT
Definition ffi.h:106
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:118
@ BOTAN_FFI_SUCCESS
Definition ffi.h:103
struct botan_pk_op_verify_struct * botan_pk_op_verify_t
Definition ffi.h:1607
int botan_pk_op_encrypt(botan_pk_op_encrypt_t op, botan_rng_t rng_obj, uint8_t out[], size_t *out_len, const uint8_t plaintext[], size_t plaintext_len)
Definition ffi_pk_op.cpp:57
int botan_pk_op_decrypt(botan_pk_op_decrypt_t op, uint8_t out[], size_t *out_len, const uint8_t ciphertext[], size_t ciphertext_len)
int botan_pk_op_kem_decrypt_create(botan_pk_op_kem_decrypt_t *op, botan_privkey_t key_obj, const char *padding)
int botan_pk_op_sign_output_length(botan_pk_op_sign_t op, size_t *sig_len)
int botan_pk_op_key_agreement_export_public(botan_privkey_t key, uint8_t out[], size_t *out_len)
int botan_pk_op_kem_decrypt_shared_key(botan_pk_op_kem_decrypt_t op, const uint8_t salt[], size_t salt_len, const uint8_t encapsulated_key[], size_t encapsulated_key_len, size_t desired_shared_key_len, uint8_t shared_key_out[], size_t *shared_key_len)
int botan_pk_op_kem_encrypt_shared_key_length(botan_pk_op_kem_encrypt_t op, size_t desired_shared_key_length, size_t *output_shared_key_length)
int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t *out_len)
int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len)
int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op)
Definition ffi_pk_op.cpp:92
int botan_pk_op_verify_create(botan_pk_op_verify_t *op, botan_pubkey_t key_obj, const char *hash, uint32_t flags)
int botan_pk_op_kem_encrypt_create_shared_key(botan_pk_op_kem_encrypt_t op, botan_rng_t rng, const uint8_t salt[], size_t salt_len, size_t desired_shared_key_len, uint8_t shared_key_out[], size_t *shared_key_len, uint8_t encapsulated_key_out[], size_t *encapsulated_key_len)
int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op)
int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng_obj, uint8_t out[], size_t *out_len)
int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len)
int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t *op, botan_pubkey_t key_obj, const char *padding, uint32_t flags)
Definition ffi_pk_op.cpp:28
int botan_pk_op_verify_destroy(botan_pk_op_verify_t op)
int botan_pk_op_kem_encrypt_create(botan_pk_op_kem_encrypt_t *op, botan_pubkey_t key_obj, const char *padding)
int botan_pk_op_key_agreement_view_public(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
int botan_pk_op_kem_encrypt_encapsulated_key_length(botan_pk_op_kem_encrypt_t op, size_t *output_encapsulated_key_length)
int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len)
int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op, size_t ctext_len, size_t *ptext_len)
Definition ffi_pk_op.cpp:96
int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op, size_t ptext_len, size_t *ctext_len)
Definition ffi_pk_op.cpp:50
int botan_pk_op_key_agreement(botan_pk_op_ka_t op, uint8_t out[], size_t *out_len, const uint8_t other_key[], size_t other_key_len, const uint8_t salt[], size_t salt_len)
int botan_pk_op_kem_encrypt_destroy(botan_pk_op_kem_encrypt_t op)
int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t *op, botan_privkey_t key_obj, const char *padding, uint32_t flags)
Definition ffi_pk_op.cpp:71
int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op)
Definition ffi_pk_op.cpp:46
int botan_pk_op_kem_decrypt_shared_key_length(botan_pk_op_kem_decrypt_t op, size_t desired_shared_key_length, size_t *output_shared_key_length)
int botan_pk_op_sign_create(botan_pk_op_sign_t *op, botan_privkey_t key_obj, const char *hash, uint32_t flags)
int botan_pk_op_kem_decrypt_destroy(botan_pk_op_kem_decrypt_t op)
int botan_pk_op_sign_destroy(botan_pk_op_sign_t op)
int botan_pk_op_key_agreement_create(botan_pk_op_ka_t *op, botan_privkey_t key_obj, const char *kdf, uint32_t flags)
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:124
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:143
#define BOTAN_FFI_DECLARE_STRUCT(NAME, TYPE, MAGIC)
Definition ffi_util.h:51
int copy_view_bin(uint8_t out[], size_t *out_len, Fn fn, Args... args)
Definition ffi_util.h:163
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:63
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, const std::vector< uint8_t, Alloc > &buf)
Definition ffi_util.h:146
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition ffi.cpp:116
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition ffi_util.h:201
RandomNumberGenerator & system_rng()