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

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

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

98.29
/src/lib/ffi/ffi_pk_op.cpp
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

15
extern "C" {
16

17
using namespace Botan_FFI;
18

19
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_encrypt_struct, Botan::PK_Encryptor, 0x891F3FC3);
5✔
20
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_decrypt_struct, Botan::PK_Decryptor, 0x912F3C37);
5✔
21
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_sign_struct, Botan::PK_Signer, 0x1AF0C39F);
22✔
22
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F936);
24✔
23
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_ka_struct, Botan::PK_Key_Agreement, 0x2939CAB1);
22✔
24

25
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_kem_encrypt_struct, Botan::PK_KEM_Encryptor, 0x1D13A446);
4✔
26
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_kem_decrypt_struct, Botan::PK_KEM_Decryptor, 0x1743D8E6);
4✔
27

28
int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op, botan_pubkey_t key_obj, const char* padding, uint32_t flags) {
5✔
29
   if(op == nullptr)
5✔
30
      return BOTAN_FFI_ERROR_NULL_POINTER;
31

32
   if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE)
5✔
33
      return BOTAN_FFI_ERROR_BAD_FLAG;
34

35
   return ffi_guard_thunk(__func__, [=]() -> int {
10✔
36
      *op = nullptr;
5✔
37

38
      auto pk = std::make_unique<Botan::PK_Encryptor_EME>(safe_get(key_obj), Botan::system_rng(), padding);
5✔
39
      *op = new botan_pk_op_encrypt_struct(std::move(pk));
5✔
40
      return BOTAN_FFI_SUCCESS;
5✔
41
   });
5✔
42
}
43

44
int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
5✔
45

46
int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op, size_t ptext_len, size_t* ctext_len) {
5✔
47
   if(ctext_len == nullptr)
5✔
48
      return BOTAN_FFI_ERROR_NULL_POINTER;
49
   return BOTAN_FFI_VISIT(op, [=](const auto& o) { *ctext_len = o.ciphertext_length(ptext_len); });
10✔
50
}
51

52
int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
5✔
53
                        botan_rng_t rng_obj,
54
                        uint8_t out[],
55
                        size_t* out_len,
56
                        const uint8_t plaintext[],
57
                        size_t plaintext_len) {
58
   return BOTAN_FFI_VISIT(op, [=](const auto& o) {
15✔
59
      return write_vec_output(out, out_len, o.encrypt(plaintext, plaintext_len, safe_get(rng_obj)));
60
   });
61
}
62

63
/*
64
* Public Key Decryption
65
*/
66
int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
5✔
67
                               botan_privkey_t key_obj,
68
                               const char* padding,
69
                               uint32_t flags) {
70
   if(op == nullptr)
5✔
71
      return BOTAN_FFI_ERROR_NULL_POINTER;
72

73
   if(flags != 0)
5✔
74
      return BOTAN_FFI_ERROR_BAD_FLAG;
75

76
   return ffi_guard_thunk(__func__, [=]() -> int {
10✔
77
      *op = nullptr;
5✔
78

79
      auto pk = std::make_unique<Botan::PK_Decryptor_EME>(safe_get(key_obj), Botan::system_rng(), padding);
5✔
80
      *op = new botan_pk_op_decrypt_struct(std::move(pk));
5✔
81
      return BOTAN_FFI_SUCCESS;
5✔
82
   });
5✔
83
}
84

85
int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
5✔
86

87
int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op, size_t ctext_len, size_t* ptext_len) {
4✔
88
   if(ptext_len == nullptr)
4✔
89
      return BOTAN_FFI_ERROR_NULL_POINTER;
90
   return BOTAN_FFI_VISIT(op, [=](const auto& o) { *ptext_len = o.plaintext_length(ctext_len); });
8✔
91
}
92

93
int botan_pk_op_decrypt(
5✔
94
   botan_pk_op_decrypt_t op, uint8_t out[], size_t* out_len, const uint8_t ciphertext[], size_t ciphertext_len) {
95
   return BOTAN_FFI_VISIT(
15✔
96
      op, [=](const auto& o) { return write_vec_output(out, out_len, o.decrypt(ciphertext, ciphertext_len)); });
97
}
98

99
/*
100
* Signature Generation
101
*/
102
int botan_pk_op_sign_create(botan_pk_op_sign_t* op, botan_privkey_t key_obj, const char* hash, uint32_t flags) {
11✔
103
   if(op == nullptr)
11✔
104
      return BOTAN_FFI_ERROR_NULL_POINTER;
105

106
   if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE)
11✔
107
      return BOTAN_FFI_ERROR_BAD_FLAG;
108

109
   return ffi_guard_thunk(__func__, [=]() -> int {
22✔
110
      *op = nullptr;
22✔
111

112
      auto format = (flags & BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) ? Botan::Signature_Format::DerSequence
11✔
113
                                                                : Botan::Signature_Format::Standard;
114

115
      auto pk = std::make_unique<Botan::PK_Signer>(safe_get(key_obj), Botan::system_rng(), hash, format);
11✔
116
      *op = new botan_pk_op_sign_struct(std::move(pk));
11✔
117
      return BOTAN_FFI_SUCCESS;
11✔
118
   });
11✔
119
}
120

121
int botan_pk_op_sign_destroy(botan_pk_op_sign_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
11✔
122

123
int botan_pk_op_sign_output_length(botan_pk_op_sign_t op, size_t* sig_len) {
11✔
124
   if(sig_len == nullptr)
11✔
125
      return BOTAN_FFI_ERROR_NULL_POINTER;
126

127
   return BOTAN_FFI_VISIT(op, [=](const auto& o) { *sig_len = o.signature_length(); });
22✔
128
}
129

130
int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len) {
10✔
131
   return BOTAN_FFI_VISIT(op, [=](auto& o) { o.update(in, in_len); });
20✔
132
}
133

134
int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng_obj, uint8_t out[], size_t* out_len) {
11✔
135
   return BOTAN_FFI_VISIT(op, [=](auto& o) { return write_vec_output(out, out_len, o.signature(safe_get(rng_obj))); });
33✔
136
}
137

138
int botan_pk_op_verify_create(botan_pk_op_verify_t* op, botan_pubkey_t key_obj, const char* hash, uint32_t flags) {
12✔
139
   if(op == nullptr)
12✔
140
      return BOTAN_FFI_ERROR_NULL_POINTER;
141

142
   if(flags != 0 && flags != BOTAN_PUBKEY_DER_FORMAT_SIGNATURE)
12✔
143
      return BOTAN_FFI_ERROR_BAD_FLAG;
144

145
   return ffi_guard_thunk(__func__, [=]() -> int {
24✔
146
      *op = nullptr;
24✔
147
      auto format = (flags & BOTAN_PUBKEY_DER_FORMAT_SIGNATURE) ? Botan::Signature_Format::DerSequence
12✔
148
                                                                : Botan::Signature_Format::Standard;
149
      auto pk = std::make_unique<Botan::PK_Verifier>(safe_get(key_obj), hash, format);
12✔
150
      *op = new botan_pk_op_verify_struct(std::move(pk));
12✔
151
      return BOTAN_FFI_SUCCESS;
12✔
152
   });
12✔
153
}
154

155
int botan_pk_op_verify_destroy(botan_pk_op_verify_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
12✔
156

157
int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len) {
36✔
158
   return BOTAN_FFI_VISIT(op, [=](auto& o) { o.update(in, in_len); });
72✔
159
}
160

161
int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len) {
36✔
162
   return BOTAN_FFI_VISIT(op, [=](auto& o) {
72✔
163
      const bool legit = o.check_signature(sig, sig_len);
164

165
      if(legit)
166
         return BOTAN_FFI_SUCCESS;
167
      else
168
         return BOTAN_FFI_INVALID_VERIFIER;
169
   });
170
}
171

172
int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, botan_privkey_t key_obj, const char* kdf, uint32_t flags) {
11✔
173
   if(op == nullptr)
11✔
174
      return BOTAN_FFI_ERROR_NULL_POINTER;
175

176
   if(flags != 0)
11✔
177
      return BOTAN_FFI_ERROR_BAD_FLAG;
178

179
   return ffi_guard_thunk(__func__, [=]() -> int {
22✔
180
      *op = nullptr;
22✔
181
      auto pk = std::make_unique<Botan::PK_Key_Agreement>(safe_get(key_obj), Botan::system_rng(), kdf);
11✔
182
      *op = new botan_pk_op_ka_struct(std::move(pk));
11✔
183
      return BOTAN_FFI_SUCCESS;
11✔
184
   });
11✔
185
}
186

187
int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
11✔
188

189
int botan_pk_op_key_agreement_export_public(botan_privkey_t key, uint8_t out[], size_t* out_len) {
8✔
190
   return copy_view_bin(out, out_len, botan_pk_op_key_agreement_view_public, key);
8✔
191
}
192

193
int botan_pk_op_key_agreement_view_public(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
14✔
194
   return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
42✔
195
      if(auto kak = dynamic_cast<const Botan::PK_Key_Agreement_Key*>(&k))
196
         return invoke_view_callback(view, ctx, kak->public_value());
197
      else
198
         return BOTAN_FFI_ERROR_INVALID_INPUT;
199
   });
200
}
201

202
int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t* out_len) {
×
203
   return BOTAN_FFI_VISIT(op, [=](const auto& o) {
×
204
      if(out_len == nullptr)
205
         return BOTAN_FFI_ERROR_NULL_POINTER;
206
      *out_len = o.agreed_value_size();
207
      return BOTAN_FFI_SUCCESS;
208
   });
209
}
210

211
int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
11✔
212
                              uint8_t out[],
213
                              size_t* out_len,
214
                              const uint8_t other_key[],
215
                              size_t other_key_len,
216
                              const uint8_t salt[],
217
                              size_t salt_len) {
218
   return BOTAN_FFI_VISIT(op, [=](const auto& o) {
55✔
219
      auto k = o.derive_key(*out_len, other_key, other_key_len, salt, salt_len).bits_of();
220
      return write_vec_output(out, out_len, k);
221
   });
222
}
223

224
int botan_pk_op_kem_encrypt_create(botan_pk_op_kem_encrypt_t* op, botan_pubkey_t key_obj, const char* padding) {
2✔
225
   if(op == nullptr || padding == nullptr)
2✔
226
      return BOTAN_FFI_ERROR_NULL_POINTER;
227

228
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
229
      auto pk = std::make_unique<Botan::PK_KEM_Encryptor>(safe_get(key_obj), padding);
2✔
230
      *op = new botan_pk_op_kem_encrypt_struct(std::move(pk));
2✔
231
      return BOTAN_FFI_SUCCESS;
2✔
232
   });
2✔
233
}
234

235
int botan_pk_op_kem_encrypt_destroy(botan_pk_op_kem_encrypt_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
2✔
236

237
int botan_pk_op_kem_encrypt_shared_key_length(botan_pk_op_kem_encrypt_t op,
2✔
238
                                              size_t desired_shared_key_length,
239
                                              size_t* output_shared_key_length) {
240
   if(output_shared_key_length == nullptr)
2✔
241
      return BOTAN_FFI_ERROR_NULL_POINTER;
242

243
   return BOTAN_FFI_VISIT(op, [=](auto& kem) {
4✔
244
      *output_shared_key_length = kem.shared_key_length(desired_shared_key_length);
245
      return BOTAN_FFI_SUCCESS;
246
   });
247
}
248

249
int botan_pk_op_kem_encrypt_encapsulated_key_length(botan_pk_op_kem_encrypt_t op,
2✔
250
                                                    size_t* output_encapsulated_key_length) {
251
   if(output_encapsulated_key_length == nullptr)
2✔
252
      return BOTAN_FFI_ERROR_NULL_POINTER;
253

254
   return BOTAN_FFI_VISIT(op, [=](auto& kem) {
4✔
255
      *output_encapsulated_key_length = kem.encapsulated_key_length();
256
      return BOTAN_FFI_SUCCESS;
257
   });
258
}
259

260
int botan_pk_op_kem_encrypt_create_shared_key(botan_pk_op_kem_encrypt_t op,
2✔
261
                                              botan_rng_t rng,
262
                                              const uint8_t salt[],
263
                                              size_t salt_len,
264
                                              size_t desired_shared_key_len,
265
                                              uint8_t shared_key_out[],
266
                                              size_t* shared_key_len,
267
                                              uint8_t encapsulated_key_out[],
268
                                              size_t* encapsulated_key_len) {
269
   return BOTAN_FFI_VISIT(op, [=](auto& kem) {
8✔
270
      Botan::secure_vector<uint8_t> encapsulated_key;
271
      Botan::secure_vector<uint8_t> shared_key;
272

273
      kem.encrypt(encapsulated_key, shared_key, desired_shared_key_len, safe_get(rng), salt, salt_len);
274

275
      int rc = write_vec_output(encapsulated_key_out, encapsulated_key_len, encapsulated_key);
276

277
      if(rc != 0)
278
         return rc;
279

280
      return write_vec_output(shared_key_out, shared_key_len, shared_key);
281
   });
282
}
283

284
int botan_pk_op_kem_decrypt_create(botan_pk_op_kem_decrypt_t* op, botan_privkey_t key_obj, const char* padding) {
2✔
285
   if(op == nullptr || padding == nullptr)
2✔
286
      return BOTAN_FFI_ERROR_NULL_POINTER;
287

288
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
289
      auto pk = std::make_unique<Botan::PK_KEM_Decryptor>(safe_get(key_obj), Botan::system_rng(), padding);
2✔
290
      *op = new botan_pk_op_kem_decrypt_struct(std::move(pk));
2✔
291
      return BOTAN_FFI_SUCCESS;
2✔
292
   });
2✔
293
}
294

295
int botan_pk_op_kem_decrypt_shared_key_length(botan_pk_op_kem_decrypt_t op,
2✔
296
                                              size_t desired_shared_key_length,
297
                                              size_t* output_shared_key_length) {
298
   if(output_shared_key_length == nullptr)
2✔
299
      return BOTAN_FFI_ERROR_NULL_POINTER;
300

301
   return BOTAN_FFI_VISIT(op, [=](auto& kem) {
4✔
302
      *output_shared_key_length = kem.shared_key_length(desired_shared_key_length);
303
      return BOTAN_FFI_SUCCESS;
304
   });
305
}
306

307
int botan_pk_op_kem_decrypt_shared_key(botan_pk_op_kem_decrypt_t op,
2✔
308
                                       const uint8_t salt[],
309
                                       size_t salt_len,
310
                                       const uint8_t encapsulated_key[],
311
                                       size_t encapsulated_key_len,
312
                                       size_t desired_shared_key_len,
313
                                       uint8_t shared_key_out[],
314
                                       size_t* shared_key_len) {
315
   return BOTAN_FFI_VISIT(op, [=](auto& kem) {
6✔
316
      const auto shared_key =
317
         kem.decrypt(encapsulated_key, encapsulated_key_len, desired_shared_key_len, salt, salt_len);
318

319
      write_vec_output(shared_key_out, shared_key_len, shared_key);
320
   });
321
}
322

323
int botan_pk_op_kem_decrypt_destroy(botan_pk_op_kem_decrypt_t op) { return BOTAN_FFI_CHECKED_DELETE(op); }
2✔
324
}
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