diff --git a/deps/extension/Cargo.lock b/deps/extension/Cargo.lock index 50b2c66..8368ef1 100644 --- a/deps/extension/Cargo.lock +++ b/deps/extension/Cargo.lock @@ -425,6 +425,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.8" @@ -454,7 +465,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-sqlcipher-extension" -version = "0.2.1" +version = "0.2.2" dependencies = [ "aes", "cbc", @@ -462,6 +473,7 @@ dependencies = [ "hmac", "pbkdf2", "rand_core", + "sha1", "sha2", "signal-tokenizer", ] diff --git a/deps/extension/Cargo.toml b/deps/extension/Cargo.toml index 25ed5d4..c955492 100644 --- a/deps/extension/Cargo.toml +++ b/deps/extension/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "signal-sqlcipher-extension" -version = "0.2.1" +version = "0.2.2" edition = "2021" license = "AGPL-3.0-only" @@ -23,6 +23,7 @@ cbc = "0.1.2" hmac = "0.12.1" pbkdf2 = "0.12.2" rand_core = { version = "0.6.4", "default-features" = false, features = ["getrandom"] } +sha1 = { version = "0.10.6", "default-features" = false } sha2 = { version = "0.10.8", "default-features" = false } signal-tokenizer = { git = "https://github.com/signalapp/Signal-FTS5-Extension" } diff --git a/deps/extension/src/lib.rs b/deps/extension/src/lib.rs index 6def862..3d01561 100644 --- a/deps/extension/src/lib.rs +++ b/deps/extension/src/lib.rs @@ -10,6 +10,7 @@ use core::ffi::{c_char, c_int, c_uchar, c_void}; use hmac::{Hmac, Mac}; use pbkdf2::pbkdf2_hmac; use rand_core::{OsRng, RngCore}; +use sha1::Sha1; use sha2::Sha512; pub use signal_tokenizer; @@ -70,6 +71,7 @@ extern "C" fn random(_ctx: *mut c_void, buf: *mut c_void, length: c_int) -> c_in extern "C" fn get_hmac_sz(_ctx: *mut c_void, algorithm: c_int) -> c_int { match algorithm { SQLCIPHER_HMAC_SHA512 => 64, + SQLCIPHER_HMAC_SHA1 => 20, _ => 0, } } @@ -85,9 +87,6 @@ extern "C" fn hmac( in2_sz: c_int, out: *mut c_uchar, ) -> c_int { - if algorithm != SQLCIPHER_HMAC_SHA512 { - return SQLITE_ERROR; - } if hmac_key.is_null() || in1.is_null() || out.is_null() { return SQLITE_ERROR; } @@ -99,16 +98,34 @@ extern "C" fn hmac( Some(unsafe { core::slice::from_raw_parts(in2 as *mut c_uchar, in2_sz as usize) }) }; - let Ok(mut mac) = Hmac::::new_from_slice(key) else { - return SQLITE_ERROR; - }; - mac.update(in1); - if let Some(in2) = in2 { - mac.update(in2); - } - let digest = mac.finalize().into_bytes(); - unsafe { - out.copy_from(digest.as_ptr(), digest.len()); + match algorithm { + SQLCIPHER_HMAC_SHA512 => { + let Ok(mut mac) = Hmac::::new_from_slice(key) else { + return SQLITE_ERROR; + }; + mac.update(in1); + if let Some(in2) = in2 { + mac.update(in2); + } + let digest = mac.finalize().into_bytes(); + unsafe { + out.copy_from(digest.as_ptr(), digest.len()); + }; + } + SQLCIPHER_HMAC_SHA1 => { + let Ok(mut mac) = Hmac::::new_from_slice(key) else { + return SQLITE_ERROR; + }; + mac.update(in1); + if let Some(in2) = in2 { + mac.update(in2); + } + let digest = mac.finalize().into_bytes(); + unsafe { + out.copy_from(digest.as_ptr(), digest.len()); + }; + } + _ => return SQLITE_ERROR, }; SQLITE_OK } @@ -124,16 +141,21 @@ extern "C" fn pbkdf( key_sz: c_int, key: *mut c_uchar, ) -> c_int { - if algorithm != SQLCIPHER_PBKDF2_HMAC_SHA512 { - return SQLITE_ERROR; - } if pass.is_null() || salt.is_null() || key.is_null() { return SQLITE_ERROR; } let password = unsafe { core::slice::from_raw_parts(pass as *const c_uchar, pass_sz as usize) }; let salt = unsafe { core::slice::from_raw_parts(salt as *const c_uchar, salt_sz as usize) }; let buf = unsafe { core::slice::from_raw_parts_mut(key as *mut c_uchar, key_sz as usize) }; - pbkdf2_hmac::(password, salt, workfactor as u32, buf); + match algorithm { + SQLCIPHER_PBKDF2_HMAC_SHA512 => { + pbkdf2_hmac::(password, salt, workfactor as u32, buf); + } + SQLCIPHER_PBKDF2_HMAC_SHA1 => { + pbkdf2_hmac::(password, salt, workfactor as u32, buf); + } + _ => return SQLITE_ERROR, + }; SQLITE_OK } diff --git a/deps/extension/src/sqlcipher.rs b/deps/extension/src/sqlcipher.rs index a6dee67..e12d71c 100644 --- a/deps/extension/src/sqlcipher.rs +++ b/deps/extension/src/sqlcipher.rs @@ -10,6 +10,10 @@ use core::ffi::{c_char, c_int, c_uchar, c_void}; pub const SQLCIPHER_HMAC_SHA512: c_int = 2; pub const SQLCIPHER_PBKDF2_HMAC_SHA512: c_int = 2; +// Legacy encryption primitives +pub const SQLCIPHER_HMAC_SHA1: c_int = 0; +pub const SQLCIPHER_PBKDF2_HMAC_SHA1: c_int = 0; + pub const CIPHER_ENCRYPT: c_int = 1; #[repr(C)]