Botan 3.13.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(Botan::any_null_pointers(op, padding)) {
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 return ffi_new_object(op, std::move(pk));
42 });
43}
44
48
49int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op, size_t ptext_len, size_t* ctext_len) {
50 if(ctext_len == nullptr) {
52 }
53 return BOTAN_FFI_VISIT(op, [=](const auto& o) { *ctext_len = o.ciphertext_length(ptext_len); });
54}
55
57 botan_rng_t rng_obj,
58 uint8_t out[],
59 size_t* out_len,
60 const uint8_t plaintext[],
61 size_t plaintext_len) {
62 if(plaintext_len > 0 && plaintext == nullptr) {
64 }
65
66 return BOTAN_FFI_VISIT(op, [=](const auto& o) {
67 return write_vec_output(out, out_len, o.encrypt(plaintext, plaintext_len, safe_get(rng_obj)));
68 });
69}
70
71/*
72* Public Key Decryption
73*/
75 botan_privkey_t key_obj,
76 const char* padding,
77 uint32_t flags) {
78 if(Botan::any_null_pointers(op, padding)) {
80 }
81
82 if(flags != 0) {
84 }
85
86 return ffi_guard_thunk(__func__, [=]() -> int {
87 *op = nullptr;
88
89 auto pk = std::make_unique<Botan::PK_Decryptor_EME>(safe_get(key_obj), Botan::system_rng(), padding);
90 return ffi_new_object(op, std::move(pk));
91 });
92}
93
97
98int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op, size_t ctext_len, size_t* ptext_len) {
99 if(ptext_len == nullptr) {
101 }
102 return BOTAN_FFI_VISIT(op, [=](const auto& o) { *ptext_len = o.plaintext_length(ctext_len); });
103}
104
106 botan_pk_op_decrypt_t op, uint8_t out[], size_t* out_len, const uint8_t ciphertext[], size_t ciphertext_len) {
107 if(ciphertext_len > 0 && ciphertext == nullptr) {
109 }
110
111 return BOTAN_FFI_VISIT(
112 op, [=](const auto& o) { return write_vec_output(out, out_len, o.decrypt(ciphertext, ciphertext_len)); });
113}
114
115/*
116* Signature Generation
117*/
118int botan_pk_op_sign_create(botan_pk_op_sign_t* op, botan_privkey_t key_obj, const char* hash, uint32_t flags) {
119 if(Botan::any_null_pointers(op, hash)) {
121 }
122
123 if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) {
125 }
126
127 return ffi_guard_thunk(__func__, [=]() -> int {
128 *op = nullptr;
129
130 const bool use_der = (flags & BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) != 0;
132
133 auto pk = std::make_unique<Botan::PK_Signer>(safe_get(key_obj), Botan::system_rng(), hash, format);
134 return ffi_new_object(op, std::move(pk));
135 });
136}
137
141
143 if(sig_len == nullptr) {
145 }
146
147 return BOTAN_FFI_VISIT(op, [=](const auto& o) { *sig_len = o.signature_length(); });
148}
149
150int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len) {
151 if(in_len > 0 && in == nullptr) {
153 }
154
155 return BOTAN_FFI_VISIT(op, [=](auto& o) { o.update(in, in_len); });
156}
157
158int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng_obj, uint8_t out[], size_t* out_len) {
159 return BOTAN_FFI_VISIT(op, [=](auto& o) { return write_vec_output(out, out_len, o.signature(safe_get(rng_obj))); });
160}
161
162int botan_pk_op_verify_create(botan_pk_op_verify_t* op, botan_pubkey_t key_obj, const char* hash, uint32_t flags) {
163 if(Botan::any_null_pointers(op, hash)) {
165 }
166
167 if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) {
169 }
170
171 return ffi_guard_thunk(__func__, [=]() -> int {
172 *op = nullptr;
173 const bool use_der = (flags & BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) != 0;
175 auto pk = std::make_unique<Botan::PK_Verifier>(safe_get(key_obj), hash, format);
176 return ffi_new_object(op, std::move(pk));
177 });
178}
179
183
184int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len) {
185 if(in_len > 0 && in == nullptr) {
187 }
188
189 return BOTAN_FFI_VISIT(op, [=](auto& o) { o.update(in, in_len); });
190}
191
192int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len) {
193 if(sig_len > 0 && sig == nullptr) {
195 }
196
197 return BOTAN_FFI_VISIT(op, [=](auto& o) {
198 const bool legit = o.check_signature(sig, sig_len);
199
200 if(legit) {
201 return BOTAN_FFI_SUCCESS;
202 } else {
204 }
205 });
206}
207
208int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, botan_privkey_t key_obj, const char* kdf, uint32_t flags) {
209 if(Botan::any_null_pointers(op, kdf)) {
211 }
212
213 if(flags != 0) {
215 }
216
217 return ffi_guard_thunk(__func__, [=]() -> int {
218 *op = nullptr;
219 auto pk = std::make_unique<Botan::PK_Key_Agreement>(safe_get(key_obj), Botan::system_rng(), kdf);
220 return ffi_new_object(op, std::move(pk));
221 });
222}
223
227
228int botan_pk_op_key_agreement_export_public(botan_privkey_t key, uint8_t out[], size_t* out_len) {
229 return copy_view_bin(out, out_len, botan_pk_op_key_agreement_view_public, key);
230}
231
233 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
234 if(auto kak = dynamic_cast<const Botan::PK_Key_Agreement_Key*>(&k)) {
235 return invoke_view_callback(view, ctx, kak->public_value());
236 } else {
238 }
239 });
240}
241
243 return BOTAN_FFI_VISIT(op, [=](const auto& o) {
244 if(out_len == nullptr) {
246 }
247 *out_len = o.agreed_value_size();
248 return BOTAN_FFI_SUCCESS;
249 });
250}
251
253 uint8_t out[],
254 size_t* out_len,
255 const uint8_t other_key[],
256 size_t other_key_len,
257 const uint8_t salt[],
258 size_t salt_len) {
259 if(out_len == nullptr) {
261 }
262 if(other_key_len > 0 && other_key == nullptr) {
264 }
265 if(salt_len > 0 && salt == nullptr) {
267 }
268
269 return BOTAN_FFI_VISIT(op, [=](const auto& o) {
270 auto k = o.derive_key(*out_len, other_key, other_key_len, salt, salt_len).bits_of();
271 return write_vec_output(out, out_len, k);
272 });
273}
274
276 if(Botan::any_null_pointers(op, padding)) {
278 }
279
280 return ffi_guard_thunk(__func__, [=]() -> int {
281 auto pk = std::make_unique<Botan::PK_KEM_Encryptor>(safe_get(key_obj), padding);
282 return ffi_new_object(op, std::move(pk));
283 });
284}
285
289
291 size_t desired_shared_key_length,
292 size_t* output_shared_key_length) {
293 if(output_shared_key_length == nullptr) {
295 }
296
297 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
298 *output_shared_key_length = kem.shared_key_length(desired_shared_key_length);
299 return BOTAN_FFI_SUCCESS;
300 });
301}
302
304 size_t* output_encapsulated_key_length) {
305 if(output_encapsulated_key_length == nullptr) {
307 }
308
309 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
310 *output_encapsulated_key_length = kem.encapsulated_key_length();
311 return BOTAN_FFI_SUCCESS;
312 });
313}
314
316 botan_rng_t rng,
317 const uint8_t salt[],
318 size_t salt_len,
319 size_t desired_shared_key_len,
320 uint8_t shared_key_out[],
321 size_t* shared_key_len,
322 uint8_t encapsulated_key_out[],
323 size_t* encapsulated_key_len) {
324 if(salt_len > 0 && salt == nullptr) {
326 }
327
328 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
329 const auto result = kem.encrypt(safe_get(rng), desired_shared_key_len, {salt, salt_len});
330
331 const int rc = write_vec_output(encapsulated_key_out, encapsulated_key_len, result.encapsulated_shared_key());
332
333 if(rc != 0) {
334 return rc;
335 }
336
337 return write_vec_output(shared_key_out, shared_key_len, result.shared_key());
338 });
339}
340
342 if(Botan::any_null_pointers(op, padding)) {
344 }
345
346 return ffi_guard_thunk(__func__, [=]() -> int {
347 auto pk = std::make_unique<Botan::PK_KEM_Decryptor>(safe_get(key_obj), Botan::system_rng(), padding);
348 return ffi_new_object(op, std::move(pk));
349 });
350}
351
353 size_t desired_shared_key_length,
354 size_t* output_shared_key_length) {
355 if(output_shared_key_length == nullptr) {
357 }
358
359 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
360 *output_shared_key_length = kem.shared_key_length(desired_shared_key_length);
361 return BOTAN_FFI_SUCCESS;
362 });
363}
364
366 const uint8_t salt[],
367 size_t salt_len,
368 const uint8_t encapsulated_key[],
369 size_t encapsulated_key_len,
370 size_t desired_shared_key_len,
371 uint8_t shared_key_out[],
372 size_t* shared_key_len) {
373 if(salt_len > 0 && salt == nullptr) {
375 }
376 if(Botan::any_null_pointers(encapsulated_key, shared_key_len)) {
378 }
379
380 return BOTAN_FFI_VISIT(op, [=](auto& kem) {
381 const auto shared_key =
382 kem.decrypt(encapsulated_key, encapsulated_key_len, desired_shared_key_len, salt, salt_len);
383
384 return write_vec_output(shared_key_out, shared_key_len, shared_key);
385 });
386}
387
391}
struct botan_pk_op_kem_decrypt_struct * botan_pk_op_kem_decrypt_t
Definition ffi.h:3363
struct botan_pubkey_struct * botan_pubkey_t
Definition ffi.h:2112
#define BOTAN_PUBKEY_DER_FORMAT_SIGNATURE
Definition ffi.h:3123
struct botan_pk_op_decrypt_struct * botan_pk_op_decrypt_t
Definition ffi.h:3076
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1777
struct botan_pk_op_encrypt_struct * botan_pk_op_encrypt_t
Definition ffi.h:3025
struct botan_pk_op_kem_encrypt_struct * botan_pk_op_kem_encrypt_t
Definition ffi.h:3295
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:161
struct botan_pk_op_ka_struct * botan_pk_op_ka_t
Definition ffi.h:3224
int botan_pk_op_key_agreement_view_public(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
struct botan_pk_op_sign_struct * botan_pk_op_sign_t
Definition ffi.h:3128
void * botan_view_ctx
Definition ffi.h:152
struct botan_rng_struct * botan_rng_t
Definition ffi.h:289
@ BOTAN_FFI_INVALID_VERIFIER
Definition ffi.h:116
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition ffi.h:130
@ BOTAN_FFI_ERROR_INVALID_INPUT
Definition ffi.h:118
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:131
@ BOTAN_FFI_SUCCESS
Definition ffi.h:114
struct botan_pk_op_verify_struct * botan_pk_op_verify_t
Definition ffi.h:3179
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:56
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:94
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:98
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:49
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:74
int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op)
Definition ffi_pk_op.cpp:45
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:158
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:188
#define BOTAN_FFI_DECLARE_STRUCT(NAME, TYPE, MAGIC)
Definition ffi_util.h:61
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
Definition ffi_util.h:190
int copy_view_bin(uint8_t out[], size_t *out_len, Fn fn, Args... args)
Definition ffi_util.h:214
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:79
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
Definition ffi_util.h:178
int ffi_guard_thunk(const char *func_name, T thunk)
Definition ffi_util.h:95
int write_vec_output(uint8_t out[], size_t *out_len, std::span< const uint8_t > buf)
Definition ffi_util.h:267
RandomNumberGenerator & system_rng()
bool any_null_pointers(Ptrs... ptr)
Definition mem_utils.h:54