From f77d5c8d3b9a34ee35d3e693415d02b463625407 Mon Sep 17 00:00:00 2001 From: Sofia Brenes Date: Wed, 20 Aug 2025 22:39:56 -0600 Subject: [PATCH 1/4] solved conflict --- cpp/src/parquet/encryption/key_toolkit_internal.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/src/parquet/encryption/key_toolkit_internal.cc b/cpp/src/parquet/encryption/key_toolkit_internal.cc index 7b068ab8f6ab..bcd84d4c7172 100644 --- a/cpp/src/parquet/encryption/key_toolkit_internal.cc +++ b/cpp/src/parquet/encryption/key_toolkit_internal.cc @@ -17,9 +17,8 @@ #include "arrow/util/base64.h" -#include "parquet/encryption/encryption.h" #include "parquet/encryption/aes_encryption.h" -#include "parquet/encryption/key_toolkit_internal.h" +#include "parquet/encryption/encryption.h" namespace parquet::encryption::internal { From 5ab6a563ed13e2bf0f5681fe2962f1bd0699d1e4 Mon Sep 17 00:00:00 2001 From: Sofia Brenes Date: Wed, 20 Aug 2025 22:40:45 -0600 Subject: [PATCH 2/4] solved conflict --- cpp/src/parquet/encryption/key_toolkit_internal.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/src/parquet/encryption/key_toolkit_internal.cc b/cpp/src/parquet/encryption/key_toolkit_internal.cc index bcd84d4c7172..7b068ab8f6ab 100644 --- a/cpp/src/parquet/encryption/key_toolkit_internal.cc +++ b/cpp/src/parquet/encryption/key_toolkit_internal.cc @@ -17,8 +17,9 @@ #include "arrow/util/base64.h" -#include "parquet/encryption/aes_encryption.h" #include "parquet/encryption/encryption.h" +#include "parquet/encryption/aes_encryption.h" +#include "parquet/encryption/key_toolkit_internal.h" namespace parquet::encryption::internal { From 52eec39de28670f6a4565546ac540b40fbdc62e7 Mon Sep 17 00:00:00 2001 From: Sofia Brenes Date: Wed, 20 Aug 2025 17:57:29 -0600 Subject: [PATCH 3/4] Refactor AesEncryptor and AesDecryptor. Move their AesCryptoContext to header file and make them inherit from EncryptorInterface and DecryptorInterface respectively --- cpp/src/parquet/encryption/aes_encryption.cc | 327 ++++++------------ cpp/src/parquet/encryption/aes_encryption.h | 82 ++++- .../parquet/encryption/decryptor_interface.h | 4 + .../parquet/encryption/encryptor_interface.h | 4 + .../encryption/write_configurations_test.cc | 3 +- 5 files changed, 173 insertions(+), 247 deletions(-) diff --git a/cpp/src/parquet/encryption/aes_encryption.cc b/cpp/src/parquet/encryption/aes_encryption.cc index 91d4e8f65354..5d082ce31153 100644 --- a/cpp/src/parquet/encryption/aes_encryption.cc +++ b/cpp/src/parquet/encryption/aes_encryption.cc @@ -17,7 +17,6 @@ #include "parquet/encryption/aes_encryption.h" -#include #include #include @@ -49,108 +48,59 @@ constexpr int32_t kBufferSizeLength = 4; throw ParquetException("Couldn't init ALG decryption"); \ } -class AesCryptoContext { - public: - AesCryptoContext(ParquetCipher::type alg_id, int32_t key_len, bool metadata, - bool include_length) { - openssl::EnsureInitialized(); +AesCryptoContext::AesCryptoContext( + ParquetCipher::type alg_id, int32_t key_len, bool metadata, bool include_length) { + openssl::EnsureInitialized(); + + length_buffer_length_ = include_length ? kBufferSizeLength : 0; + ciphertext_size_delta_ = length_buffer_length_ + kNonceLength; - length_buffer_length_ = include_length ? kBufferSizeLength : 0; - ciphertext_size_delta_ = length_buffer_length_ + kNonceLength; - - if (ParquetCipher::EXTERNAL_DBPA_V1 == alg_id) { - std::stringstream ss; - ss << "ExternalDataBatchProtectionAgent (DBPA) algorithm is not yet implemented"; - throw ParquetException(ss.str()); - } - if (ParquetCipher::AES_GCM_V1 != alg_id && ParquetCipher::AES_GCM_CTR_V1 != alg_id) { - std::stringstream ss; - ss << "Crypto algorithm " << alg_id << " is not supported"; - throw ParquetException(ss.str()); - } - if (16 != key_len && 24 != key_len && 32 != key_len) { - std::stringstream ss; - ss << "Wrong key length: " << key_len; - throw ParquetException(ss.str()); - } - - if (metadata || (ParquetCipher::AES_GCM_V1 == alg_id)) { - aes_mode_ = kGcmMode; - ciphertext_size_delta_ += kGcmTagLength; - } else { - aes_mode_ = kCtrMode; - } - - key_length_ = key_len; + if (ParquetCipher::AES_GCM_V1 != alg_id && ParquetCipher::AES_GCM_CTR_V1 != alg_id) { + std::stringstream ss; + ss << "Crypto algorithm " << alg_id << " is not supported"; + throw ParquetException(ss.str()); } - - virtual ~AesCryptoContext() = default; - - protected: - static void DeleteCipherContext(EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_free(ctx); } - - using CipherContext = std::unique_ptr; - - static CipherContext NewCipherContext() { - auto ctx = CipherContext(EVP_CIPHER_CTX_new(), DeleteCipherContext); - if (!ctx) { - throw ParquetException("Couldn't init cipher context"); - } - return ctx; + if (16 != key_len && 24 != key_len && 32 != key_len) { + std::stringstream ss; + ss << "Wrong key length: " << key_len; + throw ParquetException(ss.str()); } - int32_t aes_mode_; - int32_t key_length_; - int32_t ciphertext_size_delta_; - int32_t length_buffer_length_; -}; - -class AesEncryptor::AesEncryptorImpl : public AesCryptoContext { - public: - explicit AesEncryptorImpl(ParquetCipher::type alg_id, int32_t key_len, bool metadata, - bool write_length); - - int32_t Encrypt(span plaintext, span key, - span aad, span ciphertext); - - int32_t SignedFooterEncrypt(span footer, span key, - span aad, span nonce, - span encrypted_footer); - - [[nodiscard]] int32_t CiphertextLength(int64_t plaintext_len) const { - if (plaintext_len < 0) { - std::stringstream ss; - ss << "Negative plaintext length " << plaintext_len; - throw ParquetException(ss.str()); - } else if (plaintext_len > - std::numeric_limits::max() - ciphertext_size_delta_) { - std::stringstream ss; - ss << "Plaintext length " << plaintext_len << " plus ciphertext size delta " - << ciphertext_size_delta_ << " overflows int32"; - throw ParquetException(ss.str()); - } - - return static_cast(plaintext_len + ciphertext_size_delta_); + if (metadata || (ParquetCipher::AES_GCM_V1 == alg_id)) { + aes_mode_ = kGcmMode; + ciphertext_size_delta_ += kGcmTagLength; + } else { + aes_mode_ = kCtrMode; } - private: - [[nodiscard]] CipherContext MakeCipherContext() const; + key_length_ = key_len; +} - int32_t GcmEncrypt(span plaintext, span key, - span nonce, span aad, - span ciphertext); +AesEncryptor::AesEncryptor( + ParquetCipher::type alg_id, int32_t key_len, bool metadata, bool write_length) + : AesCryptoContext(alg_id, key_len, metadata, write_length) {} - int32_t CtrEncrypt(span plaintext, span key, - span nonce, span ciphertext); -}; +std::unique_ptr AesEncryptor::Make( + ParquetCipher::type alg_id, int32_t key_len, bool metadata, bool write_length) { + return std::make_unique(alg_id, key_len, metadata, write_length); +} -AesEncryptor::AesEncryptorImpl::AesEncryptorImpl(ParquetCipher::type alg_id, - int32_t key_len, bool metadata, - bool write_length) - : AesCryptoContext(alg_id, key_len, metadata, write_length) {} +int32_t AesEncryptor::CiphertextLength(int64_t plaintext_len) const { + if (plaintext_len < 0) { + std::stringstream ss; + ss << "Negative plaintext length " << plaintext_len; + throw ParquetException(ss.str()); + } else if (plaintext_len > + std::numeric_limits::max() - ciphertext_size_delta_) { + std::stringstream ss; + ss << "Plaintext length " << plaintext_len << " plus ciphertext size delta " + << ciphertext_size_delta_ << " overflows int32"; + throw ParquetException(ss.str()); + } + return static_cast(plaintext_len + ciphertext_size_delta_); +} -AesCryptoContext::CipherContext AesEncryptor::AesEncryptorImpl::MakeCipherContext() - const { +AesCryptoContext::CipherContext AesEncryptor::MakeCipherContext() const { auto ctx = NewCipherContext(); if (kGcmMode == aes_mode_) { // Init AES-GCM with specified key length @@ -174,7 +124,7 @@ AesCryptoContext::CipherContext AesEncryptor::AesEncryptorImpl::MakeCipherContex return ctx; } -int32_t AesEncryptor::AesEncryptorImpl::SignedFooterEncrypt( +int32_t AesEncryptor::SignedFooterEncrypt( span footer, span key, span aad, span nonce, span encrypted_footer) { if (static_cast(key_length_) != key.size()) { @@ -197,10 +147,9 @@ int32_t AesEncryptor::AesEncryptorImpl::SignedFooterEncrypt( return GcmEncrypt(footer, key, nonce, aad, encrypted_footer); } -int32_t AesEncryptor::AesEncryptorImpl::Encrypt(span plaintext, - span key, - span aad, - span ciphertext) { +int32_t AesEncryptor::Encrypt( + span plaintext, span key, span aad, + span ciphertext) { if (static_cast(key_length_) != key.size()) { std::stringstream ss; ss << "Wrong key length " << key.size() << ". Should be " << key_length_; @@ -226,11 +175,9 @@ int32_t AesEncryptor::AesEncryptorImpl::Encrypt(span plaintext, return CtrEncrypt(plaintext, key, nonce, ciphertext); } -int32_t AesEncryptor::AesEncryptorImpl::GcmEncrypt(span plaintext, - span key, - span nonce, - span aad, - span ciphertext) { +int32_t AesEncryptor::GcmEncrypt( + span plaintext, span key, span nonce, + span aad, span ciphertext) { int len; int32_t ciphertext_len; @@ -305,10 +252,9 @@ int32_t AesEncryptor::AesEncryptorImpl::GcmEncrypt(span plaintext return length_buffer_length_ + buffer_size; } -int32_t AesEncryptor::AesEncryptorImpl::CtrEncrypt(span plaintext, - span key, - span nonce, - span ciphertext) { +int32_t AesEncryptor::CtrEncrypt( + span plaintext, span key, span nonce, + span ciphertext) { int len; int32_t ciphertext_len; @@ -370,90 +316,57 @@ int32_t AesEncryptor::AesEncryptorImpl::CtrEncrypt(span plaintext return length_buffer_length_ + buffer_size; } -AesEncryptor::~AesEncryptor() = default; +AesDecryptor::AesDecryptor( + ParquetCipher::type alg_id, int32_t key_len, bool metadata, bool contains_length) + : AesCryptoContext(alg_id, key_len, metadata, contains_length) {} -int32_t AesEncryptor::SignedFooterEncrypt(span footer, - span key, - span aad, - span nonce, - span encrypted_footer) { - return impl_->SignedFooterEncrypt(footer, key, aad, nonce, encrypted_footer); -} +std::unique_ptr AesDecryptor::Make( + ParquetCipher::type alg_id, int32_t key_len, bool metadata) { + return std::make_unique(alg_id, key_len, metadata); +} -int32_t AesEncryptor::CiphertextLength(int64_t plaintext_len) const { - return impl_->CiphertextLength(plaintext_len); +int32_t AesDecryptor::PlaintextLength(int32_t ciphertext_len) const { + if (ciphertext_len < ciphertext_size_delta_) { + std::stringstream ss; + ss << "Ciphertext length " << ciphertext_len << " is invalid, expected at least " + << ciphertext_size_delta_; + throw ParquetException(ss.str()); + } + return ciphertext_len - ciphertext_size_delta_; } -int32_t AesEncryptor::Encrypt(span plaintext, span key, - span aad, span ciphertext) { - return impl_->Encrypt(plaintext, key, aad, ciphertext); +int32_t AesDecryptor::CiphertextLength(int32_t plaintext_len) const { + if (plaintext_len < 0) { + std::stringstream ss; + ss << "Negative plaintext length " << plaintext_len; + throw ParquetException(ss.str()); + } else if (plaintext_len > + std::numeric_limits::max() - ciphertext_size_delta_) { + std::stringstream ss; + ss << "Plaintext length " << plaintext_len << " plus ciphertext size delta " + << ciphertext_size_delta_ << " overflows int32"; + throw ParquetException(ss.str()); + } + return plaintext_len + ciphertext_size_delta_; } -AesEncryptor::AesEncryptor(ParquetCipher::type alg_id, int32_t key_len, bool metadata, - bool write_length) - : impl_{std::unique_ptr( - new AesEncryptorImpl(alg_id, key_len, metadata, write_length))} {} - -class AesDecryptor::AesDecryptorImpl : AesCryptoContext { - public: - explicit AesDecryptorImpl(ParquetCipher::type alg_id, int32_t key_len, bool metadata, - bool contains_length); - - int32_t Decrypt(span ciphertext, span key, - span aad, span plaintext); - - [[nodiscard]] int32_t PlaintextLength(int32_t ciphertext_len) const { - if (ciphertext_len < ciphertext_size_delta_) { - std::stringstream ss; - ss << "Ciphertext length " << ciphertext_len << " is invalid, expected at least " - << ciphertext_size_delta_; - throw ParquetException(ss.str()); - } - return ciphertext_len - ciphertext_size_delta_; +int32_t AesDecryptor::Decrypt( + span ciphertext, span key, span aad, + span plaintext) { + if (static_cast(key_length_) != key.size()) { + std::stringstream ss; + ss << "Wrong key length " << key.size() << ". Should be " << key_length_; + throw ParquetException(ss.str()); } - [[nodiscard]] int32_t CiphertextLength(int32_t plaintext_len) const { - if (plaintext_len < 0) { - std::stringstream ss; - ss << "Negative plaintext length " << plaintext_len; - throw ParquetException(ss.str()); - } else if (plaintext_len > - std::numeric_limits::max() - ciphertext_size_delta_) { - std::stringstream ss; - ss << "Plaintext length " << plaintext_len << " plus ciphertext size delta " - << ciphertext_size_delta_ << " overflows int32"; - throw ParquetException(ss.str()); - } - return plaintext_len + ciphertext_size_delta_; + if (kGcmMode == aes_mode_) { + return GcmDecrypt(ciphertext, key, aad, plaintext); } - private: - [[nodiscard]] CipherContext MakeCipherContext() const; - - /// Get the actual ciphertext length, inclusive of the length buffer length, - /// and validate that the provided buffer size is large enough. - [[nodiscard]] int32_t GetCiphertextLength(span ciphertext) const; - - int32_t GcmDecrypt(span ciphertext, span key, - span aad, span plaintext); - - int32_t CtrDecrypt(span ciphertext, span key, - span plaintext); -}; - -int32_t AesDecryptor::Decrypt(span ciphertext, span key, - span aad, span plaintext) { - return impl_->Decrypt(ciphertext, key, aad, plaintext); + return CtrDecrypt(ciphertext, key, plaintext); } -AesDecryptor::~AesDecryptor() {} - -AesDecryptor::AesDecryptorImpl::AesDecryptorImpl(ParquetCipher::type alg_id, - int32_t key_len, bool metadata, - bool contains_length) - : AesCryptoContext(alg_id, key_len, metadata, contains_length) {} - -AesCryptoContext::CipherContext AesDecryptor::AesDecryptorImpl::MakeCipherContext() +AesCryptoContext::CipherContext AesDecryptor::MakeCipherContext() const { auto ctx = NewCipherContext(); if (kGcmMode == aes_mode_) { @@ -478,32 +391,7 @@ AesCryptoContext::CipherContext AesDecryptor::AesDecryptorImpl::MakeCipherContex return ctx; } -std::unique_ptr AesEncryptor::Make(ParquetCipher::type alg_id, - int32_t key_len, bool metadata, - bool write_length) { - return std::make_unique(alg_id, key_len, metadata, write_length); -} - -AesDecryptor::AesDecryptor(ParquetCipher::type alg_id, int32_t key_len, bool metadata, - bool contains_length) - : impl_{std::make_unique(alg_id, key_len, metadata, - contains_length)} {} - -std::unique_ptr AesDecryptor::Make(ParquetCipher::type alg_id, - int32_t key_len, bool metadata) { - return std::make_unique(alg_id, key_len, metadata); -} - -int32_t AesDecryptor::PlaintextLength(int32_t ciphertext_len) const { - return impl_->PlaintextLength(ciphertext_len); -} - -int32_t AesDecryptor::CiphertextLength(int32_t plaintext_len) const { - return impl_->CiphertextLength(plaintext_len); -} - -int32_t AesDecryptor::AesDecryptorImpl::GetCiphertextLength( - span ciphertext) const { +int32_t AesDecryptor::GetCiphertextLength(span ciphertext) const { if (length_buffer_length_ > 0) { // Note: length_buffer_length_ must be either 0 or kBufferSizeLength if (ciphertext.size() < static_cast(kBufferSizeLength)) { @@ -548,10 +436,9 @@ int32_t AesDecryptor::AesDecryptorImpl::GetCiphertextLength( } } -int32_t AesDecryptor::AesDecryptorImpl::GcmDecrypt(span ciphertext, - span key, - span aad, - span plaintext) { +int32_t AesDecryptor::GcmDecrypt( + span ciphertext, span key, span aad, + span plaintext) { int len; int32_t plaintext_len; @@ -623,9 +510,8 @@ int32_t AesDecryptor::AesDecryptorImpl::GcmDecrypt(span ciphertex return plaintext_len; } -int32_t AesDecryptor::AesDecryptorImpl::CtrDecrypt(span ciphertext, - span key, - span plaintext) { +int32_t AesDecryptor::CtrDecrypt( + span ciphertext, span key, span plaintext) { int len; int32_t plaintext_len; @@ -682,23 +568,6 @@ int32_t AesDecryptor::AesDecryptorImpl::CtrDecrypt(span ciphertex return plaintext_len; } -int32_t AesDecryptor::AesDecryptorImpl::Decrypt(span ciphertext, - span key, - span aad, - span plaintext) { - if (static_cast(key_length_) != key.size()) { - std::stringstream ss; - ss << "Wrong key length " << key.size() << ". Should be " << key_length_; - throw ParquetException(ss.str()); - } - - if (kGcmMode == aes_mode_) { - return GcmDecrypt(ciphertext, key, aad, plaintext); - } - - return CtrDecrypt(ciphertext, key, plaintext); -} - #undef ENCRYPT_INIT #undef DECRYPT_INIT diff --git a/cpp/src/parquet/encryption/aes_encryption.h b/cpp/src/parquet/encryption/aes_encryption.h index 31d131f4ddd3..d2a1b349462f 100644 --- a/cpp/src/parquet/encryption/aes_encryption.h +++ b/cpp/src/parquet/encryption/aes_encryption.h @@ -18,16 +18,46 @@ #pragma once #include +#include #include "arrow/util/span.h" +#include "parquet/encryption/encryptor_interface.h" +#include "parquet/encryption/decryptor_interface.h" #include "parquet/types.h" +#include "parquet/exception.h" using parquet::ParquetCipher; namespace parquet::encryption { +class AesCryptoContext { + public: + AesCryptoContext(ParquetCipher::type alg_id, int32_t key_len, bool metadata, + bool include_length); + + virtual ~AesCryptoContext() = default; + + protected: + static void DeleteCipherContext(EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_free(ctx); } + + using CipherContext = std::unique_ptr; + + static CipherContext NewCipherContext() { + auto ctx = CipherContext(EVP_CIPHER_CTX_new(), DeleteCipherContext); + if (!ctx) { + throw ParquetException("Couldn't init cipher context"); + } + return ctx; + } + + int32_t aes_mode_; + int32_t key_length_; + int32_t ciphertext_size_delta_; + int32_t length_buffer_length_; +}; + /// Performs AES encryption operations with GCM or CTR ciphers. -class PARQUET_EXPORT AesEncryptor { +class PARQUET_EXPORT AesEncryptor : public AesCryptoContext, public EncryptorInterface { public: /// Can serve one key length only. Possible values: 16, 24, 32 bytes. /// If write_length is true, prepend ciphertext length to the ciphertext @@ -37,33 +67,42 @@ class PARQUET_EXPORT AesEncryptor { static std::unique_ptr Make(ParquetCipher::type alg_id, int32_t key_len, bool metadata, bool write_length = true); - ~AesEncryptor(); + ~AesEncryptor() = default; /// The size of the ciphertext, for this cipher and the specified plaintext length. - [[nodiscard]] int32_t CiphertextLength(int64_t plaintext_len) const; + [[nodiscard]] int32_t CiphertextLength(int64_t plaintext_len) const override; /// Encrypts plaintext with the key and aad. Key length is passed only for validation. /// If different from value in constructor, exception will be thrown. int32_t Encrypt(::arrow::util::span plaintext, ::arrow::util::span key, ::arrow::util::span aad, - ::arrow::util::span ciphertext); + ::arrow::util::span ciphertext) override; /// Encrypts plaintext footer, in order to compute footer signature (tag). int32_t SignedFooterEncrypt(::arrow::util::span footer, ::arrow::util::span key, ::arrow::util::span aad, ::arrow::util::span nonce, - ::arrow::util::span encrypted_footer); + ::arrow::util::span encrypted_footer) override; private: - // PIMPL Idiom - class AesEncryptorImpl; - std::unique_ptr impl_; + [[nodiscard]] CipherContext MakeCipherContext() const; + + int32_t GcmEncrypt(::arrow::util::span plaintext, + ::arrow::util::span key, + ::arrow::util::span nonce, + ::arrow::util::span aad, + ::arrow::util::span ciphertext); + + int32_t CtrEncrypt(::arrow::util::span plaintext, + ::arrow::util::span key, + ::arrow::util::span nonce, + ::arrow::util::span ciphertext); }; /// Performs AES decryption operations with GCM or CTR ciphers. -class PARQUET_EXPORT AesDecryptor { +class PARQUET_EXPORT AesDecryptor : public AesCryptoContext, public DecryptorInterface { public: /// \brief Construct an AesDecryptor /// @@ -77,13 +116,13 @@ class PARQUET_EXPORT AesDecryptor { static std::unique_ptr Make(ParquetCipher::type alg_id, int32_t key_len, bool metadata); - ~AesDecryptor(); + ~AesDecryptor() = default; /// The size of the plaintext, for this cipher and the specified ciphertext length. - [[nodiscard]] int32_t PlaintextLength(int32_t ciphertext_len) const; + [[nodiscard]] int32_t PlaintextLength(int32_t ciphertext_len) const override; /// The size of the ciphertext, for this cipher and the specified plaintext length. - [[nodiscard]] int32_t CiphertextLength(int32_t plaintext_len) const; + [[nodiscard]] int32_t CiphertextLength(int32_t plaintext_len) const override; /// Decrypts ciphertext with the key and aad. Key length is passed only for /// validation. If different from value in constructor, exception will be thrown. @@ -92,12 +131,23 @@ class PARQUET_EXPORT AesDecryptor { int32_t Decrypt(::arrow::util::span ciphertext, ::arrow::util::span key, ::arrow::util::span aad, - ::arrow::util::span plaintext); + ::arrow::util::span plaintext) override; private: - // PIMPL Idiom - class AesDecryptorImpl; - std::unique_ptr impl_; + [[nodiscard]] CipherContext MakeCipherContext() const; + + /// Get the actual ciphertext length, inclusive of the length buffer length, + /// and validate that the provided buffer size is large enough. + [[nodiscard]] int32_t GetCiphertextLength(::arrow::util::span ciphertext) const; + + int32_t GcmDecrypt(::arrow::util::span ciphertext, + ::arrow::util::span key, + ::arrow::util::span aad, + ::arrow::util::span plaintext); + + int32_t CtrDecrypt(::arrow::util::span ciphertext, + ::arrow::util::span key, + ::arrow::util::span plaintext); }; } // namespace parquet::encryption diff --git a/cpp/src/parquet/encryption/decryptor_interface.h b/cpp/src/parquet/encryption/decryptor_interface.h index 4844b3245b49..d820683b0d27 100644 --- a/cpp/src/parquet/encryption/decryptor_interface.h +++ b/cpp/src/parquet/encryption/decryptor_interface.h @@ -32,7 +32,11 @@ class PARQUET_EXPORT DecryptorInterface { [[nodiscard]] virtual int32_t CiphertextLength(int32_t plaintext_len) const = 0; /// Decrypt the ciphertext and leave the results in the plaintext buffer. + /// Most implementations will require the key and aad to be provided, but it is up to + /// each decryptor whether to use them or not. virtual int32_t Decrypt(::arrow::util::span ciphertext, + ::arrow::util::span key, + ::arrow::util::span aad, ::arrow::util::span plaintext) = 0; }; diff --git a/cpp/src/parquet/encryption/encryptor_interface.h b/cpp/src/parquet/encryption/encryptor_interface.h index 6e8316acc351..339e46fab78c 100644 --- a/cpp/src/parquet/encryption/encryptor_interface.h +++ b/cpp/src/parquet/encryption/encryptor_interface.h @@ -29,7 +29,11 @@ class PARQUET_EXPORT EncryptorInterface { [[nodiscard]]virtual int32_t CiphertextLength(int64_t plaintext_len) const = 0; /// Encrypt the plaintext and leave the results in the ciphertext buffer. + /// Most implementations will require the key and aad to be provided, but it is up to + /// each encryptor whether to use them or not. virtual int32_t Encrypt(::arrow::util::span plaintext, + ::arrow::util::span key, + ::arrow::util::span aad, ::arrow::util::span ciphertext) = 0; /// Encrypt footer metadata for signature verification purposes only. diff --git a/cpp/src/parquet/encryption/write_configurations_test.cc b/cpp/src/parquet/encryption/write_configurations_test.cc index b7f1d1a17158..7cf8d0aebac7 100644 --- a/cpp/src/parquet/encryption/write_configurations_test.cc +++ b/cpp/src/parquet/encryption/write_configurations_test.cc @@ -243,8 +243,7 @@ TEST_F(TestEncryptionConfiguration, EncryptOneColumnAndUseExternalDBPA) { "tmp_encrypt_one_column_and_use_external_dbpa.parquet.encrypted"); FAIL() << "Expected ParquetException was not thrown"; } catch (const parquet::ParquetException& e) { - EXPECT_STREQ("ExternalDataBatchProtectionAgent (DBPA) algorithm is not yet implemented", - e.what()); + EXPECT_STREQ("Crypto algorithm 2 is not supported", e.what()); } } From 445ac4a6aaca12a92ffd6aad4fc80395db3d25ce Mon Sep 17 00:00:00 2001 From: Sofia Brenes Date: Wed, 20 Aug 2025 22:56:18 -0600 Subject: [PATCH 4/4] Added more comments --- cpp/src/parquet/encryption/aes_encryption.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cpp/src/parquet/encryption/aes_encryption.h b/cpp/src/parquet/encryption/aes_encryption.h index d2a1b349462f..5ce919c995c6 100644 --- a/cpp/src/parquet/encryption/aes_encryption.h +++ b/cpp/src/parquet/encryption/aes_encryption.h @@ -69,6 +69,8 @@ class PARQUET_EXPORT AesEncryptor : public AesCryptoContext, public EncryptorInt ~AesEncryptor() = default; + /// Start of Encryptor Interface methods. + /// The size of the ciphertext, for this cipher and the specified plaintext length. [[nodiscard]] int32_t CiphertextLength(int64_t plaintext_len) const override; @@ -86,6 +88,8 @@ class PARQUET_EXPORT AesEncryptor : public AesCryptoContext, public EncryptorInt ::arrow::util::span nonce, ::arrow::util::span encrypted_footer) override; + /// End of Encryptor Interface methods. + private: [[nodiscard]] CipherContext MakeCipherContext() const; @@ -118,6 +122,8 @@ class PARQUET_EXPORT AesDecryptor : public AesCryptoContext, public DecryptorInt ~AesDecryptor() = default; + /// Start of Decryptor Interface methods. + /// The size of the plaintext, for this cipher and the specified ciphertext length. [[nodiscard]] int32_t PlaintextLength(int32_t ciphertext_len) const override; @@ -133,6 +139,8 @@ class PARQUET_EXPORT AesDecryptor : public AesCryptoContext, public DecryptorInt ::arrow::util::span aad, ::arrow::util::span plaintext) override; + /// End of Decryptor Interface methods. + private: [[nodiscard]] CipherContext MakeCipherContext() const;