Coverage Report

Created: 2026-07-07 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/duckdb/third_party/mbedtls/mbedtls_wrapper.cpp
Line
Count
Source
1
#include "mbedtls_wrapper.hpp"
2
3
// otherwise we have different definitions for mbedtls_pk_context / mbedtls_sha256_context
4
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
5
6
#include "duckdb/common/crypto/md5.hpp"
7
#include "duckdb/common/helper.hpp"
8
#include "mbedtls/md.h"
9
#include "mbedtls/pk.h"
10
#include "mbedtls/sha1.h"
11
#include "mbedtls/sha256.h"
12
#include "mbedtls/cipher.h"
13
14
#include "duckdb/common/random_engine.hpp"
15
#include "duckdb/common/types/timestamp.hpp"
16
#include "duckdb/main/config.hpp"
17
#include "duckdb/common/encryption_types.hpp"
18
19
#include <stdexcept>
20
21
using namespace duckdb_mbedtls;
22
using CipherType = duckdb::EncryptionTypes::CipherType;
23
using EncryptionVersion = duckdb::EncryptionTypes::EncryptionVersion;
24
using MainHeader = duckdb::MainHeader;
25
26
/*
27
# Command line tricks to help here
28
# Create a new key
29
openssl genrsa -out private.pem 2048
30
31
# Export public key
32
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
33
34
# Calculate digest and write to 'hash' file on command line
35
openssl dgst -binary -sha256 dummy > hash
36
37
# Calculate signature from hash
38
openssl pkeyutl -sign -in hash -inkey private.pem -pkeyopt digest:sha256 -out dummy.sign
39
*/
40
41
0
void MbedTlsWrapper::ComputeSha256Hash(const char *in, size_t in_len, char *out) {
42
43
0
  mbedtls_sha256_context sha_context;
44
0
  mbedtls_sha256_init(&sha_context);
45
0
  if (mbedtls_sha256_starts(&sha_context, false) ||
46
0
      mbedtls_sha256_update(&sha_context, reinterpret_cast<const unsigned char *>(in), in_len) ||
47
0
      mbedtls_sha256_finish(&sha_context, reinterpret_cast<unsigned char *>(out))) {
48
0
    throw std::runtime_error("SHA256 Error");
49
0
  }
50
0
  mbedtls_sha256_free(&sha_context);
51
0
}
52
53
0
std::string MbedTlsWrapper::ComputeSha256Hash(const std::string &file_content) {
54
0
  std::string hash;
55
0
  hash.resize(MbedTlsWrapper::SHA256_HASH_LENGTH_BYTES);
56
0
  ComputeSha256Hash(file_content.data(), file_content.size(), (char *)hash.data());
57
0
  return hash;
58
0
}
59
60
bool MbedTlsWrapper::IsValidSha256Signature(const std::string &pubkey, const std::string &signature,
61
0
                                            const std::string &sha256_hash) {
62
63
0
  if (signature.size() != 256 || sha256_hash.size() != 32) {
64
0
    throw std::runtime_error("Invalid input lengths, expected signature length 256, got " +
65
0
                             std::to_string(signature.size()) + ", hash length 32, got " +
66
0
                             std::to_string(sha256_hash.size()));
67
0
  }
68
69
0
  mbedtls_pk_context pk_context;
70
0
  mbedtls_pk_init(&pk_context);
71
72
0
  if (mbedtls_pk_parse_public_key(&pk_context, reinterpret_cast<const unsigned char *>(pubkey.c_str()),
73
0
                                  pubkey.size() + 1)) {
74
0
    throw std::runtime_error("RSA public key import error");
75
0
  }
76
77
  // actually verify
78
0
  bool valid = mbedtls_pk_verify(&pk_context, MBEDTLS_MD_SHA256,
79
0
                                 reinterpret_cast<const unsigned char *>(sha256_hash.data()), sha256_hash.size(),
80
0
                                 reinterpret_cast<const unsigned char *>(signature.data()), signature.length()) == 0;
81
82
0
  mbedtls_pk_free(&pk_context);
83
0
  return valid;
84
0
}
85
86
// used in s3fs
87
0
void MbedTlsWrapper::Hmac256(const char *key, size_t key_len, const char *message, size_t message_len, char *out) {
88
0
  mbedtls_md_context_t hmac_ctx;
89
0
  const mbedtls_md_info_t *md_type = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
90
0
  if (!md_type) {
91
0
    throw std::runtime_error("failed to init hmac");
92
0
  }
93
94
0
  if (mbedtls_md_setup(&hmac_ctx, md_type, 1) ||
95
0
      mbedtls_md_hmac_starts(&hmac_ctx, reinterpret_cast<const unsigned char *>(key), key_len) ||
96
0
      mbedtls_md_hmac_update(&hmac_ctx, reinterpret_cast<const unsigned char *>(message), message_len) ||
97
0
      mbedtls_md_hmac_finish(&hmac_ctx, reinterpret_cast<unsigned char *>(out))) {
98
0
    throw std::runtime_error("HMAC256 Error");
99
0
  }
100
0
  mbedtls_md_free(&hmac_ctx);
101
0
}
102
103
0
void MbedTlsWrapper::ToBase16(char *in, char *out, size_t len) {
104
0
  static char const HEX_CODES[] = "0123456789abcdef";
105
0
  size_t i, j;
106
107
0
  for (j = i = 0; i < len; i++) {
108
0
    int a = in[i];
109
0
    out[j++] = HEX_CODES[(a >> 4) & 0xf];
110
0
    out[j++] = HEX_CODES[a & 0xf];
111
0
  }
112
0
}
113
114
class MbedTLSCryptoHashState : public duckdb::CryptoHashState {
115
public:
116
0
  explicit MbedTLSCryptoHashState(duckdb::CryptoHashFunction function) : duckdb::CryptoHashState(function) {
117
0
    switch (function) {
118
0
    case duckdb::CryptoHashFunction::MD5:
119
0
      break;
120
0
    case duckdb::CryptoHashFunction::SHA1:
121
0
      mbedtls_sha1_init(&sha1_context);
122
0
      break;
123
0
    case duckdb::CryptoHashFunction::SHA256:
124
0
      mbedtls_sha256_init(&sha256_context);
125
0
      break;
126
0
    default:
127
0
      throw duckdb::InternalException("Unsupported crypto hash function");
128
0
    }
129
0
  }
130
131
0
  ~MbedTLSCryptoHashState() override {
132
0
    switch (GetFunction()) {
133
0
    case duckdb::CryptoHashFunction::MD5:
134
0
      break;
135
0
    case duckdb::CryptoHashFunction::SHA1:
136
0
      mbedtls_sha1_free(&sha1_context);
137
0
      break;
138
0
    case duckdb::CryptoHashFunction::SHA256:
139
0
      mbedtls_sha256_free(&sha256_context);
140
0
      break;
141
0
    default:
142
0
      break;
143
0
    }
144
0
  }
145
146
0
  void Hash(duckdb::const_data_ptr_t input, duckdb::idx_t input_len, duckdb::data_ptr_t output) override {
147
0
    switch (GetFunction()) {
148
0
    case duckdb::CryptoHashFunction::MD5: {
149
0
      duckdb::MD5Context context;
150
0
      context.Add(input, input_len);
151
0
      context.Finish(output);
152
0
      return;
153
0
    }
154
0
    case duckdb::CryptoHashFunction::SHA1:
155
0
      if (mbedtls_sha1_starts(&sha1_context) || mbedtls_sha1_update(&sha1_context, input, input_len) ||
156
0
          mbedtls_sha1_finish(&sha1_context, output)) {
157
0
        throw std::runtime_error("SHA1 Error");
158
0
      }
159
0
      return;
160
0
    case duckdb::CryptoHashFunction::SHA256:
161
0
      if (mbedtls_sha256_starts(&sha256_context, false) ||
162
0
          mbedtls_sha256_update(&sha256_context, input, input_len) ||
163
0
          mbedtls_sha256_finish(&sha256_context, output)) {
164
0
        throw std::runtime_error("SHA256 Error");
165
0
      }
166
0
      return;
167
0
    default:
168
0
      throw duckdb::InternalException("Unsupported crypto hash function");
169
0
    }
170
0
  }
171
172
private:
173
  mbedtls_sha1_context sha1_context;
174
  mbedtls_sha256_context sha256_context;
175
};
176
177
void MbedTlsWrapper::AESStateMBEDTLSFactory::Hash(duckdb::CryptoHashFunction function, duckdb::const_data_ptr_t input,
178
0
                                                  duckdb::idx_t input_len, duckdb::data_ptr_t output) const {
179
0
  switch (function) {
180
0
  case duckdb::CryptoHashFunction::MD5: {
181
0
    duckdb::MD5Context context;
182
0
    context.Add(input, input_len);
183
0
    context.Finish(output);
184
0
    return;
185
0
  }
186
0
  case duckdb::CryptoHashFunction::SHA1:
187
0
    if (mbedtls_sha1(input, input_len, output)) {
188
0
      throw std::runtime_error("SHA1 Error");
189
0
    }
190
0
    return;
191
0
  case duckdb::CryptoHashFunction::SHA256:
192
0
    if (mbedtls_sha256(input, input_len, output, false)) {
193
0
      throw std::runtime_error("SHA256 Error");
194
0
    }
195
0
    return;
196
0
  default:
197
0
    throw duckdb::InternalException("Unsupported crypto hash function");
198
0
  }
199
0
}
200
201
duckdb::unique_ptr<duckdb::CryptoHashState>
202
0
MbedTlsWrapper::AESStateMBEDTLSFactory::CreateHashState(duckdb::CryptoHashFunction function) const {
203
0
  return duckdb::make_uniq<MbedTLSCryptoHashState>(function);
204
0
}
205
206
void MbedTlsWrapper::AESStateMBEDTLSFactory::Hmac(duckdb::CryptoHashFunction function, duckdb::const_data_ptr_t key,
207
                                                  duckdb::idx_t key_len, duckdb::const_data_ptr_t input,
208
0
                                                  duckdb::idx_t input_len, duckdb::data_ptr_t output) const {
209
0
  if (function != duckdb::CryptoHashFunction::SHA256) {
210
0
    throw duckdb::NotImplementedException("MbedTLS HMAC currently only supports SHA256");
211
0
  }
212
0
  MbedTlsWrapper::Hmac256(duckdb::const_char_ptr_cast(key), key_len, duckdb::const_char_ptr_cast(input), input_len,
213
0
                          duckdb::char_ptr_cast(output));
214
0
}
215
216
0
bool MbedTlsWrapper::AESStateMBEDTLSFactory::SupportsHash(duckdb::CryptoHashFunction function) const {
217
0
  switch (function) {
218
0
  case duckdb::CryptoHashFunction::MD5:
219
0
  case duckdb::CryptoHashFunction::SHA1:
220
0
  case duckdb::CryptoHashFunction::SHA256:
221
0
    return true;
222
0
  default:
223
0
    return false;
224
0
  }
225
0
}
226
227
0
bool MbedTlsWrapper::AESStateMBEDTLSFactory::SupportsHmac(duckdb::CryptoHashFunction function) const {
228
0
  return function == duckdb::CryptoHashFunction::SHA256;
229
0
}
230
231
0
MbedTlsWrapper::SHA256State::SHA256State() : sha_context(new mbedtls_sha256_context()) {
232
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
233
234
0
  mbedtls_sha256_init(context);
235
236
0
  if (mbedtls_sha256_starts(context, false)) {
237
0
    throw std::runtime_error("SHA256 Error");
238
0
  }
239
0
}
240
241
0
MbedTlsWrapper::SHA256State::~SHA256State() {
242
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
243
0
  mbedtls_sha256_free(context);
244
0
  delete context;
245
0
}
246
247
0
void MbedTlsWrapper::SHA256State::AddString(const std::string &str) {
248
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
249
0
  if (mbedtls_sha256_update(context, (unsigned char *)str.data(), str.size())) {
250
0
    throw std::runtime_error("SHA256 Error");
251
0
  }
252
0
}
253
254
0
void MbedTlsWrapper::SHA256State::AddBytes(duckdb::const_data_ptr_t input_bytes, duckdb::idx_t len) {
255
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
256
0
  if (mbedtls_sha256_update(context, input_bytes, len)) {
257
0
    throw std::runtime_error("SHA256 Error");
258
0
  }
259
0
}
260
261
0
void MbedTlsWrapper::SHA256State::AddBytes(duckdb::data_ptr_t input_bytes, duckdb::idx_t len) {
262
0
  AddBytes(duckdb::const_data_ptr_t(input_bytes), len);
263
0
}
264
265
0
void MbedTlsWrapper::SHA256State::AddSalt(unsigned char *salt, size_t salt_len) {
266
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
267
0
  if (mbedtls_sha256_update(context, salt, salt_len)) {
268
0
    throw std::runtime_error("SHA256 Error");
269
0
  }
270
0
}
271
272
0
void MbedTlsWrapper::SHA256State::FinalizeDerivedKey(duckdb::data_ptr_t hash) {
273
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
274
275
0
  if (mbedtls_sha256_finish(context, (duckdb::data_ptr_t)hash)) {
276
0
    throw std::runtime_error("SHA256 Error");
277
0
  }
278
0
}
279
280
0
std::string MbedTlsWrapper::SHA256State::Finalize() {
281
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
282
283
0
  std::string hash;
284
0
  hash.resize(MbedTlsWrapper::SHA256_HASH_LENGTH_BYTES);
285
286
0
  if (mbedtls_sha256_finish(context, (unsigned char *)hash.data())) {
287
0
    throw std::runtime_error("SHA256 Error");
288
0
  }
289
290
0
  return hash;
291
0
}
292
293
0
void MbedTlsWrapper::SHA256State::FinishHex(char *out) {
294
0
  auto context = reinterpret_cast<mbedtls_sha256_context *>(sha_context);
295
296
0
  std::string hash;
297
0
  hash.resize(MbedTlsWrapper::SHA256_HASH_LENGTH_BYTES);
298
299
0
  if (mbedtls_sha256_finish(context, (unsigned char *)hash.data())) {
300
0
    throw std::runtime_error("SHA256 Error");
301
0
  }
302
303
0
  MbedTlsWrapper::ToBase16(const_cast<char *>(hash.c_str()), out, MbedTlsWrapper::SHA256_HASH_LENGTH_BYTES);
304
0
}
305
306
0
MbedTlsWrapper::SHA1State::SHA1State() : sha_context(new mbedtls_sha1_context()) {
307
0
  auto context = reinterpret_cast<mbedtls_sha1_context *>(sha_context);
308
309
0
  mbedtls_sha1_init(context);
310
311
0
  if (mbedtls_sha1_starts(context)) {
312
0
    throw std::runtime_error("SHA1 Error");
313
0
  }
314
0
}
315
316
0
MbedTlsWrapper::SHA1State::~SHA1State() {
317
0
  auto context = reinterpret_cast<mbedtls_sha1_context *>(sha_context);
318
0
  mbedtls_sha1_free(context);
319
0
  delete context;
320
0
}
321
322
0
void MbedTlsWrapper::SHA1State::AddString(const std::string &str) {
323
0
  auto context = reinterpret_cast<mbedtls_sha1_context *>(sha_context);
324
0
  if (mbedtls_sha1_update(context, (unsigned char *)str.data(), str.size())) {
325
0
    throw std::runtime_error("SHA1 Error");
326
0
  }
327
0
}
328
329
0
std::string MbedTlsWrapper::SHA1State::Finalize() {
330
0
  auto context = reinterpret_cast<mbedtls_sha1_context *>(sha_context);
331
332
0
  std::string hash;
333
0
  hash.resize(MbedTlsWrapper::SHA1_HASH_LENGTH_BYTES);
334
335
0
  if (mbedtls_sha1_finish(context, (unsigned char *)hash.data())) {
336
0
    throw std::runtime_error("SHA1 Error");
337
0
  }
338
339
0
  return hash;
340
0
}
341
342
0
void MbedTlsWrapper::SHA1State::FinishHex(char *out) {
343
0
  auto context = reinterpret_cast<mbedtls_sha1_context *>(sha_context);
344
345
0
  std::string hash;
346
0
  hash.resize(MbedTlsWrapper::SHA1_HASH_LENGTH_BYTES);
347
348
0
  if (mbedtls_sha1_finish(context, (unsigned char *)hash.data())) {
349
0
    throw std::runtime_error("SHA1 Error");
350
0
  }
351
352
0
  MbedTlsWrapper::ToBase16(const_cast<char *>(hash.c_str()), out, MbedTlsWrapper::SHA1_HASH_LENGTH_BYTES);
353
0
}
354
355
0
const mbedtls_cipher_info_t *MbedTlsWrapper::AESStateMBEDTLS::GetCipher(){
356
0
  switch(metadata->GetCipher()) {
357
0
    case CipherType::GCM:
358
0
        switch (metadata->GetKeyLen()) {
359
0
        case 16:
360
0
          return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_GCM);
361
0
        case 24:
362
0
          return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_192_GCM);
363
0
        case 32:
364
0
          return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_GCM);
365
0
        default:
366
0
          throw std::runtime_error("Invalid AES key length for GCM");
367
0
        }
368
0
    case CipherType::CTR:
369
0
        switch (metadata->GetKeyLen()) {
370
0
        case 16:
371
0
          return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CTR);
372
0
        case 24:
373
0
          return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_192_CTR);
374
0
        case 32:
375
0
          return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CTR);
376
0
        default:
377
0
          throw std::runtime_error("Invalid AES key length for CTR");
378
0
        }
379
0
    case CipherType::CBC:
380
0
      switch (metadata->GetKeyLen()) {
381
0
      case 16:
382
0
        return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CBC);
383
0
      case 24:
384
0
        return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_192_CBC);
385
0
      case 32:
386
0
        return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CBC);
387
0
      default:
388
0
        throw std::runtime_error("Invalid AES key length for CBC");
389
0
      }
390
0
    default:
391
0
        throw duckdb::InternalException("Invalid Encryption/Decryption Cipher: %s", duckdb::EncryptionTypes::CipherToString(metadata->GetCipher()));
392
0
  }
393
0
}
394
395
0
void MbedTlsWrapper::AESStateMBEDTLS::SecureClearData(duckdb::data_ptr_t data, duckdb::idx_t len) {
396
0
  mbedtls_platform_zeroize(data, len);
397
0
}
398
399
0
MbedTlsWrapper::AESStateMBEDTLS::AESStateMBEDTLS(duckdb::unique_ptr<duckdb::EncryptionStateMetadata> metadata_p) : EncryptionState(std::move(metadata_p)), context(duckdb::make_uniq<mbedtls_cipher_context_t>()) {
400
0
  mbedtls_cipher_init(context.get());
401
402
0
  auto cipher_info = GetCipher();
403
404
0
  if (!cipher_info) {
405
0
    throw std::runtime_error("Failed to get Cipher");
406
0
  }
407
408
0
  if (mbedtls_cipher_setup(context.get(), cipher_info)) {
409
0
    throw std::runtime_error("Failed to initialize cipher context");
410
0
  }
411
412
0
  if (metadata->GetCipher() == duckdb::EncryptionTypes::CBC && mbedtls_cipher_set_padding_mode(context.get(), MBEDTLS_PADDING_PKCS7)) {
413
0
    throw std::runtime_error("Failed to set CBC padding");
414
415
0
  }
416
0
}
417
418
0
MbedTlsWrapper::AESStateMBEDTLS::~AESStateMBEDTLS() {
419
0
  if (context) {
420
0
    mbedtls_cipher_free(context.get());
421
0
  }
422
0
}
423
424
0
void MbedTlsWrapper::AESStateMBEDTLS::GenerateRandomDataInsecure(duckdb::data_ptr_t data, duckdb::idx_t len) {
425
0
  if (!force_mbedtls) {
426
    // To use this insecure MbedTLS random number generator
427
    // we double check if force_mbedtls_unsafe is set
428
    // such that we do not accidentaly opt-in
429
0
    throw duckdb::InternalException("Insecure random generation called without setting 'force_mbedtls_unsafe' = true");
430
0
  }
431
432
0
  duckdb::RandomEngine random_engine;
433
434
0
  while (len != 0) {
435
0
    const auto random_integer = random_engine.NextRandomInteger();
436
0
    const auto next = duckdb::MinValue<duckdb::idx_t>(len, sizeof(random_integer));
437
0
    memcpy(data, duckdb::const_data_ptr_cast(&random_integer), next);
438
0
    data += next;
439
0
    len -= next;
440
0
  }
441
0
}
442
443
0
void MbedTlsWrapper::AESStateMBEDTLS::GenerateRandomData(duckdb::data_ptr_t data, duckdb::idx_t len) {
444
  // generate insecure random data
445
0
  GenerateRandomDataInsecure(data, len);
446
0
}
447
448
0
void MbedTlsWrapper::AESStateMBEDTLS::InitializeInternal(duckdb::EncryptionNonce &nonce, duckdb::const_data_ptr_t aad, duckdb::idx_t aad_len){
449
0
  if (mbedtls_cipher_set_iv(context.get(), nonce.data(), nonce.total_size())) {
450
0
    throw std::runtime_error("Failed to set IV for encryption");
451
0
  }
452
453
0
  if (aad_len > 0) {
454
0
    if (mbedtls_cipher_update_ad(context.get(), aad, aad_len)) {
455
0
      throw std::runtime_error("Failed to set AAD");
456
0
    }
457
0
  }
458
0
}
459
460
0
void MbedTlsWrapper::AESStateMBEDTLS::InitializeEncryption(duckdb::EncryptionNonce &nonce, duckdb::const_data_ptr_t key, duckdb::const_data_ptr_t aad, duckdb::idx_t aad_len) {
461
0
  mode = duckdb::EncryptionTypes::ENCRYPT;
462
463
0
  if (mbedtls_cipher_setkey(context.get(), key, metadata->GetKeyLen() * 8, MBEDTLS_ENCRYPT) != 0) {
464
0
    throw std::runtime_error("Failed to set AES key for encryption");
465
0
  }
466
467
0
  InitializeInternal(nonce, aad, aad_len);
468
0
}
469
470
0
void MbedTlsWrapper::AESStateMBEDTLS::InitializeDecryption(duckdb::EncryptionNonce &nonce, duckdb::const_data_ptr_t key, duckdb::const_data_ptr_t aad, duckdb::idx_t aad_len) {
471
0
  mode = duckdb::EncryptionTypes::DECRYPT;
472
473
0
  if (mbedtls_cipher_setkey(context.get(), key, metadata->GetKeyLen() * 8, MBEDTLS_DECRYPT)) {
474
0
    throw std::runtime_error("Failed to set AES key for encryption");
475
0
  }
476
477
0
  InitializeInternal(nonce, aad, aad_len);
478
0
}
479
480
size_t MbedTlsWrapper::AESStateMBEDTLS::Process(duckdb::const_data_ptr_t in, duckdb::idx_t in_len, duckdb::data_ptr_t out,
481
0
                                                   duckdb::idx_t out_len) {
482
483
  // GCM works in-place, CTR and CBC don't
484
0
  auto use_out_copy = in == out && metadata->GetCipher() != CipherType::GCM;
485
486
0
  auto out_ptr = out;
487
0
  std::unique_ptr<duckdb::data_t[]> out_copy;
488
0
  if (use_out_copy) {
489
0
    out_copy.reset(new duckdb::data_t[out_len]);
490
0
    out_ptr = out_copy.get();
491
0
  }
492
493
0
  size_t out_len_res = duckdb::NumericCast<size_t>(out_len);
494
0
  if (mbedtls_cipher_update(context.get(), reinterpret_cast<const unsigned char *>(in), in_len, out_ptr,
495
0
                        &out_len_res)) {
496
0
      throw std::runtime_error("Encryption or Decryption failed at Process");
497
0
    };
498
499
0
  if (use_out_copy) {
500
0
    memcpy(out, out_ptr, out_len_res);
501
0
  }
502
0
  return out_len_res;
503
0
}
504
505
0
void MbedTlsWrapper::AESStateMBEDTLS::FinalizeGCM(duckdb::data_ptr_t tag, duckdb::idx_t tag_len){
506
507
0
  switch (mode) {
508
509
0
  case duckdb::EncryptionTypes::ENCRYPT: {
510
0
    if (mbedtls_cipher_write_tag(context.get(), tag, tag_len)) {
511
0
      throw std::runtime_error("Writing tag failed");
512
0
    }
513
0
    break;
514
0
  }
515
516
0
  case duckdb::EncryptionTypes::DECRYPT: {
517
0
    if (mbedtls_cipher_check_tag(context.get(), tag, tag_len)) {
518
0
      throw duckdb::InvalidInputException(
519
0
          "Computed AES tag differs from read AES tag, are you using the right key?");
520
0
    }
521
0
    break;
522
0
  }
523
524
0
  default:
525
0
    throw duckdb::InternalException("Unhandled encryption mode %d", static_cast<int>(mode));
526
0
  }
527
0
}
528
529
size_t MbedTlsWrapper::AESStateMBEDTLS::Finalize(duckdb::data_ptr_t out, duckdb::idx_t out_len, duckdb::data_ptr_t tag,
530
0
                          duckdb::idx_t tag_len) {
531
0
  size_t result = out_len;
532
0
  if (mbedtls_cipher_finish(context.get(), out, &result)) {
533
0
    throw std::runtime_error("Encryption or Decryption failed at Finalize");
534
0
  }
535
0
  if (metadata->GetCipher() == duckdb::EncryptionTypes::GCM) {
536
0
    FinalizeGCM(tag, tag_len);
537
0
  }
538
0
  return result;
539
0
}