Skip to content

Commit

Permalink
added ciphers for CTR and OCB
Browse files Browse the repository at this point in the history
  • Loading branch information
ccfelius committed Nov 5, 2024
1 parent 46644e3 commit 39ac907
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
69 changes: 56 additions & 13 deletions src/core/crypto/crypto_primitives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,45 @@ void hex256(hash_bytes &in, hash_str &out) {
}
}

const EVP_CIPHER *GetCipher(const string &key) {
// For now, we only support GCM ciphers
switch (key.size()) {
case 16:
return EVP_aes_128_gcm();
case 24:
return EVP_aes_192_gcm();
case 32:
return EVP_aes_256_gcm();
default:
throw InternalException("Invalid AES key length");
// it's nowhere defined so this is fine
const EVP_CIPHER *GetCipher(const string &key, AESStateSSL::Algorithm algorithm) {

switch(algorithm) {
case AESStateSSL::GCM:
switch (key.size()) {
case 16:
return EVP_aes_128_gcm();
case 24:
return EVP_aes_192_gcm();
case 32:
return EVP_aes_256_gcm();
default:
throw InternalException("Invalid AES key length");
}

case AESStateSSL::CTR:
switch (key.size()) {
case 16:
return EVP_aes_128_ctr();
case 24:
return EVP_aes_192_ctr();
case 32:
return EVP_aes_256_ctr();
default:
throw InternalException("Invalid AES key length");
}
case AESStateSSL::OCB:
// For now, we only support GCM ciphers
switch (key.size()) {
case 16:
return EVP_aes_128_ocb();
case 24:
return EVP_aes_192_ocb();
case 32:
return EVP_aes_256_ocb();
default:
throw InternalException("Invalid AES key length");
}
}
}

Check warning on line 76 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 76 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 76 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 76 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 76 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 76 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Expand All @@ -62,23 +90,38 @@ bool AESStateSSL::IsOpenSSL() {
return ssl;
}

void AESStateSSL::SetEncryptionAlgorithm(string_t s_algorithm) {

if (s_algorithm == "GCM") {
algorithm = GCM;
} else if (s_algorithm == "CTR") {
algorithm = CTR;
} else if (s_algorithm == "OCB") {
algorithm = OCB;
} else {
throw InvalidInputException("Invalid encryption algorithm");
}
}

void AESStateSSL::GenerateRandomData(data_ptr_t data, idx_t len) {
// generate random bytes for nonce
RAND_bytes(data, len);
}

void AESStateSSL::InitializeEncryption(const_data_ptr_t iv, idx_t iv_len, const string *key) {
// somewhere here or earlier we should set the encryption algorithm (maybe manually)

mode = ENCRYPT;

if (1 != EVP_EncryptInit_ex(gcm_context, GetCipher(*key), NULL, const_data_ptr_cast(key->data()), iv)) {
if (1 != EVP_EncryptInit_ex(gcm_context, GetCipher(*key, algorithm), NULL, const_data_ptr_cast(key->data()), iv)) {
throw InternalException("EncryptInit failed");
}
}

void AESStateSSL::InitializeDecryption(const_data_ptr_t iv, idx_t iv_len, const string *key) {
mode = DECRYPT;

if (1 != EVP_DecryptInit_ex(gcm_context, GetCipher(*key), NULL, const_data_ptr_cast(key->data()), iv)) {
if (1 != EVP_DecryptInit_ex(gcm_context, GetCipher(*key, algorithm), NULL, const_data_ptr_cast(key->data()), iv)) {
throw InternalException("DecryptInit failed");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class DUCKDB_EXTENSION_API AESStateSSL : public duckdb::EncryptionState {
explicit AESStateSSL();
~AESStateSSL() override;

// We can use GCM, CTR or OCB
enum Algorithm { GCM, CTR, OCB };

public:
bool IsOpenSSL() override;
void InitializeEncryption(const_data_ptr_t iv, idx_t iv_len, const std::string *key) override;
Expand All @@ -36,10 +39,16 @@ class DUCKDB_EXTENSION_API AESStateSSL : public duckdb::EncryptionState {
size_t Finalize(data_ptr_t out, idx_t out_len, data_ptr_t tag, idx_t tag_len) override;
void GenerateRandomData(data_ptr_t data, idx_t len) override;

// crypto-specific functions
void SetEncryptionAlgorithm(string_t s_algorithm);

private:
bool ssl = true;
EVP_CIPHER_CTX *gcm_context;
Mode mode;

// default value is GCM
Algorithm algorithm = GCM;
};

} // namespace duckdb
Expand Down

0 comments on commit 39ac907

Please sign in to comment.