30#if !defined(SIGNET_ENABLE_COMMERCIAL) || !SIGNET_ENABLE_COMMERCIAL
31#error "pme_facade.hpp requires SIGNET_ENABLE_COMMERCIAL=ON"
44#include <unordered_map>
91 if (size != KEY_SIZE) {
92 throw std::invalid_argument(
93 "KeyHandle requires exactly 32 bytes (AES-256), got " +
94 std::to_string(size));
97 std::memcpy(h.key_.data(),
data, KEY_SIZE);
108 reinterpret_cast<const uint8_t*
>(seed.data()), seed.size());
110 reinterpret_cast<const uint8_t*
>(
"signet-pme-test-key"),
111 19, h.key_.data(), KEY_SIZE);
127 : key_(other.key_), valid_(other.valid_) {
129 std::memset(other.key_.data(), 0, KEY_SIZE);
130 other.valid_ =
false;
134 if (
this != &other) {
140 valid_ = other.valid_;
142 std::memset(other.key_.data(), 0, KEY_SIZE);
143 other.valid_ =
false;
152 [[nodiscard]]
bool is_valid() const noexcept {
return valid_; }
155 static constexpr size_t key_size() noexcept {
return KEY_SIZE; }
160 [[nodiscard]]
const uint8_t*
data() const noexcept {
return key_.data(); }
164 return std::vector<uint8_t>(key_.begin(), key_.end());
169 static constexpr size_t KEY_SIZE = 32;
170 std::array<uint8_t, KEY_SIZE> key_;
209 throw std::runtime_error(
"KeyHandle is not valid (moved or not initialised)");
224 std::string info =
"signet-pme-col:" +
225 std::to_string(
static_cast<int>(cls)) +
":" + col_name;
234 reinterpret_cast<const uint8_t*
>(info.data()),
235 info.size(), spec.
key.data(), 32);
285 if (name == column_name)
return true;
294 throw std::runtime_error(
"KeyHandle is not valid");
308 std::string info =
"signet-pme-col:" +
309 std::to_string(
static_cast<int>(cls)) +
":" + col_name;
318 reinterpret_cast<const uint8_t*
>(info.data()),
319 info.size(), spec.
key.data(), 32);
Abstract cipher interface, GCM/CTR adapters, CipherFactory, and platform CSPRNG.
Opaque handle to AES-256 key material held in a SecureKeyBuffer.
KeyHandle(const KeyHandle &)=delete
static KeyHandle from_seed(const std::string &seed)
Construct from a deterministic seed (for benchmarking/testing ONLY).
KeyHandle & operator=(KeyHandle &&other) noexcept
bool is_valid() const noexcept
Check if the handle holds a valid key.
static KeyHandle generate()
Generate a new random AES-256 key via platform CSPRNG.
std::vector< uint8_t > to_vector() const
Get key as a vector (copies — use sparingly). For EncryptionConfig construction.
static KeyHandle from_bytes(const uint8_t *data, size_t size)
Construct from raw bytes (C++ internal use only — NOT exposed to Python).
static constexpr size_t key_size() noexcept
Key size in bytes (always 32 for AES-256).
const uint8_t * data() const noexcept
Access raw key bytes. MUST NOT be exposed through FFI.
KeyHandle(KeyHandle &&other) noexcept
KeyHandle & operator=(const KeyHandle &)=delete
HKDF key derivation (RFC 5869) using HMAC-SHA256.
void fill_random_bytes(uint8_t *buf, size_t size)
Fill a buffer with cryptographically random bytes using the best available OS-level CSPRNG (CWE-338: ...
void secure_zero(void *ptr, size_t size)
Securely zero a memory region (not optimized out by the compiler).
bool lock_memory(void *ptr, size_t size)
Lock a memory region so it is not paged to swap.
void unlock_memory(void *ptr, size_t size)
Unlock a previously locked memory region.
ColumnClassification
Classification determines whether a column is encrypted and with which key derivation context.
@ RESTRICTED
Encrypted — general restricted data.
@ HEALTH
Encrypted — health/biometric data (HIPAA)
@ PII
Encrypted — personally identifiable information.
@ FINANCIAL
Encrypted — financial data (prices, quantities)
@ REFERENCE
Unencrypted — public/reference data.
std::array< uint8_t, 32 > hkdf_extract(const uint8_t *salt, size_t salt_size, const uint8_t *ikm, size_t ikm_size)
HKDF-Extract (RFC 5869 §2.2): Extract a pseudorandom key from input keying material.
bool hkdf_expand(const std::array< uint8_t, 32 > &prk, const uint8_t *info, size_t info_size, uint8_t *output, size_t output_size)
HKDF-Expand (RFC 5869 §2.3): Expand PRK to output keying material.
@ INTERNAL
Key material stored directly in file metadata (testing/dev).
EncryptionAlgorithm
Encryption algorithm identifier.
@ AES_GCM_CTR_V1
AES-256-GCM for footer, AES-256-CTR for column data (Parquet default).
Parquet Modular Encryption (PME) orchestrator – encrypts and decrypts Parquet file components (footer...
Specifies the encryption key for a single Parquet column.
std::string column_name
Parquet column path (e.g. "a.b.c").
std::vector< uint8_t > key
32-byte AES-256 key (INTERNAL mode).
High-level decryption options for ParquetReader.
std::string aad_prefix
AAD prefix (must match writer).
bool encrypted_footer
Whether the footer was encrypted (must match writer).
EncryptionAlgorithm algorithm
Algorithm must match the writer's algorithm.
std::vector< std::string > authorised_columns
Authorised columns for this reader.
std::unordered_map< std::string, ColumnClassification > column_classes
Column classifications (must match writer for correct key derivation).
EncryptionConfig build_config(const KeyHandle &master_key) const
Build the low-level EncryptionConfig for decryption.
void authorise(const std::string &column_name)
Authorise a column for reading.
void classify(const std::string &column_name, ColumnClassification cls)
Classify a column (must match writer classification for correct HKDF).
bool is_authorised(const std::string &column_name) const
Check if a column is authorised for this reader.
High-level encryption options for ParquetWriter.
std::unordered_map< std::string, ColumnClassification > column_classes
Column classifications.
std::string aad_prefix
AAD prefix — typically a file URI or tenant identifier.
EncryptionAlgorithm algorithm
Algorithm: GCM for both footer and columns (default), or GCM footer + CTR columns.
void classify(const std::string &column_name, ColumnClassification cls)
Classify a column for encryption.
bool encrypt_footer
Whether to encrypt the footer (true) or sign it with HMAC (false).
EncryptionConfig build_config(const KeyHandle &master_key) const
Build the low-level EncryptionConfig from this facade.
Top-level configuration structure that drives FileEncryptor / FileDecryptor.
bool encrypt_footer
If true, the footer is encrypted.
std::vector< uint8_t > footer_key
32-byte AES-256 key for encrypting the Parquet footer (FileMetaData).
KeyMode key_mode
INTERNAL: keys stored in file metadata. EXTERNAL: KMS references only.
std::string aad_prefix
AAD prefix – typically a file identifier or URI.
EncryptionAlgorithm algorithm
Encryption algorithm (GCM everywhere, or GCM-footer + CTR-columns).
std::vector< ColumnKeySpec > column_keys
Per-column key specifications. Columns listed here get their own key.