Merge 'Encryption: add support for other AEGIS and AES-GCM cipher variants' from Frank Denis

Now supported:
- AEGIS variants: 256, 256X2, 256X4, 128L, 128X2, 128X4
- AES-GCM variants: AES-128-GCM, AES-256-GCM
With minor changes in order to make it easy to add new ciphers later
regardless of their key size.

Reviewed-by: Avinash Sajjanshetty (@avinassh)

Closes #2899
This commit is contained in:
Pekka Enberg
2025-09-04 11:42:16 +03:00
committed by GitHub
4 changed files with 795 additions and 282 deletions

View File

@@ -2038,16 +2038,16 @@ impl Connection {
self.syms.borrow().vtab_modules.keys().cloned().collect()
}
pub fn set_encryption_key(&self, key: EncryptionKey) {
pub fn set_encryption_key(&self, key: EncryptionKey) -> Result<()> {
tracing::trace!("setting encryption key for connection");
*self.encryption_key.borrow_mut() = Some(key.clone());
self.set_encryption_context();
self.set_encryption_context()
}
pub fn set_encryption_cipher(&self, cipher_mode: CipherMode) {
pub fn set_encryption_cipher(&self, cipher_mode: CipherMode) -> Result<()> {
tracing::trace!("setting encryption cipher for connection");
self.encryption_cipher_mode.replace(Some(cipher_mode));
self.set_encryption_context();
self.set_encryption_context()
}
pub fn get_encryption_cipher_mode(&self) -> Option<CipherMode> {
@@ -2055,17 +2055,17 @@ impl Connection {
}
// if both key and cipher are set, set encryption context on pager
fn set_encryption_context(&self) {
fn set_encryption_context(&self) -> Result<()> {
let key_ref = self.encryption_key.borrow();
let Some(key) = key_ref.as_ref() else {
return;
return Ok(());
};
let Some(cipher_mode) = self.encryption_cipher_mode.get() else {
return;
return Ok(());
};
tracing::trace!("setting encryption ctx for connection");
let pager = self.pager.borrow();
pager.set_encryption_context(cipher_mode, key);
pager.set_encryption_context(cipher_mode, key)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2165,16 +2165,23 @@ impl Pager {
Ok(IOResult::Done(f(header)))
}
pub fn set_encryption_context(&self, cipher_mode: CipherMode, key: &EncryptionKey) {
pub fn set_encryption_context(
&self,
cipher_mode: CipherMode,
key: &EncryptionKey,
) -> Result<()> {
let page_size = self.page_size.get().unwrap().get() as usize;
let encryption_ctx = EncryptionContext::new(cipher_mode, key, page_size).unwrap();
let encryption_ctx = EncryptionContext::new(cipher_mode, key, page_size)?;
{
let mut io_ctx = self.io_ctx.borrow_mut();
io_ctx.set_encryption(encryption_ctx);
}
let Some(wal) = self.wal.as_ref() else { return };
let Some(wal) = self.wal.as_ref() else {
return Ok(());
};
wal.borrow_mut()
.set_io_context(self.io_ctx.borrow().clone())
.set_io_context(self.io_ctx.borrow().clone());
Ok(())
}
}

View File

@@ -317,13 +317,13 @@ fn update_pragma(
PragmaName::EncryptionKey => {
let value = parse_string(&value)?;
let key = EncryptionKey::from_hex_string(&value)?;
connection.set_encryption_key(key);
connection.set_encryption_key(key)?;
Ok((program, TransactionMode::None))
}
PragmaName::EncryptionCipher => {
let value = parse_string(&value)?;
let cipher = CipherMode::try_from(value.as_str())?;
connection.set_encryption_cipher(cipher);
connection.set_encryption_cipher(cipher)?;
Ok((program, TransactionMode::None))
}
PragmaName::Synchronous => {