Skip to content

Commit 883dcce

Browse files
DX-108149: Add support for CBC abd GCM encryption modes
1 parent 4f197f6 commit 883dcce

24 files changed

+2172
-300
lines changed

.github/workflows/csharp.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ jobs:
9898
run: ci/scripts/csharp_test.sh $(pwd)
9999

100100
macos:
101-
name: AMD64 macOS 13 C# ${{ matrix.dotnet }}
102-
runs-on: macos-13
101+
name: AMD64 macOS 15 C# ${{ matrix.dotnet }}
102+
runs-on: macos-15-intel
103103
if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
104104
timeout-minutes: 15
105105
strategy:

.github/workflows/js.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ jobs:
8686
run: archery docker push debian-js
8787

8888
macos:
89-
name: AMD64 macOS 13 NodeJS ${{ matrix.node }}
90-
runs-on: macos-13
89+
name: AMD64 macOS 15 NodeJS ${{ matrix.node }}
90+
runs-on: macos-15-intel
9191
if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
9292
timeout-minutes: 45
9393
strategy:

cpp/src/gandiva/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ set(SRC_FILES
6464
decimal_xlarge.cc
6565
engine.cc
6666
date_utils.cc
67-
encrypt_utils.cc
67+
encrypt_utils_common.cc
68+
encrypt_utils_ecb.cc
69+
encrypt_utils_cbc.cc
70+
encrypt_utils_gcm.cc
71+
encrypt_mode_dispatcher.cc
6872
expr_decomposer.cc
6973
expr_validator.cc
7074
expression.cc
@@ -262,7 +266,10 @@ add_gandiva_test(internals-test
262266
llvm_generator_test.cc
263267
annotator_test.cc
264268
tree_expr_test.cc
265-
encrypt_utils_test.cc
269+
encrypt_utils_ecb_test.cc
270+
encrypt_utils_cbc_test.cc
271+
encrypt_utils_gcm_test.cc
272+
encrypt_utils_common_test.cc
266273
expr_decomposer_test.cc
267274
exported_funcs_registry_test.cc
268275
expression_registry_test.cc
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License") you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
#include "gandiva/encrypt_mode_dispatcher.h"
19+
#include "gandiva/encrypt_utils_ecb.h"
20+
#include "gandiva/encrypt_utils_cbc.h"
21+
#include "gandiva/encrypt_utils_gcm.h"
22+
#include "arrow/util/string.h"
23+
#include <string>
24+
#include <sstream>
25+
#include <stdexcept>
26+
#include <vector>
27+
28+
namespace gandiva {
29+
30+
// Supported encryption modes
31+
static const std::vector<std::string_view> SUPPORTED_MODES = {
32+
AES_ECB_MODE, AES_ECB_PKCS7_MODE, AES_ECB_NONE_MODE,
33+
AES_CBC_MODE, AES_CBC_PKCS7_MODE, AES_CBC_NONE_MODE,
34+
AES_GCM_MODE
35+
};
36+
37+
enum class EncryptionMode {
38+
ECB,
39+
ECB_PKCS7,
40+
ECB_NONE,
41+
CBC,
42+
CBC_PKCS7,
43+
CBC_NONE,
44+
GCM,
45+
UNKNOWN
46+
};
47+
48+
EncryptionMode ParseEncryptionMode(std::string_view mode_str) {
49+
if (mode_str == AES_ECB_MODE) return EncryptionMode::ECB;
50+
if (mode_str == AES_ECB_PKCS7_MODE) return EncryptionMode::ECB_PKCS7;
51+
if (mode_str == AES_ECB_NONE_MODE) return EncryptionMode::ECB_NONE;
52+
if (mode_str == AES_CBC_MODE) return EncryptionMode::CBC;
53+
if (mode_str == AES_CBC_PKCS7_MODE) return EncryptionMode::CBC_PKCS7;
54+
if (mode_str == AES_CBC_NONE_MODE) return EncryptionMode::CBC_NONE;
55+
if (mode_str == AES_GCM_MODE) return EncryptionMode::GCM;
56+
return EncryptionMode::UNKNOWN;
57+
}
58+
59+
int32_t EncryptModeDispatcher::encrypt(
60+
const char* plaintext, int32_t plaintext_len, const char* key,
61+
int32_t key_len, const char* mode, int32_t mode_len, const char* iv,
62+
int32_t iv_len, const char* fifth_argument, int32_t fifth_argument_len,
63+
unsigned char* cipher) {
64+
std::string mode_str =
65+
arrow::internal::AsciiToUpper(std::string_view(mode, mode_len));
66+
67+
switch (ParseEncryptionMode(mode_str)) {
68+
case EncryptionMode::ECB:
69+
case EncryptionMode::ECB_PKCS7:
70+
// Shorthand AES-ECB and explicit AES-ECB-PKCS7 both use ECB with PKCS7 padding
71+
return aes_encrypt_ecb(plaintext, plaintext_len, key, key_len, true, cipher);
72+
case EncryptionMode::ECB_NONE:
73+
// ECB without padding
74+
return aes_encrypt_ecb(plaintext, plaintext_len, key, key_len, false, cipher);
75+
case EncryptionMode::CBC:
76+
case EncryptionMode::CBC_PKCS7:
77+
// Shorthand AES-CBC and explicit AES-CBC-PKCS7 both use CBC with PKCS7
78+
return aes_encrypt_cbc(plaintext, plaintext_len, key, key_len,
79+
iv, iv_len, true, cipher);
80+
case EncryptionMode::CBC_NONE:
81+
// CBC without padding
82+
return aes_encrypt_cbc(plaintext, plaintext_len, key, key_len,
83+
iv, iv_len, false, cipher);
84+
case EncryptionMode::GCM:
85+
return aes_encrypt_gcm(plaintext, plaintext_len, key, key_len,
86+
iv, iv_len, fifth_argument, fifth_argument_len, cipher);
87+
case EncryptionMode::UNKNOWN:
88+
default: {
89+
std::string modes_str = arrow::internal::JoinStrings(SUPPORTED_MODES, ", ");
90+
std::ostringstream oss;
91+
oss << "Unsupported encryption mode: " << mode_str
92+
<< ". Supported modes: " << modes_str;
93+
throw std::runtime_error(oss.str());
94+
}
95+
}
96+
}
97+
98+
int32_t EncryptModeDispatcher::decrypt(
99+
const char* ciphertext, int32_t ciphertext_len, const char* key,
100+
int32_t key_len, const char* mode, int32_t mode_len, const char* iv,
101+
int32_t iv_len, const char* fifth_argument, int32_t fifth_argument_len,
102+
unsigned char* plaintext) {
103+
std::string mode_str =
104+
arrow::internal::AsciiToUpper(std::string_view(mode, mode_len));
105+
106+
switch (ParseEncryptionMode(mode_str)) {
107+
case EncryptionMode::ECB:
108+
case EncryptionMode::ECB_PKCS7:
109+
// Shorthand AES-ECB and explicit AES-ECB-PKCS7 both use ECB with PKCS7 padding
110+
return aes_decrypt_ecb(ciphertext, ciphertext_len, key, key_len, true, plaintext);
111+
case EncryptionMode::ECB_NONE:
112+
// ECB without padding
113+
return aes_decrypt_ecb(ciphertext, ciphertext_len, key, key_len, false, plaintext);
114+
case EncryptionMode::CBC:
115+
case EncryptionMode::CBC_PKCS7:
116+
// Shorthand AES-CBC and explicit AES-CBC-PKCS7 both use CBC with PKCS7
117+
return aes_decrypt_cbc(ciphertext, ciphertext_len, key, key_len,
118+
iv, iv_len, true, plaintext);
119+
case EncryptionMode::CBC_NONE:
120+
// CBC without padding
121+
return aes_decrypt_cbc(ciphertext, ciphertext_len, key, key_len,
122+
iv, iv_len, false, plaintext);
123+
case EncryptionMode::GCM:
124+
return aes_decrypt_gcm(ciphertext, ciphertext_len, key, key_len,
125+
iv, iv_len, fifth_argument, fifth_argument_len, plaintext);
126+
case EncryptionMode::UNKNOWN:
127+
default: {
128+
std::string modes_str = arrow::internal::JoinStrings(SUPPORTED_MODES, ", ");
129+
std::ostringstream oss;
130+
oss << "Unsupported decryption mode: " << mode_str
131+
<< ". Supported modes: " << modes_str;
132+
throw std::runtime_error(oss.str());
133+
}
134+
}
135+
}
136+
137+
} // namespace gandiva
138+
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License") you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
#ifndef GANDIVA_ENCRYPT_MODE_DISPATCHER_H
19+
#define GANDIVA_ENCRYPT_MODE_DISPATCHER_H
20+
21+
#include <cstdint>
22+
23+
namespace gandiva {
24+
25+
/**
26+
* Dispatcher for AES encryption/decryption based on mode string.
27+
* Routes calls to appropriate implementation.
28+
*/
29+
class EncryptModeDispatcher {
30+
public:
31+
/**
32+
* Encrypt data using the specified mode
33+
*
34+
* @param plaintext The data to encrypt
35+
* @param plaintext_len Length of plaintext in bytes
36+
* @param key The encryption key
37+
* @param key_len Length of key in bytes
38+
* @param mode Mode string
39+
* @param mode_len Length of mode string in bytes
40+
* @param iv The initialization vector (optional, only for modes that support it)
41+
* @param iv_len Length of the IV in bytes
42+
* @param fifth_argument Additional parameter (optional, only for modes that support it)
43+
* @param fifth_argument_len Length of fifth_argument in bytes
44+
* @param cipher Output buffer for encrypted data
45+
* @return Length of encrypted data in bytes
46+
* @throws std::runtime_error on encryption failure or unsupported mode
47+
*/
48+
static int32_t encrypt(const char* plaintext, int32_t plaintext_len,
49+
const char* key, int32_t key_len,
50+
const char* mode, int32_t mode_len,
51+
const char* iv, int32_t iv_len,
52+
const char* fifth_argument, int32_t fifth_argument_len,
53+
unsigned char* cipher);
54+
55+
/**
56+
* Decrypt data using the specified mode
57+
*
58+
* @param ciphertext The data to decrypt
59+
* @param ciphertext_len Length of ciphertext in bytes
60+
* @param key The decryption key
61+
* @param key_len Length of key in bytes
62+
* @param mode Mode string
63+
* @param mode_len Length of mode string in bytes
64+
* @param iv The initialization vector (optional, only for modes that support it)
65+
* @param iv_len Length of the IV in bytes
66+
* @param fifth_argument Additional parameter (optional, only for modes that support it)
67+
* @param fifth_argument_len Length of fifth_argument in bytes
68+
* @param plaintext Output buffer for decrypted data
69+
* @return Length of decrypted data in bytes
70+
* @throws std::runtime_error on decryption failure or unsupported mode
71+
*/
72+
static int32_t decrypt(const char* ciphertext, int32_t ciphertext_len,
73+
const char* key, int32_t key_len,
74+
const char* mode, int32_t mode_len,
75+
const char* iv, int32_t iv_len,
76+
const char* fifth_argument, int32_t fifth_argument_len,
77+
unsigned char* plaintext);
78+
};
79+
80+
} // namespace gandiva
81+
82+
#endif // GANDIVA_ENCRYPT_MODE_DISPATCHER_H
83+

cpp/src/gandiva/encrypt_utils.cc

Lines changed: 0 additions & 124 deletions
This file was deleted.

0 commit comments

Comments
 (0)