Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions cpp/src/gandiva/encrypt_mode_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,11 @@ int32_t EncryptModeDispatcher::encrypt(
switch (ParseEncryptionMode(mode_str)) {
case EncryptionMode::ECB:
case EncryptionMode::ECB_PKCS7:
// Shorthand AES-ECB and explicit AES-ECB-PKCS7 both use ECB with PKCS7
return aes_encrypt_ecb(plaintext, plaintext_len, key, key_len, cipher);
// Shorthand AES-ECB and explicit AES-ECB-PKCS7 both use ECB with PKCS7 padding
return aes_encrypt_ecb(plaintext, plaintext_len, key, key_len, true, cipher);
case EncryptionMode::ECB_NONE:
// ECB mode doesn't use padding, but we still call the same function
// since ECB doesn't have padding options
return aes_encrypt_ecb(plaintext, plaintext_len, key, key_len, cipher);
// ECB without padding
return aes_encrypt_ecb(plaintext, plaintext_len, key, key_len, false, cipher);
case EncryptionMode::CBC:
case EncryptionMode::CBC_PKCS7:
// Shorthand AES-CBC and explicit AES-CBC-PKCS7 both use CBC with PKCS7
Expand Down Expand Up @@ -107,12 +106,11 @@ int32_t EncryptModeDispatcher::decrypt(
switch (ParseEncryptionMode(mode_str)) {
case EncryptionMode::ECB:
case EncryptionMode::ECB_PKCS7:
// Shorthand AES-ECB and explicit AES-ECB-PKCS7 both use ECB with PKCS7
return aes_decrypt_ecb(ciphertext, ciphertext_len, key, key_len, plaintext);
// Shorthand AES-ECB and explicit AES-ECB-PKCS7 both use ECB with PKCS7 padding
return aes_decrypt_ecb(ciphertext, ciphertext_len, key, key_len, true, plaintext);
case EncryptionMode::ECB_NONE:
// ECB mode doesn't use padding, but we still call the same function
// since ECB doesn't have padding options
return aes_decrypt_ecb(ciphertext, ciphertext_len, key, key_len, plaintext);
// ECB without padding
return aes_decrypt_ecb(ciphertext, ciphertext_len, key, key_len, false, plaintext);
case EncryptionMode::CBC:
case EncryptionMode::CBC_PKCS7:
// Shorthand AES-CBC and explicit AES-CBC-PKCS7 both use CBC with PKCS7
Expand Down
18 changes: 16 additions & 2 deletions cpp/src/gandiva/encrypt_utils_ecb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const EVP_CIPHER* get_ecb_cipher_algo(int32_t key_length) {

GANDIVA_EXPORT
int32_t aes_encrypt_ecb(const char* plaintext, int32_t plaintext_len, const char* key,
int32_t key_len, unsigned char* cipher) {
int32_t key_len, bool use_padding, unsigned char* cipher) {
int32_t cipher_len = 0;
int32_t len = 0;
EVP_CIPHER_CTX* en_ctx = EVP_CIPHER_CTX_new();
Expand All @@ -66,6 +66,13 @@ int32_t aes_encrypt_ecb(const char* plaintext, int32_t plaintext_len, const char
get_openssl_error_string());
}

int padding_flag = use_padding ? 1 : 0;
if (!EVP_CIPHER_CTX_set_padding(en_ctx, padding_flag)) {
EVP_CIPHER_CTX_free(en_ctx);
throw std::runtime_error("Could not set padding mode for encryption: " +
get_openssl_error_string());
}

if (!EVP_EncryptUpdate(en_ctx, cipher, &len,
reinterpret_cast<const unsigned char*>(plaintext),
plaintext_len)) {
Expand All @@ -90,7 +97,7 @@ int32_t aes_encrypt_ecb(const char* plaintext, int32_t plaintext_len, const char

GANDIVA_EXPORT
int32_t aes_decrypt_ecb(const char* ciphertext, int32_t ciphertext_len, const char* key,
int32_t key_len, unsigned char* plaintext) {
int32_t key_len, bool use_padding, unsigned char* plaintext) {
int32_t plaintext_len = 0;
int32_t len = 0;
EVP_CIPHER_CTX* de_ctx = EVP_CIPHER_CTX_new();
Expand All @@ -108,6 +115,13 @@ int32_t aes_decrypt_ecb(const char* ciphertext, int32_t ciphertext_len, const ch
get_openssl_error_string());
}

int padding_flag = use_padding ? 1 : 0;
if (!EVP_CIPHER_CTX_set_padding(de_ctx, padding_flag)) {
EVP_CIPHER_CTX_free(de_ctx);
throw std::runtime_error("Could not set padding mode for decryption: " +
get_openssl_error_string());
}

if (!EVP_DecryptUpdate(de_ctx, plaintext, &len,
reinterpret_cast<const unsigned char*>(ciphertext),
ciphertext_len)) {
Expand Down
6 changes: 4 additions & 2 deletions cpp/src/gandiva/encrypt_utils_ecb.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ constexpr const char* AES_ECB_NONE_MODE = "AES-ECB-NONE";
* @param plaintext_len Length of plaintext in bytes
* @param key The encryption key (16, 24, or 32 bytes for 128, 192, 256-bit keys)
* @param key_len Length of key in bytes
* @param use_padding Whether to use PKCS7 padding (true) or no padding (false)
* @param cipher Output buffer for encrypted data
* @return Length of encrypted data in bytes
* @throws std::runtime_error on encryption failure
*/
GANDIVA_EXPORT
int32_t aes_encrypt_ecb(const char* plaintext, int32_t plaintext_len, const char* key,
int32_t key_len, unsigned char* cipher);
int32_t key_len, bool use_padding, unsigned char* cipher);

/**
* Decrypt data using AES-ECB algorithm (legacy, insecure)
Expand All @@ -56,13 +57,14 @@ int32_t aes_encrypt_ecb(const char* plaintext, int32_t plaintext_len, const char
* @param ciphertext_len Length of ciphertext in bytes
* @param key The decryption key (16, 24, or 32 bytes for 128, 192, 256-bit keys)
* @param key_len Length of key in bytes
* @param use_padding Whether to use PKCS7 padding (true) or no padding (false)
* @param plaintext Output buffer for decrypted data
* @return Length of decrypted data in bytes
* @throws std::runtime_error on decryption failure
*/
GANDIVA_EXPORT
int32_t aes_decrypt_ecb(const char* ciphertext, int32_t ciphertext_len, const char* key,
int32_t key_len, unsigned char* plaintext);
int32_t key_len, bool use_padding, unsigned char* plaintext);

} // namespace gandiva

20 changes: 10 additions & 10 deletions cpp/src/gandiva/encrypt_utils_ecb_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ TEST(TestAesEcbEncryptUtils, TestAesEncryptDecrypt) {
static_cast<int32_t>(strlen(reinterpret_cast<const char*>(to_encrypt)));
unsigned char cipher_1[64];

int32_t cipher_1_len = gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, cipher_1);
int32_t cipher_1_len = gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, true, cipher_1);

unsigned char decrypted_1[64];
int32_t decrypted_1_len = gandiva::aes_decrypt_ecb(reinterpret_cast<const char*>(cipher_1),
cipher_1_len, key, key_len, decrypted_1);
cipher_1_len, key, key_len, true, decrypted_1);

EXPECT_EQ(std::string(reinterpret_cast<const char*>(to_encrypt), to_encrypt_len),
std::string(reinterpret_cast<const char*>(decrypted_1), decrypted_1_len));
Expand All @@ -48,11 +48,11 @@ TEST(TestAesEcbEncryptUtils, TestAesEncryptDecrypt) {
static_cast<int32_t>(strlen(reinterpret_cast<const char*>(to_encrypt)));
unsigned char cipher_2[64];

int32_t cipher_2_len = gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, cipher_2);
int32_t cipher_2_len = gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, true, cipher_2);

unsigned char decrypted_2[64];
int32_t decrypted_2_len = gandiva::aes_decrypt_ecb(reinterpret_cast<const char*>(cipher_2),
cipher_2_len, key, key_len, decrypted_2);
cipher_2_len, key, key_len, true, decrypted_2);

EXPECT_EQ(std::string(reinterpret_cast<const char*>(to_encrypt), to_encrypt_len),
std::string(reinterpret_cast<const char*>(decrypted_2), decrypted_2_len));
Expand All @@ -66,11 +66,11 @@ TEST(TestAesEcbEncryptUtils, TestAesEncryptDecrypt) {
static_cast<int32_t>(strlen(reinterpret_cast<const char*>(to_encrypt)));
unsigned char cipher_3[64];

int32_t cipher_3_len = gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, cipher_3);
int32_t cipher_3_len = gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, true, cipher_3);

unsigned char decrypted_3[64];
int32_t decrypted_3_len = gandiva::aes_decrypt_ecb(reinterpret_cast<const char*>(cipher_3),
cipher_3_len, key, key_len, decrypted_3);
cipher_3_len, key, key_len, true, decrypted_3);

EXPECT_EQ(std::string(reinterpret_cast<const char*>(to_encrypt), to_encrypt_len),
std::string(reinterpret_cast<const char*>(decrypted_3), decrypted_3_len));
Expand All @@ -88,11 +88,11 @@ TEST(TestAesEcbEncryptUtils, TestAesEncryptDecrypt) {
static_cast<int32_t>(strlen(reinterpret_cast<const char*>(to_encrypt)));
unsigned char cipher_4[64];
ASSERT_THROW({
gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, cipher_4);
gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, true, cipher_4);
}, std::runtime_error);

ASSERT_THROW({
gandiva::aes_decrypt_ecb(cipher, cipher_len, key, key_len, plain_text);
gandiva::aes_decrypt_ecb(cipher, cipher_len, key, key_len, true, plain_text);
}, std::runtime_error);

key = "12345678";
Expand All @@ -103,10 +103,10 @@ TEST(TestAesEcbEncryptUtils, TestAesEncryptDecrypt) {
static_cast<int32_t>(strlen(reinterpret_cast<const char*>(to_encrypt)));
unsigned char cipher_5[64];
ASSERT_THROW({
gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, cipher_5);
gandiva::aes_encrypt_ecb(to_encrypt, to_encrypt_len, key, key_len, true, cipher_5);
}, std::runtime_error);
ASSERT_THROW({
gandiva::aes_decrypt_ecb(cipher, cipher_len, key, key_len, plain_text);
gandiva::aes_decrypt_ecb(cipher, cipher_len, key, key_len, true, plain_text);
}, std::runtime_error);
}

Loading