From 35870a80470b8958b9ea4ba1273e18152f92369d Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Fri, 16 Oct 2026 11:55:48 +0200 Subject: [PATCH] Drop SQLite3MC legacy mode and the SQLCipher differential from the fuzzer --- README.md | 2 +- fuzz/Cargo.lock | 7 - fuzz/Cargo.toml | 10 +- fuzz/build.rs | 144 +----- fuzz/corpus/attach/cross-copy | Bin 138 -> 434 bytes fuzz/corpus/attach/detach-reattach | Bin 434 -> 286 bytes fuzz/corpus/attach/everything-at-once | 3 +- fuzz/corpus/attach/one-attached-correct-key | Bin 175 -> 323 bytes fuzz/corpus/attach/one-attached-omitted-key | Bin 212 -> 582 bytes fuzz/corpus/attach/rows-on-both-sides | Bin 101 -> 101 bytes fuzz/corpus/attach/two-attached | Bin 249 -> 138 bytes fuzz/corpus/attach/vacuum-attached | Bin 175 -> 286 bytes fuzz/corpus/backup/aes256-page-size-mismatch | Bin 656 -> 6120 bytes fuzz/corpus/backup/destination-has-content | Bin 397 -> 582 bytes fuzz/corpus/backup/different-ciphers | Bin 101 -> 175 bytes fuzz/corpus/backup/empty-source | Bin 286 -> 101 bytes fuzz/corpus/backup/no-page-size-set | Bin 138 -> 545 bytes .../backup/same-cipher-mismatched-page-size | Bin 2654 -> 2173 bytes fuzz/corpus/differential/compat-1 | 2 - fuzz/corpus/differential/compat-2 | Bin 508 -> 0 bytes fuzz/corpus/differential/compat-3 | 1 - fuzz/corpus/differential/compat-4 | 3 - fuzz/corpus/differential/corruption-present | 1 - .../differential/corruption-present-hmac-off | Bin 619 -> 0 bytes .../differential/corruption-present-hmac-on | Bin 175 -> 0 bytes fuzz/corpus/differential/hmac-algorithm-sha1 | Bin 915 -> 0 bytes .../corpus/differential/hmac-algorithm-sha256 | Bin 212 -> 0 bytes .../corpus/differential/hmac-algorithm-sha512 | Bin 582 -> 0 bytes fuzz/corpus/differential/hmac-default | Bin 397 -> 0 bytes fuzz/corpus/differential/hmac-off | Bin 582 -> 0 bytes fuzz/corpus/differential/hmac-on | Bin 767 -> 0 bytes fuzz/corpus/differential/kdf-default | 1 - fuzz/corpus/differential/kdf-sha1 | Bin 952 -> 0 bytes fuzz/corpus/differential/kdf-sha256 | 1 - fuzz/corpus/differential/kdf-sha512 | 3 - fuzz/corpus/differential/key-passphrase | Bin 360 -> 0 bytes fuzz/corpus/differential/key-raw | Bin 471 -> 0 bytes .../differential/key-raw-with-salt-and-header | Bin 360 -> 0 bytes .../differential/key-raw-with-salt-no-header | Bin 2765 -> 0 bytes fuzz/corpus/differential/many-ops | Bin 5252 -> 0 bytes fuzz/corpus/differential/page-size-512 | Bin 2580 -> 0 bytes fuzz/corpus/differential/page-size-65536 | 2 - fuzz/corpus/differential/page-size-default | Bin 249 -> 0 bytes fuzz/corpus/differential/writer-sqlcipher | 1 - fuzz/corpus/differential/writer-sqlite3mc | Bin 175 -> 0 bytes ...28-legacy-page-size-below-legacy-page-size | Bin 645 -> 0 bytes ...backup-aes128-legacy-small-page-short-read | Bin 364 -> 0 bytes .../findings/backup-guard-bypass-aes128-aegis | Bin 16 -> 0 bytes .../findings/backup-guard-bypass-cross-cipher | Bin 15 -> 0 bytes .../findings/backup-rc4-small-page-short-read | 3 - .../findings/shared-cache-many-siblings | Bin 767 -> 0 bytes .../shared-cache-one-sibling-wrong-key | 2 - .../findings/shared-cache-sibling-has-ops | Bin 323 -> 0 bytes ...shared-cache-wrong-key-sibling-then-vacuum | Bin 100 -> 0 bytes .../findings/vacuum-65536-page-size-corrupt | Bin 139 -> 0 bytes fuzz/corpus/findings/wal-aes256-legacy-vacuum | 1 - fuzz/corpus/native/aegis-128 | Bin 915 -> 138 bytes fuzz/corpus/native/aegis-256 | 3 +- fuzz/corpus/native/cipher-aegis | Bin 138 -> 1470 bytes fuzz/corpus/native/cipher-aes256 | Bin 1063 -> 212 bytes fuzz/corpus/native/cipher-ascon128 | Bin 101 -> 397 bytes fuzz/corpus/native/cipher-chacha20 | Bin 64 -> 693 bytes fuzz/corpus/native/cipher-rc4 | Bin 212 -> 0 bytes fuzz/corpus/native/cipher-sqlcipher | Bin 0 -> 582 bytes .../native/damage-present-authenticated | Bin 360 -> 175 bytes .../native/damage-present-unauthenticated | Bin 323 -> 175 bytes fuzz/corpus/native/key-passphrase | Bin 286 -> 64 bytes fuzz/corpus/native/key-raw | Bin 582 -> 101 bytes fuzz/corpus/native/key-raw-with-salt | 4 +- fuzz/corpus/native/legacy-set | Bin 175 -> 0 bytes fuzz/corpus/native/page-size-set | 1 - fuzz/corpus/native/plaintext-header-present | Bin 545 -> 101 bytes fuzz/corpus/native/sqlcipher-hmac-off | Bin 0 -> 5429 bytes fuzz/corpus/native/sqlcipher-hmac-sha1 | Bin 0 -> 2210 bytes fuzz/corpus/native/sqlcipher-sha1-damage | Bin 0 -> 5059 bytes fuzz/corpus/rekey/change-key | Bin 2531 -> 101 bytes fuzz/corpus/rekey/cipher-aegis | 2 +- fuzz/corpus/rekey/cipher-aes128 | Bin 1137 -> 249 bytes fuzz/corpus/rekey/cipher-aes256 | Bin 545 -> 397 bytes fuzz/corpus/rekey/cipher-ascon128 | 3 +- fuzz/corpus/rekey/cipher-chacha20 | Bin 1211 -> 434 bytes fuzz/corpus/rekey/cipher-rc4 | 3 - fuzz/corpus/rekey/cipher-sqlcipher | 1 + fuzz/corpus/rekey/decrypt | 3 +- fuzz/corpus/rekey/legacy-set | Bin 212 -> 0 bytes fuzz/corpus/rekey/many-ops-before | Bin 11460 -> 5318 bytes fuzz/corpus/rekey/ops-after-empty | Bin 545 -> 64 bytes fuzz/corpus/rekey/ops-after-present | Bin 582 -> 138 bytes fuzz/corpus/rekey/plaintext-header-present | Bin 286 -> 175 bytes .../shared_cache/all-siblings-correct-key | Bin 323 -> 64 bytes fuzz/corpus/shared_cache/many-siblings | Bin 212 -> 656 bytes .../shared_cache/mixed-correct-and-wrong | Bin 915 -> 323 bytes fuzz/corpus/shared_cache/no-siblings | 3 +- .../shared_cache/one-sibling-correct-key | Bin 878 -> 212 bytes .../corpus/shared_cache/one-sibling-wrong-key | Bin 249 -> 1581 bytes fuzz/corpus/shared_cache/sibling-has-ops | Bin 249 -> 804 bytes fuzz/corpus/wal/checkpoint-full | Bin 286 -> 138 bytes fuzz/corpus/wal/checkpoint-none | Bin 64 -> 64 bytes fuzz/corpus/wal/checkpoint-passive | Bin 804 -> 656 bytes fuzz/corpus/wal/checkpoint-restart | Bin 619 -> 360 bytes fuzz/corpus/wal/checkpoint-truncate | Bin 471 -> 1248 bytes fuzz/corpus/wal/cipher-aegis | Bin 64 -> 212 bytes fuzz/corpus/wal/cipher-aes128 | Bin 360 -> 545 bytes fuzz/corpus/wal/cipher-aes256 | Bin 175 -> 1322 bytes fuzz/corpus/wal/cipher-ascon128 | 2 +- fuzz/corpus/wal/cipher-chacha20 | Bin 64 -> 582 bytes fuzz/corpus/wal/cipher-rc4 | 4 - fuzz/corpus/wal/cipher-sqlcipher | Bin 0 -> 249 bytes fuzz/corpus/wal/legacy-wal-and-truncation | Bin 286 -> 101 bytes fuzz/corpus/wal/legacy-wal-false | Bin 101 -> 64 bytes fuzz/corpus/wal/legacy-wal-true | Bin 64 -> 175 bytes fuzz/corpus/wal/many-ops | Bin 7329 -> 2742 bytes fuzz/corpus/wal/wal-truncation-absent | Bin 79 -> 65 bytes fuzz/corpus/wal/wal-truncation-present | Bin 101 -> 101 bytes fuzz/examples/gen_native_seeds.rs | 37 +- fuzz/examples/gen_rekey_seeds.rs | 8 +- fuzz/examples/gen_seeds.rs | 163 ------- fuzz/examples/gen_wal_seeds.rs | 11 +- fuzz/fuzz_targets/differential.rs | 3 - fuzz/sqlcipher-entropy.c | 14 - fuzz/sqlcipher-ltc.h | 29 -- fuzz/sqlcipher-wrapper.c | 18 - fuzz/src/db.rs | 163 +++---- fuzz/src/entropy.rs | 53 --- fuzz/src/ffi.rs | 222 +++------ fuzz/src/input.rs | 364 ++++----------- fuzz/src/lib.rs | 13 +- fuzz/src/run.rs | 429 +++--------------- fuzz/tests/replay.rs | 30 +- 129 files changed, 377 insertions(+), 1396 deletions(-) delete mode 100644 fuzz/corpus/differential/compat-1 delete mode 100644 fuzz/corpus/differential/compat-2 delete mode 100644 fuzz/corpus/differential/compat-3 delete mode 100644 fuzz/corpus/differential/compat-4 delete mode 100644 fuzz/corpus/differential/corruption-present delete mode 100644 fuzz/corpus/differential/corruption-present-hmac-off delete mode 100644 fuzz/corpus/differential/corruption-present-hmac-on delete mode 100644 fuzz/corpus/differential/hmac-algorithm-sha1 delete mode 100644 fuzz/corpus/differential/hmac-algorithm-sha256 delete mode 100644 fuzz/corpus/differential/hmac-algorithm-sha512 delete mode 100644 fuzz/corpus/differential/hmac-default delete mode 100644 fuzz/corpus/differential/hmac-off delete mode 100644 fuzz/corpus/differential/hmac-on delete mode 100644 fuzz/corpus/differential/kdf-default delete mode 100644 fuzz/corpus/differential/kdf-sha1 delete mode 100644 fuzz/corpus/differential/kdf-sha256 delete mode 100644 fuzz/corpus/differential/kdf-sha512 delete mode 100644 fuzz/corpus/differential/key-passphrase delete mode 100644 fuzz/corpus/differential/key-raw delete mode 100644 fuzz/corpus/differential/key-raw-with-salt-and-header delete mode 100644 fuzz/corpus/differential/key-raw-with-salt-no-header delete mode 100644 fuzz/corpus/differential/many-ops delete mode 100644 fuzz/corpus/differential/page-size-512 delete mode 100644 fuzz/corpus/differential/page-size-65536 delete mode 100644 fuzz/corpus/differential/page-size-default delete mode 100644 fuzz/corpus/differential/writer-sqlcipher delete mode 100644 fuzz/corpus/differential/writer-sqlite3mc delete mode 100644 fuzz/corpus/findings/backup-aes128-legacy-page-size-below-legacy-page-size delete mode 100644 fuzz/corpus/findings/backup-aes128-legacy-small-page-short-read delete mode 100644 fuzz/corpus/findings/backup-guard-bypass-aes128-aegis delete mode 100644 fuzz/corpus/findings/backup-guard-bypass-cross-cipher delete mode 100644 fuzz/corpus/findings/backup-rc4-small-page-short-read delete mode 100644 fuzz/corpus/findings/shared-cache-many-siblings delete mode 100644 fuzz/corpus/findings/shared-cache-one-sibling-wrong-key delete mode 100644 fuzz/corpus/findings/shared-cache-sibling-has-ops delete mode 100644 fuzz/corpus/findings/shared-cache-wrong-key-sibling-then-vacuum delete mode 100644 fuzz/corpus/findings/vacuum-65536-page-size-corrupt delete mode 100644 fuzz/corpus/findings/wal-aes256-legacy-vacuum delete mode 100644 fuzz/corpus/native/cipher-rc4 create mode 100644 fuzz/corpus/native/cipher-sqlcipher delete mode 100644 fuzz/corpus/native/legacy-set delete mode 100644 fuzz/corpus/native/page-size-set create mode 100644 fuzz/corpus/native/sqlcipher-hmac-off create mode 100644 fuzz/corpus/native/sqlcipher-hmac-sha1 create mode 100644 fuzz/corpus/native/sqlcipher-sha1-damage delete mode 100644 fuzz/corpus/rekey/cipher-rc4 create mode 100644 fuzz/corpus/rekey/cipher-sqlcipher delete mode 100644 fuzz/corpus/rekey/legacy-set delete mode 100644 fuzz/corpus/wal/cipher-rc4 create mode 100644 fuzz/corpus/wal/cipher-sqlcipher delete mode 100644 fuzz/examples/gen_seeds.rs delete mode 100755 fuzz/fuzz_targets/differential.rs delete mode 100644 fuzz/sqlcipher-entropy.c delete mode 100644 fuzz/sqlcipher-ltc.h delete mode 100644 fuzz/sqlcipher-wrapper.c delete mode 100644 fuzz/src/entropy.rs diff --git a/README.md b/README.md index 7b01b77..8e53be7 100644 --- a/README.md +++ b/README.md @@ -22,4 +22,4 @@ SQLite3MC is MIT licensed. The amalgamation also carries public-domain code (SQL A daily workflow in the [repository](https://github.com/LucaCappelletti94/sqlite3mc-src) opens a pull request for each new SQLite3MC release, taking the archive's checksum only from the release's Sigstore-signed `SHA256SUMS`. CI re-runs `upgrade.sh`, which checks that signature again before trusting the pinned checksum, to prove the vendored bytes match the pinned release. It also compiles the packaged sources natively and through `sqlite-wasm-rs`, and checks that each build opens the other's files in every cipher, under Node and in headless Chrome and Firefox, on OPFS too. -CI also runs SQLite3MC's own tests, a rekey of every cipher and SQLite's TCL suite through the shipped amalgamation, once plainly and once under the address and undefined-behaviour sanitizers, with every expected failure named and explained. Seven fuzz targets in `fuzz/` run on every pull request and daily through `ClusterFuzzLite`: a differential fuzzer comparing the amalgamation's `sqlcipher` scheme against [SQLCipher](https://www.zetetic.net/sqlcipher/) itself, a self-consistency check across the six native cipher schemes, and dedicated targets for rekeying, `journal_mode=WAL`, `ATTACH DATABASE`, the `sqlite3_backup_*` API, and shared-cache mode. +CI also runs SQLite3MC's own tests, a rekey of every cipher and SQLite's TCL suite through the shipped amalgamation, once plainly and once under the address and undefined-behaviour sanitizers, with every expected failure named and explained. Six fuzz targets in `fuzz/` run on every pull request and daily through `ClusterFuzzLite`: a self-consistency check across the six native cipher schemes, and dedicated targets for rekeying, `journal_mode=WAL`, `ATTACH DATABASE`, the `sqlite3_backup_*` API, and shared-cache mode. diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 79d7a71..8a6bca6 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -113,12 +113,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" -[[package]] -name = "sqlcipher-src" -version = "419.0.6+sqlcipher-4.19.0-sqlite-3.53.4-libtomcrypt-1.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab732d48ebf2a1449e94d071b26544f99845834c75c3c210e927ace097b49aa4" - [[package]] name = "sqlite3mc-src" version = "206.1.0+sqlite3mc-2.6.1-sqlite-3.54.0" @@ -130,7 +124,6 @@ dependencies = [ "arbitrary", "cc", "libfuzzer-sys", - "sqlcipher-src", "sqlite3mc-src", ] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 833d894..6fdd5f7 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -3,7 +3,7 @@ name = "sqlite3mc-src-fuzz" version = "0.0.0" edition = "2021" publish = false -description = "Fuzzing SQLite3MC against SQLCipher differentially, its own native ciphers for self-consistency, its rekey support, its WAL journal mode, its ATTACH DATABASE support, its backup API, and its shared-cache mode" +description = "Fuzzing SQLite3MC's own cipher schemes for self-consistency, its rekey support, its WAL journal mode, its ATTACH DATABASE support, its backup API, and its shared-cache mode" [package.metadata] cargo-fuzz = true @@ -14,16 +14,8 @@ libfuzzer-sys = "0.4.13" [build-dependencies] cc = "1.5.1" -sqlcipher-src = "419" sqlite3mc-src = { path = ".." } -[[bin]] -name = "differential" -path = "fuzz_targets/differential.rs" -test = false -doc = false -bench = false - [[bin]] name = "native" path = "fuzz_targets/native.rs" diff --git a/fuzz/build.rs b/fuzz/build.rs index e8385d7..2280a82 100644 --- a/fuzz/build.rs +++ b/fuzz/build.rs @@ -1,126 +1,41 @@ -//! Compiles SQLite3MC and SQLCipher into one binary, prefixing each object's globals apart. +//! Compiles the vendored amalgamation as a plain static library. -use std::{ - env, - fmt::Write as _, - fs, - path::{Path, PathBuf}, - process::Command, -}; - -struct Side<'a> { - prefix: &'a str, - source: PathBuf, - includes: &'a [&'a Path], - defines: &'a [(&'a str, Option<&'a str>)], -} +use std::{env, fs, path::PathBuf, process::Command}; fn main() { assert_eq!( env::var("CARGO_CFG_TARGET_OS").as_deref(), Ok("linux"), - "the symbol renaming needs ELF objects and GNU-compatible nm and objcopy, so the fuzz crate builds on Linux only" + "the fuzz crate builds on Linux only" ); let out = PathBuf::from(env::var_os("OUT_DIR").expect("cargo sets OUT_DIR")); let mc_dir = sqlite3mc_src::source_dir(); - let sc_dir = sqlcipher_src::source_dir(); - let common = [ + let mut cc = cc::Build::new(); + cc.file(mc_dir.join(sqlite3mc_src::SOURCE_FILE)) + .warnings(false); + cc.include(mc_dir); + for (name, value) in [ + ("SQLITE_CORE", None), ("SQLITE_TEMP_STORE", Some("2")), ("SQLITE_ENABLE_DBPAGE_VTAB", None), ("SQLITE_DEFAULT_MEMSTATUS", Some("0")), - ]; - let mc_defines = [common.as_slice(), &[("SQLITE_CORE", None)]].concat(); - build( - &Side { - prefix: "mc", - source: mc_dir.join(sqlite3mc_src::SOURCE_FILE), - includes: &[mc_dir], - defines: &mc_defines, - }, - &out, - ); - let crate_dir = Path::new(env!("CARGO_MANIFEST_DIR")); - build( - &Side { - prefix: "sc", - source: sqlcipher_unit(crate_dir, sc_dir, &out), - includes: &[ - sc_dir, - &sc_dir.join(sqlcipher_src::LIBTOMCRYPT_INCLUDE_DIR), - crate_dir, - ], - defines: &common, - }, - &out, - ); - println!("cargo:rustc-link-search=native={}", out.display()); - for lib in ["m", "pthread", "dl"] { - println!("cargo:rustc-link-lib={lib}"); - } - println!("cargo:rerun-if-changed=build.rs"); - for file in [ - "sqlcipher-wrapper.c", - "sqlcipher-ltc.h", - "sqlcipher-entropy.c", ] { - println!("cargo:rerun-if-changed={file}"); - } - println!("cargo:rerun-if-env-changed=NM"); - println!("cargo:rerun-if-env-changed=OBJCOPY"); -} - -fn build(side: &Side<'_>, out: &Path) { - let mut cc = cc::Build::new(); - cc.file(&side.source).warnings(false); - for include in side.includes { - println!("cargo:rerun-if-changed={}", include.display()); - cc.include(include); - } - for (name, value) in side.defines { - cc.define(name, *value); + cc.define(name, value); } instrument(&mut cc); let objects = cc.compile_intermediates(); let [object] = objects.as_slice() else { - panic!( - "{} compiled to {} objects", - side.source.display(), - objects.len() - ); + panic!("the amalgamation compiled to {} objects", objects.len()); }; - - let map = out.join(format!("{}.redefine", side.prefix)); - fs::write(&map, redefinitions(object, side.prefix)).expect("OUT_DIR is writable"); - let renamed = out.join(format!("{}.o", side.prefix)); - run(Command::new(tool("OBJCOPY", "objcopy")) - .arg(format!("--redefine-syms={}", map.display())) - .arg(object) - .arg(&renamed)); - - let archive = out.join(format!("lib{}.a", side.prefix)); + let archive = out.join("libmc.a"); let _ = fs::remove_file(&archive); - run(cc.get_archiver().arg("crs").arg(&archive).arg(&renamed)); - println!("cargo:rustc-link-lib=static={}", side.prefix); -} - -/// Writes the one translation unit SQLCipher builds from, the wrapper's configuration and SQLCipher, then every -/// libtomcrypt source in order, then the entropy hook, all sharing one configuration as upstream's single-file -/// libtomcrypt does. -fn sqlcipher_unit(crate_dir: &Path, sc_dir: &Path, out: &Path) -> PathBuf { - let sources = std::iter::once(crate_dir.join("sqlcipher-wrapper.c")) - .chain( - sqlcipher_src::LIBTOMCRYPT_SOURCES - .iter() - .map(|source| sc_dir.join(source)), - ) - .chain(std::iter::once(crate_dir.join("sqlcipher-entropy.c"))); - let unit = sources.fold(String::new(), |mut unit, source| { - let _ = writeln!(unit, "#include \"{}\"", source.display()); - unit - }); - let path = out.join("sqlcipher-unit.c"); - fs::write(&path, unit).expect("OUT_DIR is writable"); - path + run(cc.get_archiver().arg("crs").arg(&archive).arg(object)); + println!("cargo:rustc-link-search=native={}", out.display()); + println!("cargo:rustc-link-lib=static=mc"); + for lib in ["m", "pthread", "dl"] { + println!("cargo:rustc-link-lib={lib}"); + } + println!("cargo:rerun-if-changed=build.rs"); } /// Gives the C side the coverage and sanitizer instrumentation `cargo fuzz` gives the Rust side. @@ -139,25 +54,7 @@ fn instrument(cc: &mut cc::Build) { } } -/// One `old new` line per global symbol the object defines. -fn redefinitions(object: &Path, prefix: &str) -> String { - let listing = run(Command::new(tool("NM", "nm")) - .args(["--defined-only", "--extern-only", "--format=posix"]) - .arg(object)); - listing - .lines() - .filter_map(|line| line.split_whitespace().next()) - .fold(String::new(), |mut map, name| { - let _ = writeln!(map, "{name} {prefix}_{name}"); - map - }) -} - -fn tool(var: &str, default: &str) -> String { - env::var(var).unwrap_or_else(|_| default.to_owned()) -} - -fn run(command: &mut Command) -> String { +fn run(command: &mut Command) { let output = command .output() .unwrap_or_else(|e| panic!("cannot run {command:?}: {e}")); @@ -166,5 +63,4 @@ fn run(command: &mut Command) -> String { "{command:?} failed: {}", String::from_utf8_lossy(&output.stderr) ); - String::from_utf8(output.stdout).expect("tool output is UTF-8") } diff --git a/fuzz/corpus/attach/cross-copy b/fuzz/corpus/attach/cross-copy index 50b82ef146aa6488bd9f3b605b54c1c238bf69b0..1a1f454e1c7689f0a323fbf48a3f3f87d008891f 100644 GIT binary patch literal 434 zcmV;j0Zsms?q=;A4QK*YNK9KWJDZ;zaZ6>u(zeF^MXhzZXXmVW7U1?3Ieo67#;Q_2 zw$ZwI->qGz)Itw~E_As$;2za;q{hPH2tejy+hJ3n!kec6pfGcwZ|_k+!Pm)JXHWe! zzE{YP-0;OYeUNKkg`U#3ERq=#u6^yT%`B7Mk`snPno0a3%O(o-^&T-sOb>v-XKc%a z+=xJdg9SE20pc4Nb|qBc_(V#XnG8~Zs?yum#+mlRSsS4y>zM!7$g^mx8L{_>q*of1 zCo!3BQfy+ZV7G^oYvW|M)i?p}pXQzcH;5{Ynn{nX7W**pPq{dA0!X^fKtR-DaV z$AV7eqwMUdMUfJ4Jz-%w8N4=NRT&S*z+5LaiqQhq$iuQ)yUm{0u}gd5{}8nvlT4BREkXiD^!93_fK!i#0h$@xbpQYW literal 138 zcmV;50CoQyPB$r^K1^D-FUFo>V$>O=SYt)w0x1vEyCN1k(A`q(|7rUdI)Wd^vsaWg z;vYI8AMfpIjRHA{)>_JIYxiZ`&HAc11mKg^0T?)|sK*a!LG~ZV-=i-2pswJQX@v?! sM}^P*azc7}s(S3=s!FRFf$XT7kz4;KEIEt@s0a&LPD13B2_dOlPpCmb)c^nh diff --git a/fuzz/corpus/attach/detach-reattach b/fuzz/corpus/attach/detach-reattach index d0292024e4b361fdc39e6dd62f62a3fa8602fe30..27b6ebf1f08054630893efa5752cd59826849da6 100644 GIT binary patch literal 286 zcmV+(0pb4HB$^|kYaZy1b)(Riwu8gQ$6#bX4}Kz<8>V~Sl-;Cq(TjIy@N%r%-JVMW zO=u{2{;C1RcoHUYykeZ_%Y&#f|J_SaZ_M0XkE=L}?oVR#Cau0AN%v*lSuT49DXrbk zqGZ~aiIsQu3a1~F~Qt{n|mt3U8t7pZH%gxl^f;T0nOgjW@lH0k>PeGPhP zVHnAB37VfGMrpXKjynwBae6A-Q;p6qXqLBqwVIHn=X`zM*FWwnZ_sv+k7h_YWe^+u zPrA749rh+jmwNmZnc*Dt8EE kAmbOYZ?1*Y^w1Yy%tf?%xWJteM5LILQI?EnA( literal 434 zcmV;j0Zsl{LJU5jE7lxSKuxQ7e5nazZ$311ab2+|xC7Fq0;aBUbDU5*`_mt{+y^oj zB_hN!D&6Lr5CPP_y1|3-@UwU*HNQZ6GUl{0eO>48#3Vs*(J2SyA#o~*QlYmCLTPOT zwUdIRYfhLmmI}pPw zx}nApv6topf9hW#2+qP>R1D7PlcPC1q#`Ï'l$(«¬Cú[ƒtòz}þ°1¾yÕ4pªÌ{Ò»÷úÏÕü0·¸ºïoUUW–ÕŠqoߦ -”Ks [œX” ´½.É`ךb‚ÚãæD¢®×w¸mh±¸Šn0®q(TZaôLX£ÐEØ¿ÞB* Í~,ÊÕÉ}�_AZÙÿ±£Ç©ùz‚7Èq®�u2=¼³u½µ#-«ô>[,F]ZÓÓXéöÞ‰Qn;]VÃb�ú˜Û?:ù½K4qº•†hΪô “òmÖö'>Å;o’CÀÂ=)ûۅûj4Uú®,L¹œx"diÅ9#»²­#VÌJ|wxëÅ4ÓˆªÇb-~/]´9È/ÉððÈþ|ÿÊ_jQΰ=¶üÜ2Ëÿ†ƒn©*¨s -ˆ \ No newline at end of file +üÃi“s=kmŠ"õ?6òÍǗϳ¨�H†E–Íi.úéd�u4¼3§8õµJ X7­'�(ŠÙqRpØ0\¨Ê¾Ó+1:O@aÄJPÑpo�:G¿yddßiUV®A½'â—+Ƨ»Ošéá3 ÀÞ¤[ 듥õ �ËŠAîÓ+ÅDMæW©éOãq„fîõ­,lOòeLÒÞ1!ÔŸ4ëD‰=’¬Ç3Þ×HŽjži}"SDâ¥áÀ•øÒà•Bai�ˆBfþKeÐöÁ½¯Æ�ù…Œã››«žONÛï›ãnø²Ù5êÓZ5?˜»äºT…T \ No newline at end of file diff --git a/fuzz/corpus/attach/one-attached-correct-key b/fuzz/corpus/attach/one-attached-correct-key index d5bfd1c7dc95665203af3a9f0a35a0479040798c..7c1aa17bcf4666c63854298007aa0979aba2c818 100644 GIT binary patch literal 323 zcmV-J0lfYb4lt~pUNy6Jg+8B#@65N5eGuER_@6_$KOCf08c!`f#MX8kWk6^O(?EJE zlt1RAv9gbgNH9U&cM)tFQq7+V8tw)^-tu#%F!7myhVg$UYL#mil6SJb_X z8TI@+OY=rM{ct4Awh0>3Vp@btn~Be!&uA*hpOpdu&|8LlLF>PB_f|IBMCsamyEq~zn(CqYD1(oV974`eI V(SSjfP|yW4G9F*fw~9Ad`14|2rQ84j literal 175 zcmV;g08sz73x_4Pb~fhkog0Y}YXE6&Fk7J@puI@eISW3y@6f*BtRs+%y7dj@=PfHP zjpll|kO6rhoJ_X#wlZRN>Jm_Sl^5OyA`<<#OX+VC?$gGcH_mg;7g0`%AffoL5>57# zy>Uw0$}Z`ba(T|l%Dq+pfT_Z-VubiK5ToXASs1u=1Crt~v0cC=^hJ+kCE-u-gG(7b d8vV%)MAf8Fzw#WG2s>Ui85#_r0)|f4CzE8qIT})_T0#-T+Y{p+8Z$DQH_{nyop5GK-CYO1Bogx>-oaXgNYCXoRuOcPsapWUf`1_J0%>c6pzfDz*LDwrCu9nH zXPDi2fg0WYD&lU;-b2+xRgW-d&PiDGLZRLI*A`uo{t5qpv}b24JbDsGbH6)abhGsJ U!%+jXl!NP`5X({KJ3zyHJ~jIV}--2!$OonDto{j}1$;zW5#*`s^KFX?nqsTM0JHZ4mDj z!v`T>P6I2==@PzTq3a3lkx7u)3`VEZq7z$+0K?E8aMJ8)yp!8jY@+0rXcCH*_pOo% zZHQG&itDL?r%C<`L4#CBPVR<3(}iN1)G5i~DuLO?^llMW>Dz|xn9uQ>-u2kv6%8n9 OTxr>- diff --git a/fuzz/corpus/attach/rows-on-both-sides b/fuzz/corpus/attach/rows-on-both-sides index 99f0ab99f9fbccd989e5a701c69cfd621abcb5cd..506066d8c338aa9cc48440cc28ef9abdd96a24ab 100644 GIT binary patch literal 101 zcmV-r0Gj`u$C|4b&fY|A^U`yHi2t#Tp_lbyr+F}d}p;BJXw-B*Z`yt%r*eitk>U})1%Z1 H(yPV}vcWX- literal 101 zcmV-r0Gj{b1>9?m(d+qRqIoIM3m|YoLw0xqEOro!x&V8}_|sPGM=21z)zSYqrOO-N zz{8RWy`R0?DM)>)FHCKk{F=xroZ+~=tQHGHr^l2f`1>SKFmPi4+4nyU0RdrAqs*Z2 Hh#~Q)IUF+- diff --git a/fuzz/corpus/attach/two-attached b/fuzz/corpus/attach/two-attached index db9a1091706b72d55c2d16d23faccf0d9733f653..032ba821ae455c75ec010e4ef8d0ee02383d44ce 100644 GIT binary patch literal 138 zcmV;50CoR12V`#UJe_$y9#aT*4+J4grWcC8p3C-z&S@C=5(1RHGJj$0<)WIab<^CT@bO70TR_3E>1dsy%LAyckz-Ms z{4Gee7v-Ev7pZx_Mqa@h*%JxUJUvSLNn@0lxfXRf2cLm(fpj|3IF+iX(5#P4l)#{A zW#`^^-afRl>`5}wulvCBoHcbh;>QTFU3yR!mTY+-we)bR;K>;S*zzJ(Q$=~;ASPkO z@p@g%z;373M_vZ-vTR(UmE!Y@{(3z*ultmAz(-{FD2HSW^ndX8Aj82}?Z6?MjO=8V zyTU_Yb{A2O8Ts++;EgyAf3T0G=~Q|B{&L#>atrSTd7yr5tDCMoO1Qcj+ z#+SMlr@1u*8UCYjT893Z;1mZ%LXHP1H)M)$Q5=gNiUvmRx_dYbmxpkK*#%HPz)=MJ zPzcW>9FKoolg4Y4NDlZAL=cy2l?+7YP5T)VxdEovl4iBQ7$XJXBJ$`Iom$NhVwoj8 d0GFo%V;ucCJn6}JRRkn~)xao!v1)i2s*KVZOtJs~ diff --git a/fuzz/corpus/backup/aes256-page-size-mismatch b/fuzz/corpus/backup/aes256-page-size-mismatch index da065d6d27ec32f59f74a77df9c361c7b9079254..6cb1f7e327a739eba95d5fdb9cdb76dab57b1f1a 100644 GIT binary patch literal 6120 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 literal 656 zcmV;B0&o4s)x<^+iSA#05uG6@(wEd$MGUBv9qX|pL7njux*xnX#2~Q-G{@Y||94}| z`A#BDnN+e*sk=1NoC!oQ01Qyrz%;`e91)bwC>dUDCfV!D6Ez8Bh|Y2wR9tsBNjV_y zr~_ft%E&u-n>7>VddCObp}aSrq$m5K@femca)Pgi+k}1tc=?2g2zw~KYq4vv#j8aN zt<*u{O5W%S$<~ddkSALM601rUpIvn7g%90fvQTUE0RBriVN`hRRjhHr{ZiicPrRk( zAE1Fhg-8H1*JT3l%OLPBx@IKvwj@ANt&b)Ut}ucaju~SsyL_8z4PZTH^p9m?-BNY$ zYLbV9%-rqaY$rN;pDK+GEN_aj=r%+6T{T9>*fWpr4dsf}Q2HJFYhP=2^=;3iT^leY$r1mTF zzXrFw!=VMfZ>EBC2FuoDNV=&$0V^k&psu%7!|iNd`E;7HwAmv}HTR06$;DrA4l10a zxszlNp1`-w-QMxDak_2QWu=`%_5@vFh7A&;GsI9|u#$&)4IAn1rZmuMt>sPJ9W$on zPozL~{30ITW{*y%7np&UHrljT(eZ#3xV$xsX*%kA_yya(NYW|TT~v-ta~&XlqU=f2`bxO~ diff --git a/fuzz/corpus/backup/destination-has-content b/fuzz/corpus/backup/destination-has-content index 94ee58c9121c9ea93ac25b57ab1f78d98f198271..7222851a1f20e776f9f6c7d8833883837ef0a4c0 100644 GIT binary patch literal 582 zcmV-M0=fN~ZNAD(<>ED~cF4xX9rP~iZ&s5SmgEe|6vmS8WV!LVsOSo?#z_Yf$pBdikyUnBv9k__nCZ1M9xlWW8=#y-pO}p zgH2D5N9=M_ZDc}>W!jbW5QRvi{!@4d6B%SWBNVY!3;)9y2#>?7BM&`|vxB$CwdOWY zB2K>&BwIMWuRYU)(B=i3l^lQ*ar3S#`bC`GFQ~PI3sD?#+D!bIERAakp8`DQ!4x}p zLUgY$r#5OW<6Sj$&mj4X>kG6(e3DO49SDPY@_#9s$17ARlB3-%8@Vbc-Kk33mp9AL z2}#{uw`!yo#id?Th!D?}#fxWXeZr1NY>tH(MppJY%+by*D=CqLH?hQrGNuD?z5%gp z`p4)Z$o{x0X&@JPPO5KPWghWC{<;&3YHGxx`U{?J)!m|jKit?M4qG13T0xnST1luv z>aiIiKyDZgy8Kko1kn{IeU21557G6H z0O8s{&j8KD_mC{`~Uy| literal 397 zcmV;80doEg6EhG{-{;7*)#0|`}7jA6yYLKdKxqK_Mh9xV3VR}V}i+% ze28TE+mRUbRjtOX?mehv{31D$n!Rm(+)9lrs8$fqg zH!l?QSt2vn?`KX{$fCRs{Td@Gr5sYBGlO{9%5E-G^ILBlmQwLub-=I$;(%Mfe1Gxe z2wlr=YiTu(KifThyu_t@xdbGv(SiUzHVB*{_zU>4A4Wntc`ow{)MTv0vh@X}9x!6H zM8_Z3S+Is#VWSo0@dP-*1(V)KFvYP}v|phhVXCa9+c0;_ame+F9Of4oX+8dH*!ufY rIE0!>1j)gPh}sR=vcS)2ydQ*;DWKC%YCm7_0gUkZ5-=Fae_0u6Gx^1d diff --git a/fuzz/corpus/backup/different-ciphers b/fuzz/corpus/backup/different-ciphers index ee55904489bb9388a3b2732b6b7e6a8a5528d89b..3e88749f588a04fba5c2bca33985ae1d3b16ea5d 100644 GIT binary patch literal 175 zcmV;g08sxHTtO!l)uNLI d@}F?y2Rze579AM&ThfU0H^PJc2g>|06?ve2=W0WVTd&1zIOUx_4|*zla7#5115ha(m;k* zkQZ{Dh9Dzd-vHM3Y)}lgPvXUU$gB%@IdXx!l!NUt#i5r}s;LT)dtUAW|5M)CF)ZYu H{-a5^&W12d diff --git a/fuzz/corpus/backup/empty-source b/fuzz/corpus/backup/empty-source index a4cf7a778c8c073621c250831dcf81cbdff59b24..ea88887caa3f7b28a004b3cec16b27026c455048 100644 GIT binary patch literal 101 zcmV-r0Gj_YZZ#l;c^<5G#n_JW#hB|5)fOc3k$hfgl2wY5`}Y*<2}ys(elmAv#&F-D zE;T4Dvi}DDk&2+&C#|cIkHa*sc_UlEqO7!Nx@6s12Z)+G+f45ogmMUwcnF)?h8o`Frx9obB1ai@7~ww&%gxPFGFOu zPsouBz*EO(OSe%xCAvFl(d9CaCt3^I3od-WS9{C0%S;|jw!;)}uZ1A+f9`EcpSqGc zo``%xpN$hh++A)ns&h`+S%Ch?8Jdoejp#GP0FdB#9l~IlbH$tyYFLXRyFsq#F78p% zbPCO=%gG}s=l5+bZsemD$U6giVF>dNQ}0Cb9*Q&#?&Zsj^D|tECWYB9j!wd#yJR?+ kDyED^0=;?-8*}|?1A(R~c}dU1y4&1OBp<`+NUGuNM5=v`Z2$lO diff --git a/fuzz/corpus/backup/no-page-size-set b/fuzz/corpus/backup/no-page-size-set index 373959516ecb78c60a7b9fc200645a67190fc1d1..11d3b7841f9a8c351c22bd50ac965e3daf266782 100644 GIT binary patch literal 545 zcmV++0^a@R8k6}i9xDy~@WX&Ckonio(l0|tkVl*ZIjdwy5qhy(eaTd@{ABwo_-5cw zH@p5jfi2N^3Wy>5o9_!W2o3X;JcF_!9%Cl;s3Ia~EYKIWcw!1h*23Hs48WTl&iKSH zT`o#=xD^6@%h7*#zkyCTR=(hW>CvTh?jx${DeOr z1RjcU=R&ow%~f-sEj2rf^6b=FcjXedKP9ei!5>;-IU%UDEML3UzOmu`^6Ic+KxAZg1 z2z;Ad^6CqyS@2ed4ChuBNHuxEyB7=(`wqz(Nzfbc2|t=5^oh%~6W1i21Rx=)V{w4 zhGyS1Wwp??-+5}EM0LtH_!-O;tWs99K7BSk{tQgX1omKX{r5C9tOP~i8tgc$9jK{* jKaEPS@HUSB*AEiBBe1F_bn6-ZrR)Eh0EQToYIx0*?_?8V literal 138 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 MU6V8J(6=n;YWo8#Jpcdz diff --git a/fuzz/corpus/differential/compat-1 b/fuzz/corpus/differential/compat-1 deleted file mode 100644 index 7603f97..0000000 --- a/fuzz/corpus/differential/compat-1 +++ /dev/null @@ -1,2 +0,0 @@ -5O?즔„Ë´4êÔ2!»ˆrÛ>y -høó°iî�ð„N†‰SEЉ](«1¹º”ŠûoHXƒ\vŽçVs \ No newline at end of file diff --git a/fuzz/corpus/differential/compat-2 b/fuzz/corpus/differential/compat-2 deleted file mode 100644 index 6a04c10d8285f79adb877718001706a6e14f5164..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 508 zcmVZ z{}GtU5f5><+XJ+6koQiEzYLtU%^_h7G)llbPukYr+3IS;E*$C;%7U;heLPl-;wdO#N|gh@O$J-AtYOx_UC7?Wi0U zWJaUfGW}*Cka{UlEi?5p#!-p~Z*(S&GC6L^8WpEnMikTR+z5k*ry^6CW~h4i6hQjO z2^a$2Gh7UyBF*0F%aRe)Sxd*kceR3e0(QK-`Uqg(YynnOhdAq4pp zLcCFnvww{*yn&KxX;&A@Lj;}Yjd&Gt4oUVKK.ýÐÚS¼ökì?¨øˆü�±îº4¢Ò^B‰ä¤Üy]wÝptÜÙÈÂ?Ò�”îoÊŸÈmϪS(ã êõ ¬ \ No newline at end of file diff --git a/fuzz/corpus/differential/corruption-present b/fuzz/corpus/differential/corruption-present deleted file mode 100644 index fbea514..0000000 --- a/fuzz/corpus/differential/corruption-present +++ /dev/null @@ -1 +0,0 @@ -˜‹u�ñÛää´Ä×KÐ*sëÆ9GãÈ7÷µ/¶'{Ã�h�Àƒ Û"ëá}ëá£2%FÒtjÚ øb½¦$‰¦·Ïí?]IÙ�ÉOYEEÀ84ž=ubµD0x»@à lšãc/ƒ¡? CÍq¸�Ìà â>jhk¼r®ê=½¡¬!D,Ãõ×lræPAMŒXñš¼÷B±ÍôÉSýq½ · S[` \ No newline at end of file diff --git a/fuzz/corpus/differential/corruption-present-hmac-off b/fuzz/corpus/differential/corruption-present-hmac-off deleted file mode 100644 index e9843639a7b74eabc4605b3b4e1e26154bf27e4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 619 zcmV-x0+ju_>f;fSY^J}P5U!b(LgoI&JXCWidU5XB2<*y>e3S@0Ta9FwKKA!2+fGQv z`|7rh>l=;9Pod!772zESKMsvUvQQ|;_II2*ZaEwTPRKkWUro|1+BwfkTC>K07_GeI zGqP9l823(4pHzK#FSR;L9b>~s9drMfqhQfRb0RB*Cg>sl47d80qJcrGVbX;FsRpWd zUqrqaV?OR z;D+}^=DL0Uour9`g7Wb}%3@wlOYNMnZp1%Kfl`h~2UhN>zr03fpSmH~o!K@8zg_l+ ze!3BWXpIv>CI389$lm-vM0q7! zNMRB`3~1_*3Z3v!@HOpIN4V>Y7Eekm zb1Tl~&^V?}IfgY+3j!uWY1CW11IVq9xZdOQnM!NEcWlFqx_(nSBd-_{T1c$LDPHp$aS}a1_C3 F*%b}bE{FgC diff --git a/fuzz/corpus/differential/corruption-present-hmac-on b/fuzz/corpus/differential/corruption-present-hmac-on deleted file mode 100644 index db20eb5cc8ad54c366cab6eac955cbbecb8f436d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmV;g08sx!`Q(!0>YEF!GdsV8!P@*?E!7-vMt(3acHoNCtuF%BrdJhcEC5($&o$P; zw2m%XY(m}Q1m3jw|I4f-YHwN172T8~^$hLho!pDmOvLv;dF=zyxPxo0%>Lb)*CN0` zc#H3n%rGJ%nzGdPGx|Op-V8V7+#~~6{|1HJ9-`mpCDcK$|oftCl|7Sl_BjOHG`E!WQgE&Qk76^JB8aJ&wh!ZQ`St9+ej<^tgHV zHd27&(>=(eH+)21S79W2V@ZnEb-ee4e>y8DrD!9?k?mEIp-a|8o-DJjP_w8dE{E$K%3pgZ}z~DQB%P{B!)0?s+a5fceKHb zwmyYtu=hQZDR`JZ>t3e|&$-6wFDSkY-qdeI! z{2@=^Q*%S&3uh$3pm&bpEPCb`xM?=1bV>5PoI)&vw$mCA=W&XlaWAp-WApQb50$UQs?S9<(D;6wG5$Pbqch#Zd zZ$Sia5c05j=cU3WD+4+cX+5jNLPvbSCYw$++yPX7-z;o94WAJ2Q(mGd*-(G!>Cv6P zqE+3s!FGkkbEPp;Rfj2Lo1ie6BFx$%L~%Osc_ObOD0}8vFV@GlEE3$=CNBqepv z-Zf~Q9QSGL@I=t_&@e-BVy~kJ{OdPWIvf@i*SbnjB93{2#BWAXC!t1k2vi~TC4s;| zy$JVj$C_hHEETUB)xGvMybP>5TZwb;-;2zM7yLJ9FdzZW>~d6Zwep!mzMv(Z_c~xA zj%soFm){CB_QO5~0{w!in+5OimlfS0bfqld|JCuqe?S)9fA95Tj|Fxy5AEYPFwJrB z8#P@cJWDs1TdZn7BhxYRg(nk%+a{i|j7`~Sv!KX?e>QO~rZcD)RZZtj=4|aE(bo_x zpKvO-;G}a5|5mU)zlMIcVPCA=PICoAj8vb1o_=^n+CN1H^W31i!Q{V1+nIvZjF@=P zaxTc3(kIpF0M(1Dw?C`$*4czl)uxNK;)o?~C#@~?i zG-|H0C`0v)DLGUCI9Kv}#H(C7*FS+1JHG)YzKT2?H(Y7Fi^>*p%GI9oYD-pSuxw#V zpewl=k_n2~5#yV{W?R`@4~!T8o*V8Uuh2Dc(7nSAy>15PXJBVp)CYZICkyGy?+I@= OeLGNIh~TZc!5Nfx0cer{ diff --git a/fuzz/corpus/differential/hmac-algorithm-sha512 b/fuzz/corpus/differential/hmac-algorithm-sha512 deleted file mode 100644 index c3226ec35cf7be4e418cf3d253b3630525358852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 582 zcmV-M0=fO>6C5!l{cpTW)B1?_1wTdXS$=GYx@pZ5Z5nv-riTvLJ#|_*6Pne>xWpdy zD+td2P-4|{Q`4B#acb&Z0=A2}D*Lyh+ickT8@&PqkGiFlSGcMr{GC4&tw|kJUsT0d ze4uUzLe-3f4ZA37+ZFSKxtTpuuM3AfG5vzWQ~3OTPLkcx#i}#1SFHM&pZ+6tI}GQh zV`R;>y0GKH3uhGtJAW_c07}BIq!q^<{rhb=)y1 z2Wr_#CBc+L^m1*>xtcQu&&!wpye0Lj5wL`Ou&U7pKrAiGloSUUc)d9(X{~vyj(JH1 zcJK&)pKeekg60!5-LlLa6tj$LGxZEBegR2*QwY?|E#*wV<}fCT`+Zh5ts@V0_ibf| zK0h`+T0W!N99Z-AOqL2E#|?YCxmM--7V?}5MXe;KOjZl%Wjr6g!f3?eT=MY~{Rl7j zgvonA>hb0ay*7pVz7$_KJYt&$F4xZMEK^o|?=A394q8ZRdVtW$9?2Y5J2>bhXr;zN UuXngACLxrUB**Lb+mOXS++~ruL+`XQe@Tlm593u- zz^KisxjdZKkOXs2jl0>>o~gs_I>mXsr>xLLpP_K83?Yxx^{7BE)+Fl?*n|BR2?v3O z06!&7BH43*2O>x0QfzIjRdOEIO$`+dj5A7D@CxT4m5x80#70>pobsAnIeK};d5TR$ z^dF=cWWX!9@iPXk$0RTt$0-xN&`hw6Bn>o44}rP323c8SXmXN!6J*!p=-a5 diff --git a/fuzz/corpus/differential/hmac-off b/fuzz/corpus/differential/hmac-off deleted file mode 100644 index 7d1ab84a6c74501b0ad945f69bf4870ea4e9b5f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 582 zcmV-M0=fNyt2m?s&S&z8pWMT#Qv}p;$Vg<*kdz7u@V8}rHFR+hlP{gwt)+wn81C@rdB+;roPfd3?BJ^$7~lPScaNCDDVNzRCbli;gfGck%yyuoo!xVPHU zf7jr06BSzA{iU=oq-E(9sHeV?&wEuJmO^6;NMjv?^7^!}`oz$F%1`3#&)yec({!rm z*rcu3(vhA%BSTuWGbVR|@=;OEe$gD>R_n&WA&~OHjeOSCwBU+Hts-*V&e9JQQ?9Oc z9(t@|bTF-GsHXS!sl!HU>uA{lCDAx4*{;x4z1Me6TS_X_Ji2wiq diff --git a/fuzz/corpus/differential/hmac-on b/fuzz/corpus/differential/hmac-on deleted file mode 100644 index 00c2c22852e1fffebacea90fb535769b02579b32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 767 zcmV{U+eOM(ZcWFy|+L%!|45ptTEUGHG(xGySgd0)fM8!M6$#|4x{Nb5WG zqpKOKodk%Av(ho0N^ixRoJutQO*B;Ji)ED^n1F{i{OXcZUirLs91vkAd2XeKK`){Q zdQo>)*H|~R&8lSKiDh_Uit0wsJP+1~xIx!_HmrcQdDHo=yw@Ug(9f7MRX_OZ_W_m$ z3GP8Sb*;&@V(9lh(@;rfRfxf;@fR9#XAh`buk5OyKVx~;e>1^IEVABIETbR1{j3r$ zyI0c}(RRw;XJ2glHeB%+6PNq#>|57{J$@r@k(ajLid|pFpxKDI?pc2-uGFGa%NAG1 za#F`lAIh7nV|*&!HpSdY8L_SbBgPzL@!kGeAg`cFhz8^rszxT@p{!#-&88u7e-TH_ z{V5=a#0!UNTpFeFaXmUg{ha*)C_gh7{b9h<>HTL~CGXxlX4U%j>lNEp(%JvKaD{mD z)}!jB-Luz4Uu}E+UE!0kcrA?SIsd*bO(?|`L#HPbiHdy995;DXy@o-vJ*i0*HRR2~ zD)aPd9|b^|D7(NhkNCFkEQUqpDx4Ys^{HIrWjKG@oH?mw1|EQ`s2 z$ACvg{a?fn>Nijzf9g8lTYYMsGd2y+kZSwbSGR}Y{tGU`@=(l(iYQG09NXx01KXlc zFLL#&n9+YnL?XGU4o@bKh~SWAda~ZT5O1GuMGAFN-1Zgvfb9Y+(L=n!z-gzg1s;6|zbyDhN@e-L6J@f7k#3 diff --git a/fuzz/corpus/differential/kdf-default b/fuzz/corpus/differential/kdf-default deleted file mode 100644 index ecb53e3..0000000 --- a/fuzz/corpus/differential/kdf-default +++ /dev/null @@ -1 +0,0 @@ -œìLùôÎê¬]…§(ÑŠG çóÂ×vf‰E‚øè3‹­ y0tfí§¤ÕBH>ø>7·²Fs»Ìk—wWu6£D\ÇÂS—½däµ d÷Ez£ñމG[–T\}§G \ No newline at end of file diff --git a/fuzz/corpus/differential/kdf-sha1 b/fuzz/corpus/differential/kdf-sha1 deleted file mode 100644 index b7e56a39c5585e9f1f51f14231d9b3eb8af6945d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 952 zcmV;p14sPiWS)qES0PifYV-)4jd_RzC4)KU?rn!Sx1h@E6lB-Sv!-mpry0i^-Eb$Bpvu z8MnqxJoe0Wl`)7)#EGHlI9!i~EsPk8TL`wYyGv=h$#Si#bnF}Desytt7R>Z2*NXBFR5N>>O_P--GuZ-h)ub(v8!{xXe9`S-HuD*!5X^%wvoew*L0R{w6Ys?ce|;@-*$MSJ7TR;|JgQ_Q@vkZuLUI4>ZQ~sDA%Z z`G$W7qs)Y`8Dvo^SWW(F1Xof5Z)sBT_!Yn+=R4sDlihH+d%n)qHl-q=1i&vd3&Cpr zLj`|kUYf~_PPNdyBAOp>1y3#ErTc{=9nmA~Ja`?_-RBJ1r%~gSp|^CDz)ci!_{YEf zSn0fiWac>EoaRWm6HL5Kz2=_Hn}B~hsMMWShpge2+dXJfiR%!~bVk6mcIw}gUSDXR zoqu?B^Yv+4E7bc%|9Pc4unGq0t6eeIt+$ymq_g4*MbDxqmx=p{?XFEj1D0!o2&;qG z!i*3e73=OXa~U0hT%X=Wc0~ix8nhn=Qj7{NB7L<3(0yK;ol(#5gFF8{$)<-5^|+n&a?n6eR`Qv z;AqcX*`X5imko5HrYo8oA0ic%ZsYSP%si>jlBmj%Sp{$B=K3yiK?D8jI||b~1$!pL z=IOe_)_{B68?&>qVmTZ_hf2FDy7nQa_o&++Gk?k$wh998D4bQrX|d;5?1wm<#Ev{o zCefcMHDq9{xShkm;-9<+p#+5)6cA1=dJ|jY>q~psa%PONzVIhS zJ2*k2?Y(OX9XCbi;rFTBN7rTZ&VVeBBl4Bo2MZXYenehpVIlie8= a0Pa*}2NDxUEgFjxa+C9}7U|^ïEÑxŸ~W -ߟgÙX49Ø—ÎRÜž—"¹ìdO§ÿa{–¤B: Zuî=H¼èNêïüþKäámi>—M³ô9ÿWPÒ®^—ZS¼�öÞ¢Ïä4xƒú²¼øfëy:é2 -¢7­2‹›Ûº{FìAg‡}�] \ No newline at end of file diff --git a/fuzz/corpus/differential/key-passphrase b/fuzz/corpus/differential/key-passphrase deleted file mode 100644 index 0013c8d63fa2e57045ef9e11e917ddd2d426c90f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360 zcmV-u0hj*sUZ>?gihQR{&bwk9Delr-0iY_?2nx;Ak1gNTj*wDKtUfY^VxBp;%mj+i zf9a4s(?%0JQ7hV-Oql)=$@zsx zPJQj*e@T`Z+7hWcU~VY^lxDrysX-_kM*7A(259#R+kV4G=#c{y9~duls+D2-w}K3U G6RlK+O|sem diff --git a/fuzz/corpus/differential/key-raw b/fuzz/corpus/differential/key-raw deleted file mode 100644 index 5248770575bbd4827f852203b4f6bbd70de6e876..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 471 zcmV;|0Vw`_Rs&HY6bvo@(F+!$_693TWSMvDwF;ehufT<(W?{v%`~D|y7?7l;4NN&s zpCgx@bZY+ERe?g%WuxM>N4YaD$9KI^{N8!@VN5j5ZhH1n)YJN2XCkSoIfCt zOn)cj&&#vdYOh;RWzltz#>*}Ue9Jn^bnV3X`Uxydy2cbAJ1Tf0`z-IWvh!_2qZi+(FPL_SmJBa{O;}-1+pPRvk-j^Xi8co%hjujzsr? zV}wy1tgf6`7#6mXJn_NIMM#>uhSWG(eMm{Y&MAGR@CG+gfyo6k1?Ey8$q3+b{};tg zkb-rW^d#^Djb?)bw%Q#4)fAH?@B3KJ3R2s6Pb=N64DFtCQXk0R|L7y8ha$VsI^@E5 zaOScS0P6bHBbm|BFx@mgXy@Ch`2wku_pYeOmQ4J-33|6BJsw4ev5Zn?XYxPvvL6P{ zXIO@D>tO?bH@L)SsJe0Dzx;sr(5uA#`c=2%iSZK3nQh&2Aiw=Ybe_@GST`wCc4p8= z1CSulx19PK0-Su9MkPJq#a#09wlQf|cEp~%uOf)S0a- NSiat_g@w&``zD-?`j7ws diff --git a/fuzz/corpus/differential/key-raw-with-salt-and-header b/fuzz/corpus/differential/key-raw-with-salt-and-header deleted file mode 100644 index a0f9122c4cf9a090187016778d9b383812ae2427..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360 zcmV-u0hj(;=q`O_4U1>g=Bqck)G~MDbnd5Pu)fX?5&UYNPPsfulM{%4 z3sE^QeMk^V*F@vsm>{1LjKcdoaA$zI9YO+(Bh5`Uh#Z|KHwL?LvR@(tn$)%%roO)% zbtP|q9gaa&euBOsu!c(rd2Qs`Bjys()@@PEF@6puhRDeU4Ugayrpfyc_KEaJGgCS7 zCN;}90ght4S*7*?^bc=mHUm6c-_7a~T4?1qlKWYK(4KM#T<}Vlz*sex|3L>|->Xoi z>)+celh@Q~!?X%XGD^AjsUsHl%a5l4M`j%l&3y{|9N+T%y`#eQ-RrV}( GhYuBu`>M47 diff --git a/fuzz/corpus/differential/key-raw-with-salt-no-header b/fuzz/corpus/differential/key-raw-with-salt-no-header deleted file mode 100644 index fb540f2ea06024c0ceb3ae0b219f345bf029f371..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2765 zcmV;;3NrOvbGeWA7(1QN&m6^kNMUWvc>{~x4Gq}xZ64{Rzj#@IN(sO689GH3&@aMk zY})kaKyx`f)HrHxv;{qj)=6;d1^|mWlERd1nI~Hh@Pwh-(XLIfN0rz@`(h!u7g7Nm zf6c#X`{vnbWHO>64}NK16~HI^?y9%MTk+?>Rd8GfvD!cFZ$%-EQ9k(`8e~)}&*5t+ zUdV&G=}rMH0iKa1(d2f|FuZW8M{fLLy6eSyh$g&L8UU3PB=K)fLb~JZwbla2b`6^w zNtX{dp;lY_iN6)CiL&y5Shf-p?H zq>BGP&m@s~T15^iSdRw&uqbAm*SpzPa1M%R2DBC8kcb+y6|fHn>M}EN+oxAx;?NL> zi}OdheTo#QjtHVu@_NT*EqPxZ?;d;l%whNAHaNXt}Sazyf-0RigNZ!+Ma;F zvE2patO(Y>;+nCd_d~YMMw`j|dymjJLoldRlp|^Jcs`H*BZ%SttrdB(esM_hb}JD_ ziZ!q0DaHGi4HR$3kBARG_+INdn;f^^&+aBV&kd|0GbGn=luq7MD!|JQp9ASzK+2%K zX3ri9KJ+_@@S(-Rs|%rn?V@eU#Y6=)Bg8)HfB6d>@bQ3v?mcQVyX!&YZcl7RNCqbp z(4Pt3PIJ~%Y>QFR!tQWsbW@`Jzh%@5c89oarIK+eNAkVE$~FQ`8#cB_QLm<_uI~Ic zOwhwI$#@EsJ`B7|9xd~sNe{zN5cXJ?IFDaYLDnp_~&#y`X(?or+j61XJWN4QPq z5}dSUi@K%4?NZB-+Kx;8{7PVRY(Emza-`|qnkifqbsv(PeiUywDQFuJ`7kg3h6>yZ)iY!Ky^Qn*3!i z)}07w&2uUDjsPxUj%CMfA&Kn|+~TN$Qe~FoT2Ho1D_AM`nEY@wlNPd^WNDsdX=U8Z`Q~$mv^Dtg#!-F$15g;%7feKoKKz5?+dNN zbIRt9jTnk|6atCdE2xM(uoXpb3Zj1u5*TNios9n+7%rolr;rANKHZ4gBuNgFDfq31 znkCXdH#MVwWlErV=t8U|1(MNSF9z?Rg_=7vAbAbw6b}2GcjBhZqL!%&VceKelj4RT zwP+W=i1VWZAmH@fW?p6xhu&)JnE5O00Teyy;ha5#SYB=d6i%97fwrgA9eaT6!T^|S zK@Nb;Y+z+2%Pm8b;RN}o8GD`Y59Yq<*~M1ze3!YIt5LAftuu4do{g30VXQ*mGoHE% zX;E@g-_dQ*i$RPk`y{VK3u(l(q>-gA{%|VgD!)(Joj1TR)?wKw#W+1C5cqadcHELW zlt|&<;U|H_wp>mNbz<_UvAlv^W5*JHeZ58Z z*^6t0R+S~2@dh<^ORGhVE2cjL`f-DwfbH#dV=d^EKFZf+O@XztIAJbS0M-xL|5ou< zlhmt8W`Dki=QFl(!ttq~lp}qkVdE!)61DX?;c=_GEc}&@9`ywzr&ub^gk^UK1~QQq zfp<|WZ&7hnVWP46IQL7Xs-G$K;Zkr$)eH>i&AvV=$KNNi!y%pI>cJOXRo!PH>=Ryp z@RVTtS5{@sx?dMcjCUlD%6>j1KvGVIlYi-$w4Z5$CM<4;6~l+&x_Fy;i9BT zv}mN+<@4NfpI#uibt%roP?n-zMaMt{+HpTBDvCIIwxq?sq7`<5^TYl+uL^EOCLP>3`#}#B_PVfhGt3DqA9;E3zLGWH{^4{(V8{8Kxf2W?+6j>VOYotBLn@eMcjPg- zB-19F-?0J*_3$i1^5jL;I?-j0dG}vym0Xo(Q_RuNXF4iQlxh@mokO58?oQ1^Yx+VQ z6JnqUm}?13FsPp&g@eAV;0RHZ1E%gJegU=%#I)C82{-MztM%*{0YsbSBEk>}MS&Md zxoLQpqWLr9T1Gg7)*-RbDmL-~XI@X@lMkWNZ4f1K%Gl;QaTKu9ORVp` zafrTpWUu0g`K`Ci3yK`q&0$u~qrCO{@T^Kz-zVRi-KX?=oDSm@mFH-@VOMnLHARUx zH&VQNJ>&r`KNGY>Qo7jR@&_WIy&5!$FvLPn&&-DfHOc=F;ij48ULkXp*#p#pShA12F=&Ro; z{l#9b7vLI&YY8-G0Hn!CaXByTDVwiwmj$9#zQ{)GLcNz{}D5f^S{e!|}gB~cl!$LZ* zH%Cqr@0Kgm#j#Vl&!NrOL#MY(CA`(6qbErKvlT$_dv?F~tWCrnQq{Ll4gA^1d)iV0 z(S$FNQOdbTihXy{>Co#-X*s|%VB{xi*ULp5j(`=>6ryA|4OKp>;_pWpaGf;wdruD4 zsNC>N=n0=^Ou+pK6{2=OIJfSg?&$z;=WA=#nZGYu>jFS2uYNm$O=!e_ilPCu(8TI9 z^2;&a2j;VX8uZmK^L%!7uWfqVhq^!6gN;aG95h!S7k&ownqR7(*+{&VOa+^Ootf2E zVpUcj?mv|2QLv#urH78?c;Cra&X}S#kt8Sj@jeOIi7@n47SMbz4!BMVISYKI$%9Au zugNR)-F)w~lL&C%CDM5-LHna4;5XjCJ8#DKEsw=hT~&?WHzHSfQzr@TP*n8 zZC_i@Rv;l2`@3K@jQ|mydZ{Eu!u0^&P$l9}I=`6B_Gb1!;JIc;4s8g*NKiPuSVMap zWxXzSVVuFWpJ0vQVJ5g(JVL;a<)h(LJ$&_MTgjOu}xkn3J`&dV=5BJ+P8pWqXTmBJ^x z6sf62t8E|jO>oF@Ew6mFuTmuw$#fc|>=dVfoq2?y`FVl644ntQ_ds)GLX9$;U8qUz zG)V0ywnlClF{nJjHDf8qn#2hT!rR#+zC>zJldfw!GEH)VFz8ZgKan^VD-|~W@+LfQ z#V)&JYp%2O*LChMNZ!zA1wrCU+SWyH^(8>$oIK_jJa>-5BDWZ(>}fYDOMf)WgZASs zeUEX52D{1o9)86vDY}OaD-=FiAPkKa&#tI7Mo@9JiSrLGjcv0-Gr$Lw`|B|{XH=R; z5(1UM1~qPArkxNF4-{D^7r4>f#%{$SgwW80|jHie_hmPLI5lz0jdq3EHO*spt&wLaPcaL#q z*}_+?c`jZu;1IH!=VYa?xqYagDG`Cdn(|@d5m*&nCE>~KiXZk@ZSYP-RL!-!QHJ`H zZ3RU{^t(*e=#K_zm zae+&>mnfNA8UI%_xF;xr#W+hvSKc2HWh<+h%&*ZS4tTNrSWLE&NBEv>O(Pn~h+uUx zF{$%%sC^d*zMfV&U02InfyA$PE<(35@?MN#Wn7^y0SbL7Jb2kt$=;0~kZ%F8|EN*d z;J<%ND^?AX)<`?m9|=a{K`s9U=9{BI&p3bu$uGe>lG6u!IwJ!q8FU%f$)@wocmFLy z@_y@5^z?wGg7XLvpct0Ndw+U;T{V)C7Z7K41GV(^6_K%vQ4IHhorK>wY+ygT_UjmP z{l>|VbgcU{S5mUa^SH!}MgQ8N9IM_S_XFuYk6y^*k50c};J9#h8{hm3j5H`Vr`q93 z!^^B&$WZQ&)shan;T#%>)Pm+dwpTtFXTV1*Na2Ai1FZ%}dnM|fA=>(A`+`@P2G$?Fp0TvoV^ukM78j#y zII*aq*e?5MHH9cuhEF3UJ?vSy$v{Z{lHMLRP}A2#s1Xe;qB}vp6U^$m4+vnIr08#P zHH}ABjYFp+O)QWFRQih@E(X-mRl9WmrJX&66Ea4^u_WH%J?1FX=u6Z8_|sfJv$29V zkC=BM=gqQV+GZ`dso(4ly_4GZ9p-nTz_Dz3$Y1+*7M(?%(&K&z^mIRt(7vTI9Uz&Y zUO}vnDsaTscr_h2K_Sf|S}wM7qA5z8KBS+R6>6kt#UCdAw+|{&3!&DNgWcP!kyCSlaFwDUOLw4vT9o|1Ui9m%&3 zS;%Pe%O|zzBCuk_jVnR7_nzey+@HSmltG%|UnE3L(FB(2@kNSa&_uy@21*Ow+*M2l z)lo!+UPkMpt_Nehc3)bl9#&16yGA*Ys16P?B#HPAw{9)sV~O#v7Mt~vzw*G8O!oT4 z-NHG;kXPjFkymPY)GPa=cr?bw;(8E95d4tV{UoYRL;9;{M^7R=?l@zo1`O_y#sW%= zd*L<9hSZBrd{p(NL*>y!b4ef>cHYtBZ+I!m4QLW%q>?RqI^QAdC1z~+vEMEY63zP9 z3?ig}kM=(`Vz2yeX+|8X*YL~o47fAeWKu?pHNh9O82)20rOtkx7 z1%oW8ZejwF_~(bEA&J_cTpjWiGr4vMS0^~F+=jW$nl3J21!*^JTJyTq{#}jvoCjLt z__mMObJ^UK=CEs+k^{LhqCG&+F4#beP}E9fWgE;exPlL*SlaaGE*@gPE0LD!r)stg z%FbWdNBOQ;!F(8-1Dt&e0Xe82Q&Y{{g`|fsg4wDaEUag~Mzm$JW>pwKGHZ*RH&r5* zS#|%Vae)J}+8+wWFR&(W{;|iGl}fb~EKtsMS_+puqhQNP&C7cF2sihL2aTc?!vFQ= zsBcOuJHZn|_ApV>m5a=PEL;UT(%UEex=zsRV~dNPl))(BDHb>mle z5Wyr};d9`0T!~&zL{MBrrSvS{IJ0$nlCote|10sRzv1X~P^n3Gh^+Ee*%{B*=Y6qECmYmuJSrU z!r*xQrRaPGk3B1n(Br`eeE)DpA=eQ1PMo`;+m$b0s^=xrGa|9Fu!}z9n?S#-N_hKd zsh}K_(4GtXdxmFmztc%X`uau>tjd+(C17X+gkz;Q;?6vX@snCLNhzXItiww^p2TZg z16uC-qF!Sj@F3szV?=gVPdk9M{X6{63W(INlT%yN!^B(@Gd@MN>pDA|BTcWDXyl`` zR0i_vOjC|jucIXpsr7%KMb-l_E`oA~7A()RAaBL7M43AKd;AZ+b9ZM{E?zQ}b^YAR zn925qMOK^P7|25?O9w;h4meL^>H2{>zIdPu8tn(drR>FgNR$tZ#P6-GIFem)xP^Yj z=n|wUxvx#LfA*Kkw~d@DuL}u~$CO&6PR8fzx*} z!#TAzO6U`L=*3^!y>_aFaVxbN+U=ZM|B4*Y(f(=O2bJK^r%T)_67LJ#7rYW>i#mjX z@VGn%IpOoN-f3{h0h*X6T9%^;A^RuQMOUD4zvxP#SQj_LzZMQ`bZ9sT6kzxBP~NF%}EsQdQj=7yT3NKFlrvs zJPyGv4!7`_*UI$Nn7e`;4ai#8@B5L3mGg*q93f=dqBOhSLrh_CHeoc}lJ;D($iojg z&l$se29OH#@t2ejUM<48Fx7bXyr!!EgcUVAD7>Xb-6k8YWhrpa%)MI@l@RKnhVoy# z8!Ih?zRg({k?_`KxO+cc)t*BW*s<7uQEI}eiP261K=Ty6JOY`LkV)`QGGcRpeV&*f_bD6vV2Zu6tF?gf&^zmf>xqDL~> z1~d|@;udde$KgB7G!?XK$(IkmU1dS{zk5kp1Y|)?(nvZD_Brwdm?V!-Qjfa%j7I%< zjXBNK!`?fKU_vjow>U$0>BCz8jkaP;(-hW{%K)9R*g>;(=h_d5A zg)2 z&9EsM4L1A%PJ)pgYu0n8&NpWV9X2wA{kikuX|+7$avL_yyA943Oq0npoZSFNgmS+! zh|MMFeRPKjv(?KIS;!1+iq9i6uJ4Cd|&om0Dv*ZO38t!fd!dA4UQc5_^G6O(eh0^=xn_e!mM>qfrl`b6OoJ_yd);GL7`Ph4 z3PdT)q5c`^u^a88FiEaM6{)((+S?M;2L3T@FO3H78hLeY-X&&;Aa9>n6sccQ1ldm= zHFuJzg`Y`{^3Z2_HiwFhbjqMBHa#P8IIPXKchh?*sDkW?0%UP}QHXA+u->+LPUZ2B zS_|-zK;5fBsbStnjm+>7#5Nu75o?lj|7Cclb^XX&*$E_^+|pW>T_Z3Ito2&g=HAZe zb)J>;F9RzBT%_{xHDfE4^Q-BCzSkAxo>U!U27z{^-yF#KaZR8o zXYFAgqYBL;I9gPo!tNE&vvsxJz!USL>HqUv;l0{(&H}qL=AKC1pY6$~!k&9r}IDN5C%i|$37SPpI8l;Zj{vo8FKp)Z%C_d41b z=-Boi#|=q@N0I~ zgS66Rh|g=RN)PJ;JXsXu!Nt!}q^S0SQf7?!Zh$U3w+BYjSBpMhCxxqrCcsCy#e_*X z4oL3)CC^~MUOEbGeRmG*Z#!HNbCCz&soIM~!PhugE&oqawCk2C(&<`DDbPip}U^EE;LOywl5lxFpuUqgrDY<@c0 zDqbMX-S=%kx*l5jfijCG>wd_Y$q96;WrUSTUP)pt<(;kdY$>QKI^7FE$l-1TI!ZDI zjqV=xsyF@kq>cs3M?))A-5O_;>LmsD!QAV;!i|yLS19=beweio76=YU65&||-*FM- z&C<5OFpkP>Q(Li4Vj;99SZ1kE)c;wLI5waqGdPTf$o zyrt-oFrzH^BisWgm6@ih!339|&2SbWc4}9eE`R)MS(pm>#O;wMr`n&yIe;Q@si>k0 zo`)I`KhgVz=jXC}{HrH^Eo^SGY27d6J8jgMgzf*p?*xpGVM7*?k3|@kPalkBf4XZ@ zwoAr{DjrER;*HI;#$=lTHfqJ<=n=T-&h6~qiO|{k26PEq>(Q_}pRFfO>_OCtsldh> zob@%GkUM&mA-%+1Df-}lKNZ%z&(A@xl*_R)Yx%7ipx_nxkh#9Q=*&q3? zL*F*&!pv}Rt1!l#)ZQfE05UIptq!m#C}yhNFAXpLbX2%{`5zwKyA)~acw~21sJF>Z zh-Nm9Q5RWKlv1W?w0U<}(MmNdP1D&wi2#y%YVhX;;*$7t8U%Qa$Bb zcFbCtv~?xRMgpKLbpn?qD8?18{DHIR9aX{53^B=4Ms2yoQJbDWkSiTVqoJ-J%fg09 z%7o7!sKTIf%1}&YGlfNiOb59jo2+srokKIvbEwzCw3Ph+(&Topd>zN|*FB`5`$l zF3PlaHhieFuzN#*JVF_pD-K1O>lpTrUr;qIyt(=uLU|C%$8892A<+BNInXxF`CuSK z8YT%TLPBc3C_f^{LF|bq&I?{0&x10P^4c7Ww#1gt zL<55Iq<~YnOGfp>-pdIJqeWzG=9d~o-WO&97r^aM6cdFD!fdzB!lSy;qN8oTmj$0EYh{awF z4mGU>^p1T>C|Ct5VG4g>Lo#=_q#fYVA=g?}sjUa2yc`zxoiXpegXf@w&N%9p=KRBt zu>oCJ<=3r5=?(fOH5~&WnL1>L|GnU$VAOGV?ZPSrL_LKtH56eqwGva!bz zEVl_@C37Y&@z7V51{K<*SoUQ4AE<=40mT`&4=&+-O79tDVm;SEp)!;$gMqzx@e(@+ zAG(7A(R=Y}N73#=EpSHeyvnF;LC3Zr3x~wMT6nAP!jzL$!xpuR6fJdL6vQI9>9vI1 zn~W89h`e6|gs6CmI);yfnNT%nmHq7~#hhVXUoe7{=BUh*B)?G*(R`oj)uK4~6wLhH zC~k|w6w-feiiu`M?5O@kQ9b+M?*|cbn+q~_GAbjVO(w!2wTqLQ3Cj!j6!rJx3({}P z1%iC;mY=ToLatFyV^15-^%WmX`s`slOY#9!+~+no_s}ThQFnJ+)V#_5m$^ zS+nYS%_b3?g6jXtBcQ1u+_a&li;5OeOC(iiMF2QFQ{;(rRIB`&*IBTGa&*+c9jZNZ z#bbjEcgh9cesxsF^2z%t$1BJ~v~aQQYrR(XmKq#k3w5X`YB|n}coz%xawvhL9|}r3 zUYJTQ4fwGFg}45$lBR`xrsQ`zS!z4q9sqZ*j2&~4{c5ZXIkr|Qorvo)Em#Ac2yj=- zk`JN!A-gTzon}Tmn$K10CRYTjuc8aLPBCljWh+@{>.w�Ã3)O:so™mñO�5‹†Ï^2e3còy¦DJ4M6,·°b¥ŽóŒt„µ-¯‡×ÆFš?&37‘[;ênsT§ÙÅ ¼‚©…O¦ z}Ryßl…%Õzè)ÏÂT�ƒ€¿7:e4_g EoTøh±pVH*ÀúìÌG;~eD7öª“„ªÒ‘g²ÍRuÒ˜©µqÑ¥9xüí{³æJÄ•p²-õ ÚiEêÜ3Ú_õVµý<íê µ R£dˆhddQ1v]pÄ*õ -ÈË>.ˆ_¢˜OÀÕ„dá)Ñ \ No newline at end of file diff --git a/fuzz/corpus/differential/page-size-default b/fuzz/corpus/differential/page-size-default deleted file mode 100644 index b5b18a9354a31ca66fbe4d41561ab96f0c2b811e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249 zcmVK?cxV9E~(V-lVtX@q2Z4yz&Id+9oA9^1vRMCo!w`~ib znCwA!Z88%9(o(9TR(!#1=O;iFw<}+=fyg4|_uBh{X+-VwMKMTaxBUoT33O>*Pe8Ri z7a++@aQMBl{l<*cYAwI`UVz5}uhVGPh2PD4Kn*4=|pE dIv27dUNmnly8&kA-NofE8 diff --git a/fuzz/corpus/findings/backup-aes128-legacy-page-size-below-legacy-page-size b/fuzz/corpus/findings/backup-aes128-legacy-page-size-below-legacy-page-size deleted file mode 100644 index b148d50055da3b997d01e911f059859ede22c5ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 645 zcmdN@V33sj4+ZQDV9)^LgXr4~42&yRuG9sogM$AlFcunJ57Ist3|6iNYN9^?I+zjS z2^M5efPH}?0OwdQ_S_EV{QtjrK*0b1@e5zvg@ha$2@X>R1{SoS-d18Du>6G76b%DG zWtM5NrQanj$}=bQsnsW_fqlcfP(|%kC2#C~hHI!gk0PQQ$=m-WWl@!p%8S0_FyTp< y$t#e)>Jw|YgP2XqC+kSIi7x;->K`zW)h;=-g-rm-i-QPB$$K{qb)GB$NdW-TL`k^- diff --git a/fuzz/corpus/findings/backup-aes128-legacy-small-page-short-read b/fuzz/corpus/findings/backup-aes128-legacy-small-page-short-read deleted file mode 100644 index 04c9ac37afc41350414cf7147b161225251db07a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 364 zcmWeT)F`lh-c@PotTz>pcTSsjiJ5!LL&=&xu7x;3HX}|c;w0(=yrMJKaqy@$m@u#l zynfYqW|3dTf~Cz`{Ox(QPhP+HI#=QRgst}{7rf*4kO|qQVQR6hfSJ>fBY@YF|V!xY_4gXF^&gz@c`@;AL!-NMFvWF6879S;3+Z;iI o8CuJF+?e)O@k$r}&0=m`rdjEkb$Hk9JN_#2hhKWEdicf#0FV~HA^-pY diff --git a/fuzz/corpus/findings/backup-guard-bypass-aes128-aegis b/fuzz/corpus/findings/backup-guard-bypass-aes128-aegis deleted file mode 100644 index b3dd33ed0dac302110a49c2b152d9d25305ac1de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16 Pcmb1VfPhCQ!SsIs4~_!L diff --git a/fuzz/corpus/findings/backup-guard-bypass-cross-cipher b/fuzz/corpus/findings/backup-guard-bypass-cross-cipher deleted file mode 100644 index ca9273edb292fc2229fb39391da7c994754bc960..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15 WcmdN@kYCBfAZoW%`|DfKW0(p+aH=Cefc&x&=z87RvS8={~6)2UjN zSO`z)R~J?781g>`5OC9h3{XSMob`pO^d`}(&cpwp=Vo`JFeAi8@$|~8V7;UGozSi`QLH$g5D#sE|q{0+;HeN zW6%q%2=aW&ShJv~w*2(Hd4SEd`?y>kWAPR=g-A(X^e4q%lz;&%XuY4tAB>CAfv{ZZ z1%6*8RHwv!cC;*U*PqE?M)b;@Z+pB~{jC(tAEq+*y8n_V?H!<_#S?oSU`Skq9 zGIPr!k4r#2l35k1=IvQmAnXAobC_?*0I!~)fF3&|+3vc$Q6y&rMU$ zL8te9DNxub>!JF_noRQbZ7Zhp$?7A(lVEU{5mC(xtl;)b~=HNarw5Wde}Y{P&k@KLXJ{Q*3tlA9?25d?cc z_@8kipLB?|w)u+65tO6e!xBwLI~UxBnQVco)qBjN<-y{X5rTu!nbTz=AAnzhw}6St z6u^7J+BfdGoJp9l9Y(kJ0n*c|kl7>=Q727ro5=%~V@$zk>PpSt(XYAeW!`=!`pw}Yu@+yADDfP?-T9J~Kh;*2{&^!oRIw&6CTU{S;= zJT>zaIE6FQ#FWl9OFgVQ%>CiUF`a+jZs?^nSmL#j{)aSN!Bp!j_&?gs|2?(X(~9;F zNm<~7Y~p}3>2Vb|O>CtO3}jfD0fOrB<=*wCNmmjbnS~Mb6x;*Agf)Uq+#f*_0{B)~ VhO0{&Ej5z}gS_bWW2OW3=mG#ss#O30 diff --git a/fuzz/corpus/findings/shared-cache-wrong-key-sibling-then-vacuum b/fuzz/corpus/findings/shared-cache-wrong-key-sibling-then-vacuum deleted file mode 100644 index ccf5ad6dec816023e00020e7cc960aeb3a85e613..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100 zcmbQoA6wOXeZ%rbljF_1w_WdDJ`u<$G29)!O&Kh*JY}xeUF+ozGv+p=pWN4I1X8tl uPSO@tuvlhF0|OZJTrIjV@y_2SHC@wr{INbyS&lrqw=2uXhmGMs!yEt|;4q{B diff --git a/fuzz/corpus/findings/vacuum-65536-page-size-corrupt b/fuzz/corpus/findings/vacuum-65536-page-size-corrupt deleted file mode 100644 index 5fe991badb3f1ffd75b747c4bc1704545dfa1c8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmexo{wVc72yDdy5};xq85w{q5QYG-1}sGJ^zx|Qbud+68fL^+CI$wC0mw=~=1c+t FJpk~&W8nY* diff --git a/fuzz/corpus/findings/wal-aes256-legacy-vacuum b/fuzz/corpus/findings/wal-aes256-legacy-vacuum deleted file mode 100644 index 6849ab5..0000000 --- a/fuzz/corpus/findings/wal-aes256-legacy-vacuum +++ /dev/null @@ -1 +0,0 @@ -Œ³p8)Þ<ÕÄÿ–÷`è÷©Óer^ERçŒLš*”âÿ90]Óäe÷raw:sq4¢ g ÿÿÿd–/]†Ü(,Ë]]bZK¦ \ No newline at end of file diff --git a/fuzz/corpus/native/aegis-128 b/fuzz/corpus/native/aegis-128 index 1013b4f2551eb62497e8a4abf83b5d83f36d93a6..ebefbb054c22848a92888fa27d51d0f1e8a89490 100644 GIT binary patch literal 138 zcmV;50CoSFx=Qfkdf((A@fNW`&mI@MV!Z literal 915 zcmV;E18n>{Q^@h$6Qh`TD7t+8=#jjo%YevN!y-1R^MXWw+FM9)9m1OK`_bVbPv%Us z$@cwstVF`w6UFMRgFHIVLOgx_)d)J2LMi>(bVw$>l^HPZBK-y|9)nj@BsjtYj{d#g z@<(aBAD(4d_vIwp`5$GKB4Ml9?G?}hv+GsDu5@+S*1Yof)=}b#<+|BN*a1`Jol9=j zP4E;yJ4+Szl@188`x-LCqe?)8-QB#OSfTtRFYo_lEso&$>n|pebO;tq4>-&HTIjD0 zw2!I&_NOGa>+abCF_E~h)6Wq5Q8)mbkTdfrb}CfG*II~kzyyX6Ew2y3(2*RtZqefM z*kI~VD8|M7wir2G^bnk)T5Ni~7Ll1$AaFt{GZ34;jO@hmaT|-)(mQ>+OA$>{0*V#s z&2^&u04xgab?sXPLDZ2upvtiKzpuKz<|S_UmP3Y#Sr6Ss4>h#?==B=BTN$*!1jhkC zWHqJ!^8zCIPL!Qd>?AQr%-?2y>(io+z@XT8$#TO^S;Oy_V9b!*v~#)J_i^?lxr&j+ zQpjVEDcyh83YnJ&eLKe|N@51nCqbv-lbl0z+)3@CAdI*_Wo|Kq1gBO@S(ZABN)TDIW0+Q!{9F)g0@zH~lHyk$xuy%bz9G;$>SEP!K?p04#mjQ{KZ`%U)Q)1dP}8DJp11kPn;3y3d$ zEZWfq6Vd9-wl7h#T^a<0pe{PZ2|h!j(0c&er_dDj(v)KZ1iHbJ4>c^)4mjA$8MZCiZ%$l?vJY#NyfyTWW~CWFqz74aCn zJC6}o8L&1Zd79mgV;D-sQ)#Jlj72Nh1OPl7lC)?=j)j*J7Kws24ci_vjt`QOh pj4t5+g^uWe)aYM=Gh=T<7VfRtV*;Q>P .û3Ý9\ü‚¤d.¤È?ï®æ ‚Ýï'蘀¡Eçå>Sw}([å‚á \ No newline at end of file diff --git a/fuzz/corpus/native/cipher-aegis b/fuzz/corpus/native/cipher-aegis index c7b7a1f9a463320699c0102ac30fb05ddb54abe3..57f78dee81e3f04f1ad8f469bf405fd2d638d694 100644 GIT binary patch literal 1470 zcmV;v1wr}`4w2QMnWQ9FU^G>}bw-7K5QvtwZXD z@FwYr?a3GTcP;6aorMRpc8xihT4Xq6^GJZAXm(){4Vk<-cS8q}ooMI663Vp&Lf&!8 zSyP@}nk*`}1n^9ssLRd5`66jKJyAezZ0N)p#Qb#d=mhR zg|tGgl5CFl4y%HG&r7M7VI^aMiP;iqPY%=|eosZ-BKA`*!k`NIO_sk!Q*S~hhQyN1 zsazU$Pt{#So3Ol%bfkdqD{_2s1f81wv%lEERnz2I=|dq|+{-92SQ7M~K!7dG*-#9e zNL6l$v|t>Rd^R}@OCt_-vJ;T1uNr_Opg_nvc~?Al9Iqlbu#ID);cv?_ zUcgA73-Gk*GYajdVUWd{$mk2iqDi>(y?qLmrF-T~Y-NTB_{KtC0!qr?CvJp4w)a1m zZ%L>X)N=KOVbV`KC3e?B$)9o+f5XuCNiim4TnjEC#^4n4rT6S!{a>WzYSRb05Yl9D zg{vp$!Zuj>IPL@zg{pP$)eW{=7`D$v+Q8K`)y5E)00hK;y7&%Ri&p z@G(R_IH0Ldlk}<=rekmG=E-|F8*ia9I6qridA3Ewe|RaGolZV zbNHIP21oq#1rhi4n(x{#GugV#(fZI_a(wil{eO~%ug)Y4tzGGR5+L?ASN@hK_-)7F zDZl^m-VDmoVf6mI4dS!z;m+gV6F&juE$(!`A@wWEcC(elu4*Tg0QzRF6}u3XZ2Deu zqIPOW9x0?btRT0dheFdtD=TS`{kz+4qUY?Ug2cZP-Lw4RXgb3)^ZfJN|7=kf%jur05-_Tm*eIJX8U|VusEDgH78k;Vi8I*M$frs?fXY~YxQ#;>Z(GO;cUoaagXPE zEP|i>ihsJO<%+K8-l>uwKD0IjvBz;7q5#0Fy{D`DjhleopgkbYtEC-WaVjE$7Yv!S zR?sq>QD-g!4APeJc`m7LG$8+=tHpP!9g#Zc!MfP56W(yKk47|Au3P0uG9C+9+ZC50LuXR5G-1Lpte-smVv z@7-1e2kGQGc0po~&kdXXBxbXG-nxSEcZh@!ypo&^<;5B!XUy6nTrrC2ktzTSm&R*l Y)pOA)P~Goj;y& zmg2vSjirCutBnJL;Vo1L;kQRkyINsKYfv6`Gsi=>cI7&h7Al;fImNS4YP&+JV9N=T sxqg1izK(U!bgf=6`x=pU?gE8VtgceN2a$AsqDj}jJy6aXH1ygcTgoCt_W%F@ diff --git a/fuzz/corpus/native/cipher-aes256 b/fuzz/corpus/native/cipher-aes256 index 7efeac85519253a3cb618119342839f6e775b3d5..f28e58a1dcf51b95ade04d022cbc87ac62eacd5d 100644 GIT binary patch literal 212 zcmV;_04x8{CD=z0PdT4>M%V&(nkt?VO~`Z6QzXF-t^AQ!rj6)9E*dEmk|D-Hpi1L@ zTlSM(U4PB$t1n593cf7jw>KvSaxRETKLzVN767mKPV%Rqi_v%mBuKV!53}UeK=B%+ z#z~RlF{?r+IjX?#jcT5UPT$*B%tpkbS4kNAfCWjrww9PzJ_cJ5LWwN`0%>?cR3v=b z)hUZd>4g8~(#jpK)rEHHVE`N;!UoO7DSSWwd+qwP(XVN> za7yy{De_X1U2b)#xE2wh! z@1rPgkF{x|p7XYAbBaRxkZ+o!NaFsbOwaT!d0avp@G#Q0+6{}wsei+{BhiZ0f(qi8 zUYe|%^C5>mg~r+cZ)-!f5mg&jBWjCd{bf}rdDR3s{Gf`SR;;VfcR^bn{QO3T8^}YK&L$PK|YizxUUK z{gLY~5*!@Zl)jDuFqyy2?u!bu!yZGMp*2Lcb6|eA=CI+1Qc+dpjez=!4AZR!i>szpIc&Nw8P5*Ik@X|r zftIZAsfZjmm5DZ0Vsz>*DunF-Y7&#vu_+bQ+UfdH)*%CnCG7FE_9xdiuyEWD-U7<( zg{-8!^gLO+#K=SRKb$J`js_5vg#%G3>$8o#t1f5(M@>H|b28>ZG}s2MkN~KK-YX!y zo@a!-!D6kaLfp7_^q)CcN<%+$>K%)A>^s6Z#fHqD~QW9p_l|Q~G z3FRGF>JsZ1Tk6Na5CUBf{@jPt3)XO+KR19(Z-O1`4k7Bz5l%Ho-Ow|g{5ZfL2zR35 z;W;}9-b_)A9#lW^r_8nm?6CLoZgca&iQa}P!E<>2s`zT;rn6)-GjlD`ahZ0usu(p% zYpA!8X^FDX{U8;AmrbfyVnGWa0CtkS#_CGhP#h0;4{%Vn$iSt1>Jk_A-y|94=aInF zupm9rdNdnP``4ImS~PRBzB(!{n|e7PYX~M?K5(dCbRQ#j=#QBO?}7(Uho3vbWq~x1 z1?)Bq3lm0d26bSbNAWf@TZk7Co(!WUf{I+o5-pTYi8P2t$ElVp3w{9Lj2iaOYU9o% hT^^AuG|pWQ2i`I{vpxK=K0>OpA<0bW@`wh6bk?V diff --git a/fuzz/corpus/native/cipher-ascon128 b/fuzz/corpus/native/cipher-ascon128 index a032cf73ea1a31d85a735497b4330bef55ba4075..ddb331022596e1642999096159d73766a74a858c 100644 GIT binary patch literal 397 zcmV;80doF3L6^;Pmiq^Li0)1{Y6>+wQ7H#bB0?HlbnC0qKC%J-z1pxv^V^8>W56nGst+_gdwj`B+E+p9k7}}-TQDf03*q)VQtxrk`<(bLGZiPx^d3|Q6Uv;p!oB= zxziCDN8alWcr${VzHMPsgi=eX`iJ`NImH83|8N4>YspTpecjgJG`p5xEcP7)Sqwk+ za)W=+4_#kxg_$joD6;+r?y&ApDH0mQrcCgIzTL_Fkd+=se|!%Q^vzZ^JkgPJRa3u_ zTpEpl9kfdB$f(P^7ZXH9E3s=%O7c3h{Gfb(qJn_l*m7UGQh9B1p_m_Q&!{e7a>0D- zSLLU;Orcm>b2wl)%=>XsofVqH^npwG%C-Dw{)8?X@u2n3@7joRveM%Qi1ejdt~0v> r0J2~k9%N0QEEu<%6YT8rYjp;9-6`bLkg_PkboP4ozB&2M(_D_(r_{}f literal 101 zcmV-r0Gj_jMk~E2v6`JuRar;Ka|5k7vlc8l(SJfsU2^cby8>}j_ZsgZ{L+pFQMSz|a4@|=RD3ZE0 H>=c!z5g9MJ diff --git a/fuzz/corpus/native/cipher-chacha20 b/fuzz/corpus/native/cipher-chacha20 index f6e585c61419ac5b811945e0fe5458427703003b..da65038c280df9e71aa6f36f360bea20792e0850 100644 GIT binary patch literal 693 zcmV;m0!sZn+Lm^*s|!lFnN)(TJ0DNh-?4Qy6HXbF|8bH*s~u%y+Zuy~2yk%EL05{5 zzFGPvMae5oEo*o89)_fi9k}Da1~}36L=_@Z6g)tzH@nV@xSR)x-0Xw^;ce09d|i3M zqDf0*jr3J2%wuK-|5sAul7m;y$wc7b5Z~*eiCKBLU{-S)be))km-_3H2F8#=z?T+uUyfl#ibXC$UBfcUG~tqU!F)N%>zy^S>Qyc zFJXZE!?Q>lIIMRw&_`;_jrA~NGnV>FEM5cT^e!Rj(P%i|!mzdKHIjg_eBi~@X|$^W z_k+x7;$Xa${l5=Hd{Ze`CXL1@$*DS^>@s2s6!O=h9CYjYPuJ1@2NU-f-p@h~xalLr9(16?3d~%ZF*&9veoru9)a39;FbD4vg(IaKWifr089>#*u)8J@8rW zs;9NrP`8)`wv1O;y&l%3W}#1$bg1HA#o^w&k76HW#G57a`+!+Fo@fJ(!IQ8+MBTz4 z7YBs8Q5})Sdgh|_;~12sOpn6Mp1p5WZm&kP9Pwz@jU3~4lrCqfFpuPNUiy3zQh|Pf zSu1kaybhUcoUaTR0(zEU^Qn`g7m(d?sOVdp`lq$Yp`$*NF9LItG-<+Z5fee$Oex-z zVIV<-4suNtTR`sylAoEUc@Z3ZwP#$j-=)Rv8ljh~BA!2G_aTJb?s+FTCtF>=-ro2@ zw-L&4k+*GgeTh8*8^_YnVJ(Et^OoH3^jeIEB>rIU6r#_!!l`rrQne6&r85Mmd5UxR bZQC5{EXiqe`7ywNHD6?#x3ZK4rsNw!+ujqn$6t$h3n zSKl)LjqCBn|bJr3mZc?mJZK_nO4ayBEo)?M_txFCCV?c O0?}stB-z(CHT_fzLujD@ diff --git a/fuzz/corpus/native/cipher-sqlcipher b/fuzz/corpus/native/cipher-sqlcipher new file mode 100644 index 0000000000000000000000000000000000000000..53b62ee4aac8ae010f03b449ee272630d694d9a8 GIT binary patch literal 582 zcmV-M0=fOqV3n8GxfZ#AxD{*m?KzI|uk($fWJ-@-T?Hbk_q0v=B?6reCWG_C{Xz2T z&$(ISU0jubr-biH$n6e+xa)`@IGRfbYI0@?>dwp!IC+g6$4o8~NOoxvqWXg`_8{ZaR|OSV&$xHcWcc5nC2@Y%@oo zcs6x%8(pFbAJK15el3}tmu5-FPjw5*&$&FEBHrCYlbIMV&V8i#(FHJScX~IN;|4&P zBq9(5V>{)Q9RN;8q@9+i6MEXHh-n$4ceWQ@P~R6P}_Q`tJ*~pcdVh{dsqkt)KV;d zW|m)g#SK(Jv3WY*m36-%P=$;`TPvmnI}||Zp}4H2=vQTmZL0QxPvAVcXx3joLh;yN zp%YjzopQIVC~z9ZoHV!R(xE)+-q?V;?$J!RM8F1(Lp#|~QF UGEsDW?)O#Jf%#$N&HU literal 0 HcmV?d00001 diff --git a/fuzz/corpus/native/damage-present-authenticated b/fuzz/corpus/native/damage-present-authenticated index 035f49d4d3fe1f6e0e6e0efd46e2a5364fb03003..e36493e7dc3029141d9c6038763b39e03724b987 100644 GIT binary patch literal 175 zcmV;g08sxC#rm07`K+4~AQqB`KD z^}9`qGMTYOo(#jc?}P!tM@gh47HOTXbCTuGOosth^N>aZCjvSa{Fz@uC~pwWfCSJ% zH#g!eVT*=yNWXXx3FQFVo>w9}afl@-vGsE(ta$g@2O-`wyfI2{UIKXpZ$r^nlRYre dE#ildFczP4pcL`aGWpA@ukR(4_}eCaQ1=kvRW1Mk literal 360 zcmV-u0hj)~t_^;+5#G4T>Xujc9x}F!5VXyQIzXe@`_{BLPYz78M@uGM}CLL}=Fv!LrX_$q+m&Ow8`eaGoRexkFsO}n*{qvUjND$H& zjw)vKdajfR*``TBe`zg|0hO~*>zfR*0Ktwf1NoCq_wdrzTv0`&+?)Q$QpCUe>h)Vc zte4$J$jCzyZ0#-HNl$A-2ooLKuW~7*D#3--;&d3D)P}Izc1dykppC~jfFc_W987u*KuG9vhJ4Kg>=&-9P*5pV&Z-``$&!yM zVfCuZ%u!vrtmY#C*R~e` diff --git a/fuzz/corpus/native/damage-present-unauthenticated b/fuzz/corpus/native/damage-present-unauthenticated index 923995ef0ca635c5d6aff32f445b1afcb4b5f8fd..c3ae8f0cd94310c60a35a5308c72633696608cea 100644 GIT binary patch literal 175 zcmV;g08sypv5gVsYBry1Gvcypm2}f{?#ly8_mTTy zA<`F;yahcY{NF79Vn$G!db1Ut9)UzRRK dYHS(}*&il$R*=>}T|xa$nBNy{@n@hosVR+`SKR;r literal 323 zcmV-J0lfa|gVhF)6rWB|=}lR@7q{%yQ!@i5Hrn8LCD*s!Fr z*YIoPD3+_>Ve1>($(6Mn4o0!^B=~?B!qeH(BUX_deA?4JyxS4yHw3Kbey?N7r_4QWMnIG^FDMjn%n$LD`l4*b!U!p3o^ VF3G3-=F%S}Oya+R^+m0qZ=rbWrUn22 diff --git a/fuzz/corpus/native/key-passphrase b/fuzz/corpus/native/key-passphrase index 8bbe5d0ab12c686bb66362cd840bdcdd818428e5..703ae152feed6f62884385d96798c047dd9cc7a8 100644 GIT binary patch literal 64 zcmV-G0Kfn4y=Pbs=@qL}M(v}B$!Mf>t2SK#sE*`-E literal 286 zcmV+(0pb4o(1b*(&;z_BPf3eG2u5`Ft$tMaJ?ubPUw6pKh5AON^auncNE*f~u@Y?s z>jfodifp(CYK76{Gh8-cJI=gNiy3)T!^$qh_YuJ&7TWvoH-bo{ceP-lOiVvk`f3-Q z)k=!G3`@%tGdlZ3y18H?=#Nq@Th$S`J@fU$+QmCgw~t2S|BYrOebT)yLL+ZnHzM=2 z-W63S0nGg=oRZ7>Ky$Es6-2NFYMMjl|FgY4oL)>^<@9#CM;y^=fNZ7VpGXR_RjIG| z1T3TSB^e%$#}}&VRxL1s4GF;R4wXecy^wwkbcb5Jme6v|Zt#a$p>Q2a@468|KFFvK kABLkLy^Z@t<8 diff --git a/fuzz/corpus/native/key-raw b/fuzz/corpus/native/key-raw index bbf5d8d91573f04d2bf81b89615e9bc76b82dfcc..c8f7e0347fc451356138b5b65f91de0c7abae46e 100644 GIT binary patch literal 101 zcmV-r0Gj^gLUKt1~$G8 zE5t#K4dQ1U)ReD-0C4`ZOR`|k{+TD3Ie1Vkk$$qNZ7%9)xanE^-6zsFq0|&wwPB+{ Hl@{73>HRNP literal 582 zcmV-M0=fOw5J|v$FL4r=BlU3Rb{<#lcdl!@`{BMHMPTes%3gU9837+4#1#^zg(%iR@KwLOS89xptXo zMF#IvwCX7jt!S?;$cRKiGAixln#qX?7a~uhsP(0G$>+Kol~a^xSN)@wv?@tO4cch% zFbX6Ex+xAESQpw|SupY=5BRl*aI%_K`d*F3)--x0F~w_py`jOKo?RzVGR>EXS_KLs zi4~zIxG{U4btGDV2N92jO+N#DyI9f6Pp)rco5nsvD3JBKwu1={Oz^rq6|XQeyY>Io zm;`f1OzimSDvEU0KHv=rEP#EMvTNgyQH`G8s43>nRLB<5XEt@bOrD2(@`tTM;bh-dTVOMUQbI^<2ApK5` z6~&-qq72vu?t4r@-J~o%CBvlGh}{s$*QcROR)1im2SDg^FEre5m)UFV|J_mTG?og- zn^07b^8>w6#k&_)o?li-8qqLmbZX|6BaJY;2p{(}NBMO=((i1`Yns5q#$=+)S?R&M z@tkJA-@1Y#N^S+fgvGcwKSIvC;yWc$>a@3r)$b7CutpgQwYDH@&aAJD’Ük7§êÏ·€_Z™bÉ·rà4¡”8ïð +ÍñÍýÁÜykQc \ÄæQI/¥#»ça¦ö�˜†ˆeæ3Ý5Ó¦·ƒqΆšáâ¿“TO%€©œÿáäyØÐ*ðµåo­ÚaÖkÙ\„‰ÝþEðÂBêp=ÙDÌjyÓίé{»ïÐGé+Þš‡ó´Møg>XôÅE~CFWT)s™^Œ¯»_–µ¤ÔrYGï]ˆ,�Ãçý¾\"^”ªíˆ2úßyJT:9Jú1®1˜*vôã»í}æJ…ŽË9šf¥i#J7 Jú.g Œ€ÜÛé¶eÜ郷„‰ÌBõ= +AH(z ¨=‚De\\Û´ºyoBx_’µ(è°¡FªÏópÑ9yT9�Cc¢…K>m¹ô}àåi*޹¸¤ÕíMž;\ÈäQŠOÀH ±¯Òv­Š§¨ \ No newline at end of file diff --git a/fuzz/corpus/native/legacy-set b/fuzz/corpus/native/legacy-set deleted file mode 100644 index 0a2d2c6feb69fd7869faecfc9631410e92b92547..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmV;g08sxd8J#-ibJ}|t$!{Gw31wt|Z6_a&MyY2z`6f$b69P#K6=F)3tdywd;SfMX z8FIfowiZ-`7xTYhk5T@HRN(5VYz3y84NRT#&86^y@J?hv3P5rcs8=$^Uzj2RBBldr z3hZeMXrR3Gz07XXK?Qc7F3R%hlbsECemb4B6o5*huCabIQ^ES_I2Sem@xH^0of6}> d4r=QrQ!C8b@iD`j?YrJh!-}qZ*Za#V^~#}*RC)ja diff --git a/fuzz/corpus/native/page-size-set b/fuzz/corpus/native/page-size-set deleted file mode 100644 index 538ff03..0000000 --- a/fuzz/corpus/native/page-size-set +++ /dev/null @@ -1 +0,0 @@ -ä3sÀƒ„0š{Ì BàdáGƒõü¶�ÛÌçÀGÚ‚ xíN²Â+o&?\«Ï±ßÄšø‘EÌCå>#+qDPóñ¤ÈÚײw`ó‹yYlQ·„ÊÂ�€>Â"”‹6y¢{¯â$‹ºÓØtxj û7²x&º%Y Ûû_PaCUÇmÒá®ÂùE‰/ôáÊrZxni'`_ˆFá°-mùŸºø§j¼… pÖÐ÷Ç–ñk1‡à…â)Iþ$dÇ�ïèÓÑÝÝIõñQh„®Ý}µ \ No newline at end of file diff --git a/fuzz/corpus/native/plaintext-header-present b/fuzz/corpus/native/plaintext-header-present index f88f36d36f1709e83b994b5520787a45951be896..45e470ca1c2a02d062e1bcdf3aa00fc4eb8317f3 100644 GIT binary patch literal 101 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

j8cc{pNTn_W<$HfAE{p7@$ z6>?Fon$D59CakRIidqaHqGa7obq3Sjl>AAf7#QnBvrYJJJr4RF+gyAiiTly8YC#M8 z7e#Xn(0(d8JvPyxhfmB|_JBkvXo-9VsgGosr~;NVj)>~+0fmB0Xalzfc`|KxaH^oL z*b4ktE!Mu8R;QI5>(Mbuv-h2cf6m$O>-Qe2>vjG)i9`x|FVr#q`k`}|&puVtKlY+o zeI-}qU0W(itm=A@0y#)#-GpG}FU8V~N|ezc|h(}la?f&${|`G(7k`2~R-mXPHZ z4el(*zGapt{pkG*2uUoyPLK&f;Br+L4HHD&`E-_blq%2;95xlrLIBQ_7Jhp^7iOU4 z7?sk0@BWN+{5-d!+uPiyOB1@J%6{Q;1)s%A@Fx#*{(`rofL;bJ7hDv9*wP`F!1i;z zZtA6*jLALjo*2eG9lf9N%70`0SLsihy1k9U)-a=3RRV4z7<(sIbgAqZ%?~NM|CWSz zc?6Pd_N(Q(j_2U&FDB{ZkElH&v~$yD?`B<9t(OU!xHcudY|tgm*9L(Z;29{%`(8=u zRxK9Zlg?$;O}Xhu#OiS{Ai(=*4yGXj1)|uq)qP~-zKV45f19U6q(9}p)thX20Wa(F z+sH2xJEf}39~-eAC(TSIg!I92*arK|*{mJ$t8 zS}MZ-sz|I**x8I&DmEGB4Leal1HE^Q0e;dr2oUrMI^jDr1Ixkvx8%y!KF<@Lvv#(Y zymfoEFa(S2HcT9Omlu8Ir5ACrhHCjwZC7C5T*FUiQ5L{zk;XiAc=~bKejKu|?@wj8 z%8xf=3=%0J*t($Y&3e80jbwsL16(}vZ~BYOMZ{`#;ZS8-b@fjABgZIJyZDQU|DGfQ zJ|+Y^1r3)XK{u?0)pe;3F>?jK{L<+OSVHXrG-@wE<^^#O6DffHcAqTD9b59te%-jF z7d#ymVA^2-8xL~_rqpA`(t+0t!17xB)o8=92v49KVofRDb{O)SW}~Hn+2tZ)qQ&KG zOBa+CfPIK|n2J}4jXo}FUcVO+1s+-@2aVk>m0|}bCa|5VrcnGf)qnyrhwO|{ZJiJE zoM*>}=46uEXaoOpp1_&Pg5DMZz*@ui-|1(QY(Dj)4G#Y~A~S=(vu2+d`gQt?h1V{T z==1?GoetXGcH2nDgvRj zR{PE4wym@!y85!1COC!d^%7qSKnl#2*J(EL!pU3A1XkZZNLM58Y8N9na`5B$bEC)? fh>VF1CI?ph7Ouf&TQSgZB|EANpz!99{UiN_Lvoj6 literal 0 HcmV?d00001 diff --git a/fuzz/corpus/native/sqlcipher-hmac-sha1 b/fuzz/corpus/native/sqlcipher-hmac-sha1 new file mode 100644 index 0000000000000000000000000000000000000000..8959257c2942ec4f0a927fbce8697055cf0095a4 GIT binary patch literal 2210 zcmV;T2wnG#u%DlDp`u%vM4K=v6EA_REf($<9(|0dOc>2R@D@I@u-&oWB2lNSzSd|M z5aYmm0c%Yzwm_R1D_iKi;cdV(vUJwQBU1HPgxzRSCBr(4HW@PV=Cw;g7w1;$v#A@&jRowtHjt?qzam{x02FH zd=Id--m&v0h)CeQ>U(O8=Nx$vJHv{`9XeqGH&VPeb;-!k-H77j`xKE#ES~DB9;BbS zKGl}lXT34=k(kymG`Bw|gIk3EA4(FNXTz$TC++r!&RzjhLXkY8*7gmyy*XkP3Vf`O zm?RKezezW~2sVTEIS>kd*Dm4V^5(!i7dH_G)tMLchJ{LY962@MV{%`@6%e$4H-`}{ zHw-Rw ze&N`Gzkn#z1N-REktVcY`w)##&k~V0E0LY6MrKIL^C}ig1PXzDLl=WuuAm`bnx7DR zE-J8OS+6y}QF&k_KAFIzUGY?T@p<4?@JPrQ3C9i$fiCb4^bPK^bUryA=B}+HQ`aE1 zOg@4Uu-Bg-#c?y#NTdk&1Pq9O!iamITpv$y3ZR8WRLz#>H`y2^_4Yhv<>)!cH(sE zs#{ni7mGY0{M!(TKC7W<>IR)>A1QyrwgumD&Ptm@4B=HRS0?1f2D1^b6x_gXU8`3a zdnO7sQ!4(GZas48dn-s)b)QbT3aVFjU(?pFJisA5Dgn3pa@^+_`eGfH@s@0n!d?4) z+#(v)Z=`P^sszC^f+q|8-+UCKc6=)^@ETq{{CtCEc#DmL->w53$y zYWCFMTum%vAL>uSn%hLjoLe)mi+N3F5pHZu%cM&6ghs_ylKim#Z0o-_@+m2A1-tn{gWZ?x=jImBL;iw-g}qvs;9YCEc_!>IycTkBQG}M zR`4>|{WOQ`?%3)NMVf~E>*DN^;BYb;v^yP1xxPFE`IYS%ElhLU{iEfps(KH(C}G*r zm+}`ixT0n=cG9KUlsbf}OCFNwo3F~;h{bDukysH7pO-YOm9c;qfPlZ*J+af> zn$cKjt1E0lYi+F^U<fW5O^~Ctft~3~_Ui{%8r0w3dwdxq^L)o0}m) zRY~NvGI;@_$Z3F;Q~!xdBxW|0E3C`p(!+GSz&?7p;NY>OBK*Gx5lq!n zShp}uX~dSqmPk-C)hJpbgbi?jGe=>YMaOdI;UH=u@lZ%S7R-Lt-`A|5^IMXz7&qPk z6&h1%4?2e`IUU}Dn=fw(ldpV@YZFI4OEX`WUG14M*Lk32e}v9W*xlnleCkdRA8C8C zT(U0we0)FK$uM#xk$Pfn92?+do&p9zD2Ou!z|_*eAIwHMZ+%VSRy;GZE9hX!3{Jq! z_X)DbD{3JLqEja)-UO&D_rtc<<`P>R)?|Dkjhr<{TvEF`O^tq^U)LCdl zh?zPe*f*!O9sx!A)gZ262C-zLG>7wrk|Tl6qYLy$>2v^9aW?Q=kEkj>t{!6lw+kI> zUG?2(a5qYyD!z3fRG@v}**7QK>+hTXRTLB!cr~!itLxWsrnkh=b=#RBrBf11$$tpD z033mE=9Cm_>&|jgF&vLhSzfDAr$xy`#~HKqv=SN(pa-vwK)jN{O$f88C%f)gbs8H8 zJp_jbP#r^Q{?2XO3+c%Wyh`0qpk?sLYw|L4?q!2Gm7jh@*$zH^*Cg`QF2cUzW{uBF z*0wr}r;Q=bd`5s$j>-+ty7OzV?T45ie;K2Hhw+JeT8|N0mUOHgzB zuh8|cD5B`RsuwiU#e7pS|A><_Il!o0(Jc)_9s{Fy^9{SJN)YGO%BDG|q8c>| zpPTg$#F&)h9S00AuJ&EZqhr<O~9~Orf2b~*yzR!w#F7dcDTp2(Azrvs#Kmq z(6_(OKc}<(!oa}la5*M(%u=V-)yev@D@oS67w>(|1-L%MEM<~~oX$Ng&+r_$?Hjmp z&;T&Gji?WWU9hyVZp literal 0 HcmV?d00001 diff --git a/fuzz/corpus/native/sqlcipher-sha1-damage b/fuzz/corpus/native/sqlcipher-sha1-damage new file mode 100644 index 0000000000000000000000000000000000000000..99f4f1370103d049a751021c228408436798b86e GIT binary patch literal 5059 zcmV;!6FlsK*K?%BR_j-hiB_QI3GK*10I|MJl5Bh(qVH&H^0}nv)U79}RrW=e5q`jD z32+`F7eVj)l1_2D&YHXdxalop20(RcLnfm6BY!~NYn<;Isy-U_5xU_pFya;k-m%E{ zSG7^Ffz_*h7r^*Z$h!ez5DC%3lG);3AYX|79armgrAu$vNhpuj(6jZ0jf2%vpzlC8 z`jcsMWh<=gy2;R>y|xhhU4}H&3xiY>MMS`b^W1_!Nt_&JqjaqlQ-PmyqgJ8Yf;_!X zix7gWoDnY5BmlLX=rnnHA%_(&#D~(l-MeoK6qw-+)s;;U=;d%2g*g4`Hw3T;7>`!n z^J1}&n?x@brMSuD?@`dp085G}r#n_9tT{B6?CCu%}dN>5L1T?>mp#wr%%!m8OXq2L!hA*1{az9KZOMpTfjx@Kj$WVwM;} zlzE=Lq0v@A?X7YD0TgON(=Jb{eElkQ&5>CUfua!OhAP@X1Ybw%LXiAAl~lvQDhqx5 ze@7orFijy6JCjJ!k*R?Ps~42zSm}a+Mxg-)7*#a}-i&(yDyn1T_?@$ap<&cIT7Um= z@0X+c^A}*tMT~skG=~<`RRG0((1~)Q60`9X{z{9z5{JsTz-Y1r!V9TXMYi?<j2juNOO!_HalRqWy7eC{SNswU&|fLs)@}D?v?ebXB%y1F|1QHcynR#&=5SF> zD1tny_Cn?Gaj;*6i0dpMS^wTi

|C?g|JCXK||}@p!a+NJKQ8y4Ghb$ap1uXNo>bVq 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 Ze#gHh?0#7UUr7>RFctj)uGo2NLrq3U*{c8m literal 0 HcmV?d00001 diff --git a/fuzz/corpus/rekey/change-key b/fuzz/corpus/rekey/change-key index afd6c653dce770b9f75e3ffbdba29c3bd213a9fa..3d707b70b5eca0005c6fb3877ec01934669d6144 100644 GIT binary patch literal 101 zcmV-r0Gj_a!{el3$G3Guh>-^D#7@}G@{_t}`5QWCUuCAT3dv&eb@ruCP(pzM*x&<` zXFitJx-twP$oShn1>Z1FTifHke=CsMZz!Pq7GTwB&zkR^kbdPQgFk`K!mi_}zx5;z@2YGd z&VAw?+ULSo|8Y;(sHTmuTo4@$M}Q{eAGnhy7w7yd^k`dC3D$Hu7Gt+D5nG!?4T<@w zaa>rLcL8&BeCV=^9+(M)Nv&cc_9yh*FD!Z8g5>D2gsgBfZNX+1Fc1JByUt$USqQ>> z+h{wxOHu2aSU@*kfpKAU4${4R>*hT~g=st-SsRzQxvS7DcN8sxiP zfN&+TlQj{vHcWxOSMO^=;SV2_H_ari-CH0A>qKx;$-mCh8 zSX65u**Z2yMJWumKa&4`5a)}yjxOUK;|v08H8DpZBZ|l9_Ce&k?remA( z?K5}^A!%lLT@}Be=Vhg+a)#;XOah=21=2F$uU{T!tvftwHz|o-rBc<4cMp6bHFVzc z$2pt;b}ElF#TK?K8k8E}M}0@Yn80IKH@N*Ps)T;mfepU9NH7927S9H}Z2jTp@?|ka zs0Pzb5;uwPkge*3`+SW6+-+}o+Qs->->oevJLd495BgA}M_Lp{V!7%4lHvVCBz6zn13G!{Y2| z6|uw};!{#mua$lHP7j1_ts1Bgaasm@42`ufp% zxIC)6(LwnAQoL0EjR3OK_O>vCWRbwuA)o-tE`v(2K0F%YkTWloBYh}*Xuis;{qi&0 zNiR`ds+XnrLT0BaS_wKfNNAlG&4z^7hF6ICo|W;uQ9Z^%<>jOzwY8wf@gN~{2hd-= z(XMH2@+qpHi){yb%mO5)9N|^{B|e{yy?Oj=X{Xqh-z~1FU-J;AOVIaf@E=GpzHU~= zpc)#JUx{enj()V$QWPkliIkkau3Wv~gFxA^cDXkd1-9jWsc-as#bZ=FI~WRH{`}->pT93#?3NX~4C)VL?C1bw zl-FBQ7Ud%uaC?f`2;FGa1nT^`4*v!3)YEz4qA`bmH7J*_*nTI=0@U?4Lh3@DZxgAh zvvdo{jCBP(clxesEZfVq`dkU2%Qvzph@y2P=p0+9VvC07H@Y<1VBARPj@5UT<4G}O zD93>B8vLlC=}V}7KT$K+?Wn~)4*fBT;t~jdL0k|QOHXB4%h{v$8SiFz|02jCs}MgP zQWLJAbvM;(QunX~-WS*2A289KT7qOLqHydUXXlz#+Ut7gWYMp(Q!R`THp!)(*9US+ zS{-N!=>IC@FXKKJE$uI;$=JTa6CrC0CbJkp9D+BM`p!&?Be&pE&$K(1khv!$)(+*wtxC?GMN!09Y>Vvh1XK6=hihePws|! z>ILgtiHeq@5UB5>>}S0h@9sHqGCYe~nRh`oAHF-L+%w7~++1KH^h)0neNFSGW;G$} z3G*+mXD5ct8zov6>C7KEDrxfNmC$J*SSS*X`c83w0t7{*g-bEEMOr%^ydgU&k2Wjj^(*C?O7J8&K?R#H_c%tD5;2 z+u8t_$#&(`+=yyW&M_cU^8v_7F#zUzt?hENA*W+W9amUc?=4J7D(~`zK#L{CFiaF`RCb+Ih zCd%kjT1(FPR+Eu0acIckGF?yj9O&{dOWB=XOPvJ?jr1KJ1h@Z{GuL8XP5cG7ZnoYU z2ee6x&SyZ2zB5CWO{Um4Mb}C)X#oHk6YO)e{0G2OgRa{Vk z#MrVs-fLqtM+lff0+x~f>9h#x%aD_`Ll7U{TPL9cm&!lu2sYMznB@lzOiQXn=Z~d&01xYk9_%7{U3sj z7w4lB3lU4cM_~N?G19?}XIQh2!Lh9FtkqgxL4sEDzMx0~a<8Rs6zib6`d|J9MpnApQhv-!Mmj;Wa{sEA$f-cL<%E_ik3O={xF)iu8PRT@{Dv3M zND<+u{Tf?B{^~V0-!L5YPUqR~xK8lv$|t&*JXceZYiWeWJ&Ff%6~9`o5aU~G+Uk+#esnth`cY=c+n3z4T16&b?0TXkrEF!^Ig~(-q=pS_R;jR2J0KfnM diff --git a/fuzz/corpus/rekey/cipher-aegis b/fuzz/corpus/rekey/cipher-aegis index f51592e..1b16ec2 100644 --- a/fuzz/corpus/rekey/cipher-aegis +++ b/fuzz/corpus/rekey/cipher-aegis @@ -1 +1 @@ -JeEã<‹uéκm¡/ò·7¸8ºjîr#ãÅ¥óžÁÌzÝ‹šîH¢½’JñáO‡/ƒ©Ö¢8¿�m÷“h   \ No newline at end of file +4§8ëëÑÓ y°bC·|į+æêž¯wë¥� Ðs^3…  ˜§CNÀB%j…x'ÂqK¿ø°ŽTÇ¡lµ±ÄÒ$I}ü/mqUô€`û‰‹·Ô%‡Z‘—e&g¡1WÜ^sZ¦@� \ No newline at end of file diff --git a/fuzz/corpus/rekey/cipher-aes128 b/fuzz/corpus/rekey/cipher-aes128 index b9799f545e6ede9b691805f9e007fed456b58780..e443a505a2e3dc8774eecce80787a6e43dddfe2f 100644 GIT binary patch literal 249 zcmV-#w%xC1S@q+C1#(Os^JTz)kntiE*{1q6UHPc(y@|vEs z>Q%EKHe^zCsf(vjyan zwVa}aFo4;|`H~ORJ1cxRJa(zz9vqlWah0%dD literal 1137 zcmV-%1djWFPKyhy{ORN!D8E1_D*MIr`5xly6uPGO0XB_V6|4afi4cmXb4djT{=V+! zEdO963Ax8&GC^W=I17;pe?}qv!knQ`^IW~s_sNF6Nyg`Z4LP5*I%;UBbHX>o!zUwZo!`Z;Z+feYN{f-X!w zCiEnq08W>VTa~S~fhXN6Xy9sX$1IH7OvNvipFSVUNXc6$HD+!RedFJW9T`+^v&TfE zgv&vVKGg%=s3?BL+>1u7=(R2y*ouvq`c7YrfY}mw#-OnIpo~dthcJjt2YfB}I>$~O zJiHuBR2USS1-M@xai&=dY=9S9EHR7;prDT~f&C$H4uGInipcK*f~Wlu-C!n~R8x+L zbd^%Y?GH+yCX3PxPt2uHC6Oo=5jT_xXp5g+;>BnR01$C zM|X|S%kvyz{R1DY>xZB1>A{sZ?W9p7J*KoE5?$v#7GS+_uG?X*Gijrgb-en-nD2;- zMq#6A1h1T-r#;00%B1#)?Nn@(f3X*o8=tOY!rBzkrQO4U65Rs;4V;jkCapHSz_O7e zyqLp~Ne7=l1ax9#i?%X1{;t%cIQ1-V@Q($Z5Qk03i||yFPely)Go6{c6xtHJT;XOJ zmwr5L9Z~1)aYydZAKC8zZ>D-|&f@(_#-`T%DeSH-d$H_3_Io~3^jNBr!fRNU1`1klXx>vN333rbc}44|H?2yrU5C`lvqRJO zb^3_w0QaBQMK<+#gguV`H2u=8i|6w*Wos{9;7B@7NaQN?)dJRd6;TGyCXuO9uyfGd zBZCg8R6~Vn?(iExI?!`0XnMo%cxbXN0RQmQoq%-p-WK6cCPWBg{Q+LCq%w>|8r1vB zK{wazE{(H-g9BUjKcWKt`>_5LV04+2P7&Rtk`PQ`@t?Lod ziCZNvQ?X`q{epcO3TMC29R8=0Vj-qxkDbc@b7yy&PWzzokBQ%=? z?9iYMo3_(aHmy^nfa*ktz0>uB5%_i#9xuqP-|ZuFp*0f*duKy9zeC2VjGAMq8*%P% DWkNu& diff --git a/fuzz/corpus/rekey/cipher-aes256 b/fuzz/corpus/rekey/cipher-aes256 index 3f85d74ac1849650672d7cfbe3a6dc3c56b96659..295ef7c024597880802e269becd5dcf2fc6bb167 100644 GIT binary patch literal 397 zcmV;80doGXr5RCQTO!lI9x*2$nPh`+Isn361L&9>HwKiq&^P{Zc9!D5UwxCk-Q`1o zupB72S46>*1A(}-J3Yt7!~jLK6F6`n$=tr=toH{07UKM(VW?|a(l?Kv{3iYVm@pnh zn2~rJj@>R``>BAo6zov}rnWTni>lhZDO{!JKzvtelC(v?mc8@(}LRn5t)uvob@(ws4gBm1UG+pJcmWcp&d z|M&hBM-1Un>oRjWc~!Z5Go#hY_dtcwz+Hz3lt$fx?nzkSlbg;wj zZbzg2zI}A;*{>55Nq9FCP}i2q-}@jE&yZ`5)N>SHkUt}s{!zd#3Mr1ApxK)7VWBku rw*i#e%>zY6US-$%X}s+GVfQx6|NEBnD1<6=G;2yP;@MJy`o?Pcb0*4& literal 545 zcmV++0^a?1x=m4WvX&kQ6AUoAJD+UT9|zgEobRFq%DA;#yJ3%gkIpTNihdiC{NUO3 zFAH+YnNVyQwR+7r=TCze3*R2imyf0hP7U2jjcng~kEQiHOwZC*pkW#{lX>!UKAc=U zl^piGjaQ)--!LsqVGqUO$h!=n_$AXy8W;yL4Rn%Z+BCK}3u7j|O$2XBjrv^I9+{|TFzQ&$@ch- z+9Pt=+WHN>c9r|}a#`?c!CJzRB$gEV>D`pWXBX+qw%hor@i^xNu2CTAX=F?l7rEOv zfYw~44qr>=4=x6;7@wEqo5vy%iDniu%*aj#QZ2u3xjc>hb7r$FYS54>vv_PukHx87 j;)ICCK_>i}xZ9$ytd}~(aR2Up;{rZ;B|rN6Ulo2=p%DuR diff --git a/fuzz/corpus/rekey/cipher-ascon128 b/fuzz/corpus/rekey/cipher-ascon128 index 58f37f7..28c3873 100644 --- a/fuzz/corpus/rekey/cipher-ascon128 +++ b/fuzz/corpus/rekey/cipher-ascon128 @@ -1 +1,2 @@ -+ÓsÒȽ]™% ¡:œ�<ÔÀt±e‹’5L~æˆõçñ�ǘJc.2Ô´r±�%h(×¥š»&‡T;zŒ¯¶Ð Àœ ±‚'ìD¬,XU…­ˆ+oÖŠ‘ž¬Áçß}$µ\vò»OBæ}­áý÷ÚTW, óÝ \ No newline at end of file +¨ÿ¾UQ‘Øc5E¡¢,ÿ“{ ¯Vñ Àì.Å#X9à¼Ç_þþé”0”Æ,øõ éhb›çÒÆ/6­P:ÔÉ^QÃÈ¡#¤+¶W]ϹxœbŽ2,ïýœLY>fç[ðüØš oÂ3È îï±ÊhŒ¹ÒRŸ«ž¯šœŸDÑ%û +tÇE>ê½ÎS7pžƒ�jPü±6•b«‘È0øƒ‚Þl÷·´ïW#Â�$53“ÁÀHäÀ-Ú”9½º7a¦}6°c½ÁýW}�àŸŽNû}ÿüŸ”DeHödžzæ�ߟâM!;Wá÷™1R櫜D�‘Ú-(¯Ú!~p ä”@^«W?÷dɲ“®ù¤Tä�ƒGÿlçØFt§Áp°|î‰UÅ èuˆ”G;¨p›@lás¨=îÎ]œ±lÃ6(À–<;qpÒrµÄ¾þ™Â5ý÷C °ö’aZ]$çÂ|íÄ@øˆì¦ùÏ€œ´H“0¦äw�wf»>R›ÃFàP,Ë~àk|l„€É.܈�Pb1ñK B’Ñ`X„ivår!è½A�ƒäUO@t‚ÆR 2Ö·Á£sd �|0âTÌ`!º–gŸõuKyuq™YÜwz 3ëù‰F+ƒ¤$†eq…èòÁ�¥�ÖËñš�¨þ»»„†q›E'º8ìñS‡9´5±ó>ÂTËyr}0†ìÏ\páŸÎ甘,7¹­S¶au~_™½÷Ö‘¨nŽî”«™vdõÖg>ÜÝ~Œ­2ë¼ò‡¬_Æ#c© '…T¶‰`×÷™¨àè�ÍÝ'— ¼_© hÿxw'¾Ürpcù1¯‘Òn“*{쫌ƒm¤¯ékm'ÁH” \ No newline at end of file diff --git a/fuzz/corpus/rekey/cipher-chacha20 b/fuzz/corpus/rekey/cipher-chacha20 index 19b8b300d05f016f412f4ce415200cce026de733..a639b68f52d02302cd57f03d2894c2530b37bc2a 100644 GIT binary patch literal 434 zcmV;j0Zsl6UCMmJ+X-snV|0-Ef4|${w)W{0v3l#ca2=j=Wurs1o+NXbBc*NX1eBx^N4q zt8bbKBuH+bn2ofnA>f3Jg0BjUCgPLz!U0{fIUL%WQz&k|u4EVYwVe-PS60}0m!Zve zQ_?VV5WC;p-ASuz-tg;N&}k?ou<7dI>Rp<6$jSmv*1Yyfm9#{t}IP;%*3#D+l;t$UCGf;Q`;fB~GaZV3E_=a8;aO zkQfy_T$sSC9APmkn0)6C7LKF)10B7GrG)njE!Z&J&=T%=+$G1u9V}%%V`Io8`;4Z- zH0;;Gd~4$aDDH10tlHzrP+{|OF)x&!f@pJ_1S`sE-|f#$Qg0D&;Q$2$C4oW8|DT$Z cG~DRFP3l$2mGo^w94tht@R@J=zxn$3jaRciDXK47H-Xx^3CE|7a``V@Eb^I66vF@GyzQ@&%C72x5OD8n!x8Y6|g{ zl5f=agZL_z*Es!^TB+Y0p9jhkyrtQ zhVnw0u=2&H%eJbf#A5bxjF~)IMo|(yZ26}e&dmfGmMgMtVlq>Ruqs@9!K`z@Evr*y zk_e*>7g}{3k0^M2og68F>vo|1gMSKD1-u$H)`G9_;zpFYTq8z z+O2@V4^0ziMZdgJcY6qKSO?aWP){CB!k6mZ<>LfF)0;Tvft?Cl5ck!uxLr`yTzW>) zw^#+|#R#A0>=1V4d0{nXV=`uc9iNr*`?vnB$K%orB>6^~>g;d$_6@1dJAh}xED~U8 z6JzN9!&1IaDvZ+cqt@yCzxGQ;7nH`Y^&I~|YU;SM1jCF5uJ(M_;m+_xRdeCW1$%?q z!+PYGh_kfjO{M?j6%Sm;bK-Q6cXdy%q<+K7v)OpqKtDn4Bv8O$2XDN zXyi;+-+;p^dQ~YWo>oSXOBd3;el$;|0{d;bYU4YQmzf)T6ao2FmjCB-6po`tZA95Z zTF7JGLL!KDGoOw%!OOVCIl8(;X_mIsQsJ%~A5)b($Ywur#IVk7a9htnkU(@+xv8ar z<8%!>ddAV|l*domq_2`pTOHVr1hdTzxe;Iplo14fHZ&zi>ZSUyF{URpnKlfy(XPV> zjs=7&QFYe44NCmlrUU{q+!0RcTl+(D$~DqgWfV^-kcLYTcNm$gq0N*i5_FE`g6$R1 z184jRaHkA6Z<;X>?2LIXO*X!kC)bMzRtjM@_9#@Bg9MMj@iTrfls&H%M(Pq#n4vDC zE9Sb(y$q<}+k!CHwG8k=OaI2YZ`g19#%GxJD_QQoVq5OTwjS{;a zF$vl%gh24k3a9t+_|l_qT7M!!FKX6Ytz4~TL4NZ5E)z{@<137yzvw^m92BqE3FldE zE=H~|fwlaEZbH4-PrSx}TCxZWxa#gVN*KbSb2kaQ>||oo>o{caoLIe#qfgX#hAj&x zj9j0UI+Yih=Y@%Ss4>nuE`;<_+5?fI=`x@n%-7(rHOFB=3hYDgz^LJHxjAk(7 diff --git a/fuzz/corpus/rekey/cipher-rc4 b/fuzz/corpus/rekey/cipher-rc4 deleted file mode 100644 index 267f5d8..0000000 --- a/fuzz/corpus/rekey/cipher-rc4 +++ /dev/null @@ -1,3 +0,0 @@ -!¶Ó§âq¡+>pÆHÂ…ÿ€§‘á¦:ª-þ�Å9‹'½²ÂÁ–Œ/T!‡Ê³cüˆ�Þ`xó·(€Q6¶#ך©–ºe@�–"ž9C`¯Ap2­Vi­m2’T£Ó4E¡!#œÃTMÍ�‡dr«¸#\dV¦¿g:µZ¥¨\P¡4×Õ¶"€ïýíÍz¬eÅ-šg�–¥é:5Úo-ÆMºäŒ¬ê÷†™�OWzñ�6ºÐÁ¬ùÃa(g²Ûˆ% º UI›Gü|ãJ²¥ÂÙQð¹nšÔe)¥Ù0Øa•�ð=v?Æúd¤¡ |ÞÏ-ÛLV¿rÌnhgšl÷¾ð{b–�¨Ci*hwM%©—SfˆìPêw±Ât¦°gŽw�…Æ´$"rfñ #õÌö¸2·ö;§> ­ÛX+O¬[i"I1Ѷ|1óh!åEOp†î�¬FeƒúB×Ú…làe Œf©©»ØTfÓ\Wñ.š²ÒhLü¹¹È@ßA׊ô1ð{AÁ©­ÌQNȧ‡zUòâ#/ -0'¾Û¥�oû¿£æÁh:à/¯Q +ŠNd‰š7ñ%{_•J¿ò>ߺ]¬eÉÙˆ4ñç‰æ™ñNVz?�áÑÜæö1ÅÌ&Ù?1è#úšâ9jžJ·9ëR§V|»9ÚÓ¦Š}þÆIFdGN¡Ì4妰g¸«AT&½‡Ø‡Kœ�ÖFGZÔ(«'V‡Á­Vソ�†XJ]Ñ#),ð^FïuGs§ zKï~ܬ\…´Øß«£Ö¦ZÌ!^‘@&'V4G]…nÿD‘ÅN D@ož,‚œÉ!­‡òhÆÇ/Õæå+<�oÂE‹ ßöVÓìÐ-)Rã -ªèü(‹¨®xŸ@Á(a§Wè 4tv2�ž=ƒä¯�än(™èN¥XŠª­+ìêü‹æYZ^}g}±¿5“‡s/~.ÐCƌΕÆÓ¸¯ÈtzÊ€TNÞ�˺�Öu»k<Ý‹_:w=‚®xê¬5³IÚ˜‡‰�—²Þ´é�ZÍkŠëp‡ \ No newline at end of file diff --git a/fuzz/corpus/rekey/cipher-sqlcipher b/fuzz/corpus/rekey/cipher-sqlcipher new file mode 100644 index 0000000..bc3e212 --- /dev/null +++ b/fuzz/corpus/rekey/cipher-sqlcipher @@ -0,0 +1 @@ +ˆ�€ªÑã©&”îGטðY„üJU&É¹ÍæC¬Í›"õ›,Än HFãCzD@ØÚ¨ì·Õ^ïàšQºi(°¼’Þò�(çGðxYƒªÔ%E;ݵu«ûÂ>x†ÕR�),¯5"¾œ \ No newline at end of file diff --git a/fuzz/corpus/rekey/decrypt b/fuzz/corpus/rekey/decrypt index 4569bc0..5171acc 100644 --- a/fuzz/corpus/rekey/decrypt +++ b/fuzz/corpus/rekey/decrypt @@ -1 +1,2 @@ -ÿäüÖ»æÛWÌ|\ S›.nøŒJ²l.?> ßý—¢‡6™ö™ÈK­RþÏÝùKo%Ï�¾Ã…¡”R"Ú2ˆt3œA‚çõV|÷Ö;oöQݫ䜹ºt1`}Æ· ¡Oi÷G¯¯ \ No newline at end of file +î ³ &u3èŠç‡õj +œ,Ò(•ÏT“Jç"IG:ð2åG1¬»‹�ÍJÂf&Q8»;c¨ßL­ª"Ãlíï|òJÛ&/Ùqv:š™@(2ô/-øG¬EÐäs9�« Þ \ No newline at end of file diff --git a/fuzz/corpus/rekey/legacy-set b/fuzz/corpus/rekey/legacy-set deleted file mode 100644 index 45845ec5a292a8a8778e0e31880e805626ced40f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212 zcmV;_04x88qLFU_w^C6m`gawFUX+i5wYK&^g0u20y-f7DRBD@3@?}m_pQVRr6R;qLX41N>?x0_w6{wmmMdu-+nRqaqby*^xfqi O;mvf`)y*2DXza!+?Q87- diff --git a/fuzz/corpus/rekey/many-ops-before b/fuzz/corpus/rekey/many-ops-before index 051d62fd9146bf91dfd0a69bfd0c32a4b39ffcb3..b03ef39dfad4135d47fb245129a3f86f77293fc9 100644 GIT binary patch literal 5318 zcmV;%6glgyN}T|A-!ULOn|W}8MmGJbJF4GP0z0B&w8S(!)K}AX_4UuQRY{nzo;*FN zDlr+V7Bc zxoWWI*2)2#M#x}CPT=#KTtaP@b zoNMUdN&{Cygp=DKRfNg~n<^C%y$NV&fY2mxr%c|*;NtxMp!?RZ1bKWoJI}*8 zapUIME$oNR7#HMfZ8eaa6ij}MW(kz-IOn1gYsjQQr7`Z(di{w<{RG7DSeOM4&b_xA zwjun_6;+y@*>7lxot0?AcT>lDMsyxS!BHbI*w>%#2l^rkAy`YeLFpGtm>fRwgu+_J4HRFptg zsWbhfZs#Jm-nKDX!SqizC8H(njrj>|duKz-h?h~^WkNBLyk~=KfKA6g9!1!>KY+dK zh*T`v>F_AXx=s@DVM5$iv7NV>uf%`@l@uF z3%HMW@>#%FQ8gKX+x3u(Brx>vxR*=VcU;qTJebcrv5XIg)Pszh4YrRSuif)IgMGo% zz{R2W9Ro~=J$`;k7$n6^12F=zC^tdar!-xj7%2}zrD_pBA}ve2Gm+dw&G`ET$b}7r z!8${`{Jsb5-ao(dzo3gDyG|5nH%!E%GNc~rFz7&$Idvm96=qam>>7z36v_0PY zYbOk-@`I)H%m5Ta@#rwU@T2yPD{fjHan`WCNE<-~bs=?__`($L1lH78^zQKtg#KmB27$E;4;LOX7wnva=gE~Fi0iO126n1UmKF% z7C!v5PXiZ{s8BNf9{Or9ZZYj^z&gxTJlp=+Rt&Dh5>{-=0KFK?vMu}(nrj)Ply$|x zx1~5==P#3?GbY6Qb}P+OIgl&VULP*e45MiN2MSPmfgMktH@~RgMxK*S#Dq!VfV#>w zS8CZByyu2dH3An@-I1&8iZEX&%|ThNJ;2*yg!A3KRmVb>lq~S#)1!WzpQvO}#fN2D zokdrB9xvGCkcst*&ePFl!Pwj*G307+a5I8}KpK|XBZl6=;|B8ZC38snp|6N@G ze{AH}4!xuPBNhYB1@m38Vl&c#3vCc8t`>=vuU8^xtG`nbnn`XcH^pEQ0E=m9b-Vn+ zQI&v_;FhgjfWE{6ng{L7ItJhhrgDk`m7ul0IWC~U{5|oS7!Um(WYW_O^sMzQ_^!G( ziP)yYgC_u*zvbnm!iMyZO>}IO_xe+q$r}sx%Uo?xB$cXlraNZ!p0F#fPIU<4x!Y|B z9ktaxjP2fLVD#A9rGio%zj4#*38_wCEFP}>(RN5*U&g%7#-vawor8A|RrfleA?Jbd zFs%3>4BpQ;VtM=g$MnD#+_^d*5N+M0Me>b#M=AV;Hp(;mpE1pB*~HL8n}gh1jLJl< z@GO5fU~^=6KTX&3uBnUdwVy-nJs172Qpe1zM8!Do)vQCGu!DF}QLo>;X1uG6S;XnN zv6Jw$)nfbEK^(s%kKH-opGlu@CTQV`ztAU&LjIRsZ@TkJ`QN9rDop6yz=`{(kgRuK z5V;}fY9E9QN7*avQN?k~k9(~n_c|8X$;Noe1e8ooi9ugju-d@kpsXPr3^au#U;&Ps z;N4MDa(xRbvlKIkM1A zNdVqCINX3d1hkSY=rc#yB8*%v^V<>=%j)M(;=lBf4W9}<{6XyxvkFptYICdUIBWc|JHZsfmpDW@}t(@8hZ5 zTmM`ex;pK6FAiq%&sdH7meCR9C;S)I`N?89DJx0r!A74IlWjh!Cn3*mMTUfKQEeiC z!>RE~^QB=2;1XbV;!zcUYFTHY?(IIoAP(6fKN5f}#$}~!<^*SQ%{!DMvCBZCv*s`B zo^6HD@`2#V`5^)lZD7AKmFAR-`19!uS%Iy9&+KqQP568ttVI^&J|+uYsZ7^bw&waL z+4oglJ;}{S6P$XmP*=tJN`Ru`S+bxR`YK!-6Z|m2AcB0fd^2J!er8>52A9!7E3}6~ zeoYv=I68EPBNeFJeOC$eDpX`O;(^#tHF|QY+BFOU#)&>U3*JnPY<~W( z-Z9;*J^I*=R#p1YnAW$HH=={^vKf`r(5h~Uf`6kTIGwK{BAb6$S`U{vy0@?30Ga{7 zKpfHxgBBrEB(&D9E0*J&Di?vY-4NU}@9kU=O4Af3Z1@iH(=j?ocAdE#K^FDf8W`mr zRci%}@g)XLX=@q1brI<@6GB6`qs|HJ4=z;=8V5sXdc~H&x7Cb0+~qG=f-<=km>rrE z6}2DNHnfi8-Jy0UdQ*{$w?4AGT3PLv71QU@%iizI)oFSUEs)P4!G7*Rdtdb$$2lmQ z=>PWm=ek%G&qyb%=sbwEr3)xeKZ+d-id+Z(q5h6tEE5Oq7Uz~NBb0m&wZcM2~PeJ>Lt@&L+iMIFs z2~7T2r#=NG#T{rmMFr)Ec6p0j_a3E+zDr@Kz=j$%V;%}g?0rhW3LSmPxk!S&C9d`& z>z8Hh2u1xeQB32^BOxNlml4~A@(Eu+RMIM9ywVQZG5##&59PlCWuprSWRJPLVg}qa za+c*`t-3%eMSAef(^9zjG~3DnH??2w3Q`$i0G_UAn533l-dlc2oK9tU6#`@*{P|u z9JFP3UQP$8Hq$Du!po}O_HDZlHp#|;oThemv@dFk*9t>q%zCCRZ)7^`2bfJ!quZldXw~L@+9ASi-fA#&HAOR^4l~n+Af0LSV zK)$R~qTdkty4EVv=(+6}aSmDOgQWQ{*ecINJP(U1{Hp_<4aKbkJn=8g-m6_0-@YPJ z-XtYE+S?REYC8=X#HQ&!an6@5l7x$Tb^o)4`1MJn<@QXVhPGQb(_#lE_j1dWiCZ_5 zaYO0RMYqt;^3wlh?&17Gr#fFYW!(0W;b}Ck(Bk(|$Qh5I}JtTK3j0f6cLYZLWXgOOFt4dzI%u{2h;%6Lo z=wl5mqtiIYBHA3f##CjBAy=_klEsO~w`uEy20^$MHszp$L@+ zd%2U7>l63k(rsS;@>i>^`-Ekx zd3a+!PUZkPVkM?4>u3-cHo|i92cr~LN*1}a%A2ifgzOILqL;LOL9@H!lsJ(4Xo9il zBUGwS=U*kjpmd6lBPYvq556J12NqwfLkn9E8eflnP+&y@siu4s3mLN$`rTL(iN@`x zTwAZxfde_cU0Y?qh~0^R#}$Y}`FVtk!%V=e3H_yj^lugMGQ4>N$Jz;GZq&CW=&KOr z8d;ZM$=q8xuhCir$<0VIH`Gj+7grp~E z=X1csCLw8N%$lnGr(Su+#z3Nd<^;Z)o)w`0qs!9gzcvR(bWe&Hue48w&=+n6gyZWu z%wF;WNbo>}9j-n!-E4BCr_GiIqbPv!2cH6~wPZ*R>6_u|bcO->dfAtGh|i3eU(Z7N zICYH-*+o)?^X+s3hcvL$FwG(`SyQf`W&s81#`KIv^u}Cos<1Xb|HW23DG*k|sVY|P zhL^6vStk{aVGQBM{%|0&wA=oGX`gqim+5l z4A~R?XAqBtYPH$@*>|rW{634JZ$38PB2Z<^Wij!m;L^3%LB9FO&EU7PH*~<&K@w@T zn~iPN6{}V^YoPokOtcu4#1HMlBA|-qdfTyO;^{oSu{QJ8)j!PNext!O*Iw??$_0e3 zU6hawq%O-AAu4&+9jG5CAI&j%@iCD(6#3MLfg%KLKyRnib?>L)>xKA%o@=@h6#->d zOK~*>(BUy+LCb76?+GGSlAIbf5oYK zif4CGU10x)qVb$~bxo>-W`-p{|38+^kqmo@eox+)@&CE!Ck2Nf2{KE_o>Q&G)$x{& z2F!%cbwQ^zEO#uw@p?-w{-X*u>wU>xGc3RVAVao0Jnhk?ryJ%~sgaqgFeG9QW6to7 zc42u1*_B$K{2w+OpzO_03@ZdCmqE7Ghv9=$)CRsU47eUUXe!|4xK-ON$+G6V-R@%Z zAp<25xy_A7h2%Lct;F^Ic9pTcMMuiZGQ~DNe|VUEB-2xSiGlvSanptxS@H`Pb)LC= zaxMBwHr*kF*52Lx1?yfDnkCoC%prBNByo9H8r zTglMe4q$sbp7~^lC<nj3WwlYwrJ zQV{~oRZ>Mh^eLS>x)#S9a`Ss$ zdm24#JZBodElqUfroSzMK%9J?F%q%YNq^cI4Qix9OIUptIhp1Acx|^wo-rZX#$O5z z#%T3;Y@#x?8H!ciDI>`Y{ieQdNLN;EAkIsZRhq? zl+|x-O4`$x;G+jB!jPF*z#p}bt0`loCyP3SlJT7rbdAF9@25<65t%n9ZA611ihgTiS|A*0aHnRsKk>_ak%h5EI(YhH%v^AT$Pz$u;k(g9nA4==h1vo(y zUNTxIf>v(U=o>hyNCn-3h*KL`0nfwdrp+YnTOp@9i;7{FQa5wxX`-fJD9O|shnkGq zgZ@}v=oVa)KlaDur(mqpD+g0Jpug0*{iGlRP$xV+ss4%Z798;9_K@h4#SC_MtGfWF YO^KEILdBm}8pO4S>VRa~wcsz`bilxN3jhEB literal 11460 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 literal 545 zcmV++0^a>6nb9lm7c3daNxrfUvn6>A(~(rx`g_SVSR7sql=rp;-e7B&yzCYA=5lLu zkb-+sO*7&KUipX_gsb`jg&b?G6|@LJ3qb{P6d5b57ss~kfM>y<|2R~!PiSg`1-Egm zEP4i+ndzDzL_tGx3S;EW{a>h8p&b(y7*J3hk5U2GQBf3qmjVLPrBIvR)rd{5M4T#M z>G7;`XL`2oY5=?kF=&c1A3!3FLYI%E+=I zE}tcLw1J#3Fet42@NbTnkY<~lGKI@>Xza9rn|*`JK3K1}{BtAkL4rqe`m$|&K?&)J jav1kh507I1^Zu)e5oqR)d~_-PDX*@$@>?bxf@b-MupI#> diff --git a/fuzz/corpus/rekey/ops-after-present b/fuzz/corpus/rekey/ops-after-present index 89fe11c72c8dbc3535e8b5f25b0b84a841adddf8..d016eeb379f38530df09930d7930e7afd206491b 100644 GIT binary patch literal 138 zcmV;50CoRD!P}&JzK}47)NMXs|(z3Ompv^N0Ise}vG{776cuqrv5+!ZXxG zZ#&7!`s`vm$fB*mh literal 582 zcmV-M0=fP0(5oK$>Mapxg&|E(R?O8stfA}Bx!n+&S(vR;Uv{EHTY9UKJkGi3_t-&a z4CCtt;^UD{0Z|a#M!c25<_VbhyW*dF{A78Bo~uk8B};!iWZjb7`goS41EkJJ?D=#F zEz2(wYMCjD6J^}g8Kz8XEoHzO$ZVD#VB?T*Y z58?L~z^kt2?HE$IFL`$tZhT;;u^dpyR{gxU?5-fb66L>-$YIiWwAiCwnTHXLas{_7 zKNk9pMSUGke&u}=N6uF!d*+6uN-rW8LL27qJzmSt3a0X{5#;+{69DCESPTD;P@BaW znap}4eJFTWY>h&ooP`=q8{rL3IFvFrpuVm07#O)^&Gr()-4DJ+yY#Fs1URN38o?ZDybDP`#KpQO<_l}9c9BnTsP z^^eX!IZMP&DJy_2@w5Dj@$dZO+uxD+GHxTzDbG4!5?TLAM*(k5CP1>s@=p?7R0eQ! zffVqb;;1XAh1d959>ZMIe^EmKkGbb$)S&0Y^?pQ|*|pH;lm}f_mMY9~pnP?KGI%E= dX8@dD{;ahZ-%tOD!JY^(PHr}`7E-FHv literal 286 zcmV+(0pb4J-Yk0Pawq5hH`;Q= zDb~H&4hyb@Og=g~>1$g?+hts&oi`lR4tw;~tD3T#rxH5tHuIGLCB?%X!6@Qh5+4<% z$z7N(41zKx?e9!OZQDz7-RO9V=s`il^)NrQ;6f)eq8bDOJ)S-|QD3XFA95~}6+DM~%=PA4c#)iIC k)tCCj6onsL+L-!bNG8mzD@t?AL}GciE4_n>oM|hQ<}J>RGynhq diff --git a/fuzz/corpus/shared_cache/all-siblings-correct-key b/fuzz/corpus/shared_cache/all-siblings-correct-key index b4ecc8caabe615815fe4f52a0624dadad30fd3e4..471ffcdb24d002f2d4160ab57f382479768391b9 100644 GIT binary patch literal 64 zcmV-G0Kfmjbq3(i_rezJ;O_jzC`J!aPjB?yWbrISU56TMiU}5qBM=-jO-Y9(;JR6B WW-JC6RsoLV5l5xjM_lIM$9Mqw799=% literal 323 zcmV-J0lfYOsv6$Z1SjT9H{h;Fa7_-qTQB7Oq8(9l>CUF=!jOn~;t&Qyy#p*6r<)7? z0t|=Sv%YRpl1809M3-NIHq3Aex+@&l2S}Rcs3o?D4~u=FB#5s5ar&R_n75^Z=q22N zmmhik$;L(?e3+r6GD>-o6&F|m7BRP3#ZI+t*|p?Z5?1ddfWa`c+^+rYAIBd<5z+et zIoY8+`~hNDluKUJep^lwK<3L6M3)G5h_eSO!{HIB%aDY(2Nj6e|aUS+%p+0h8RToWpg`dLknc6U7?j72hCZ*^{0b0& zBCD&BfMWB*>kvZ6hYTp~G+2a5vq+|ser46~)p65{mXTY1+8@X}68RM9{N0L|52*Y= z_o)sK`{{=u{yB?>GS@bhYur9lKl#68q4Z_m0|Q3$&lXOAuB+&aFI%^UBkf&cV?10G zHw%uCRw(X1BgYTx(xHaN5U9@tDNjZ_@<0f?25)|;+6otNhk_*X06|N%5~;t}{vg15 zCHLVD+pST;gdDB1o_s^gUWl^bFLD#ru`0n%yz}uEdnB-DoMXi~d_;b+-yh>?#YilaUG)L<2bF zx_S-vLY8!+|@2zS;kT9JoD+9Wg)){}{CO q`{ws*sAn9U9+Ruk$qz`VYm_PKL}p_j7d2mkCT|U=H17!!fyzL1T|c(~ literal 212 zcmV;_04x6!zI)R-gF$bWC-J8j6C|uQDmHn8$!K->#No*->$Y4D{fC_)Q{MBTO$07- zf=JV!g0XNjJI1+CZ7uvE@mxcP2BG>%X35&J2Ilyos|Fg^Cc4+Ek-eyh;r#9PG|mO` zW@oeHVE!Gpt-Bw*NNUFmZ*e@zUU=|>Y)DDy;aS=@87Hqa7e~-B?$n8$?DVQ*f`p%t z5vW}OEp1lu5g46C$Z+eLGU;EdZqhcD`Q100Cp-zn*f4wt9c}2%Nv^PkN`7)q@-E6m Oy+!a?=-x(3*!1x#lWq(^z85^?%t zi1DF6eT+rZ03%-o7rr8!vDUK}C1gGGWzz+!QDyxDv(Bx~aBCWGrkt-!^&NQI$z*v* Vx$fXDlm;miq49HlR>2=|PPwcBr0p&$qZe`H;|E+4Nxs) zy0Fv1iVv26OvLk80jId5oZA%cA+^hvv3!}vtgAT^Ns5NgswE_SMVjCgNudT;y15Z{ zc(36r{!f*vG`<{?$BMEbEf`9Rk}rDmvmw8)NU2jJ+L}o1#a1Z;B5r=TsKJ{|(bw+b z?u-Ko#edY(0H_WcRAcp3qeCdf84s|Yr%CI}gNd=@#_a2RenfUtS3mfl1J`qx{(5+p zr<^FVYjCJGQ#Edro6p9kcMTePfBbvckHZ{Bt)sz<>F*8zl8mOl=@SuDAZwobRoQL- z{$1LmJpyF(5cagZJe7+BWOj9}6{*si$60T3o`p@+Ynwa)D%)c**R5N>SO`@>iGii| za$<%t1Z1RdBfjy#Px97cq7SSYq$5~TmPbwY)SGpm5(vDL@LlMz(b`XfjA0%6?rShX zWPeX#iS>9G6eI@ai{|QcTa+wIaYpq^R*@7yj&Lw#cbJk+Xj?9B3Q$uLjDkDpPL3>P zNL_C$8j0`5G$+LNWUxyeL*}yUNs~q-cP0dfQ~iHJoJnTP}6M^F5w{3k!6ZPdBW=M`VI zazN4DN#{MSNp`xfA=L1-T4Z0idXVC_2G+7Tc!~cel(Nwi7Id~sih99@H*zV|UitFt ziBZKvr=qTA1yfzC`(ggBJelgHOr+FeKnt&IUL4 p7{|oDY*XkcNPp^;a$dq0uyMhnQsv6e_|~L7bC0O-lF)N#ARL!igXH7Jr(O5(=uvRxmQ!Xa81szm+kKzEu{fCg2MGDux z{Rz0bu42@?4IADg&TeWEk>*7khKrmBP8B?gr75miRf&bk*j%}VG_M=nrleS_B0b~XM literal 878 zcmV-!1CjjE-h42lgQe3oVjn$$dZG`iw~$j768rv|N#BytGv z=SkC?##YjAo3GdTmu5inNJ&18-8O7WFqzaz=L5J9UIy|YOm}(u@LO8K>8WbvQ!V7@ zlu};Xj6^fEGy;Ecx158e zO@&6xAwDx5D>=yD^~bY$bP+#OX;TM9DxutgS_HN~<%V7=U*DM3Eu&IJSi!u}G;qQs zn3%N5TRER#*49`a3E+O8=DICZd~Xp!S4?w`x##8R1QzJd&EA8P%#E^w3(?>9(BNJws?j(*Q006HrWjdI*iBvWNSECbHTgwuNB<`ddN064r$G zh(4-e15`NNx_kcNkcrNPVgnDlOxEU3KcM>;CDq^}g=1qC~_% zqUO*%b4M8VHf2;f{0aHzg;yqZCPa=Tn_JXer&)4P^6WANK1ojTK#pxP>ON?g%$!g# EVG#$rivR!s diff --git a/fuzz/corpus/shared_cache/one-sibling-wrong-key b/fuzz/corpus/shared_cache/one-sibling-wrong-key index 75e952609b82bc09ab706aba680dd39e3729dc9b..42266977aebd234fb24f9b2f4401121e26e53dc8 100644 GIT binary patch literal 1581 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 literal 249 zcmVOnw#T|Csw;V zs!OTeFLJ_pEGvb-SWFwWb&sXLmL47JXgs+1Za#7dXtSEx+-b>wZHg=rYUG4Fr+u^L z`z5G<^Uy1Zk8c-8m(Y;?!hf&A2p}!89`@VDJb4$lYh!w^j=QiQ`cj5HIRI;*s>gEl z129^%U;&>Kn9oIZh-~&^P+%x?liYpYs|I=Rj0blYOq_jhZ5*(KB-%5!K0trUv_X6Z diff --git a/fuzz/corpus/wal/checkpoint-full b/fuzz/corpus/wal/checkpoint-full index 709acb6fe5db3b563bb25efb7b630f35d1f81fb3..ae71b50ce088ba15009f585434d8d5d34d378496 100644 GIT binary patch literal 138 zcmV;50CoR|dX4k_$@r!EpFq$x?=Y9Q0GqX>wS<;>LWE>KB?cAllqP$5bJWSuogHb0ww!UuC82d==v^eNtTR<(ZscGe s*9*fCu{y{nEtZ_m=739YGSI<%eaA7ZglVv^SV9|bQ|fps`pDV>de)0a3jhEB literal 286 zcmV+(0pb3wqbsh|Mz$sH*l+1piD@xd;NXFO3|;5EFI!#fZYlvgOYI(88*e^m<^)8C zoWnJ9sPe(6{wJ`SgV?_B`N3+J{R?hf9zQRk8=#F$(dy8{s28V;^8|_wDLlbC|1lh( zekO~qo~>RM9m(~fwds*XpdjzQBWZ_WT1DX|w>G*uWQ&5Nm zF+;7)&m)Vg>>;{l(Os$U!n-R48|pTTVn*f~wvNm^8ynW1CFN?WRwF8~0epnSX=lUk kPF=rigb!e1aFVSd4I30z`{SJK50{7jAs!_F literal 64 zcmV-G0Kfm0I1S;AW##k!uaPWO8w8DM$(;%!y()_8wS%8LLido=21p>^q%r%W#`B`) W&gaXjtAYDhoa-QhH)Q5+3b(gR{v$8| diff --git a/fuzz/corpus/wal/checkpoint-passive b/fuzz/corpus/wal/checkpoint-passive index d2bc0db4baeb78aa2902b751f8ed0117038df04b..e55615dc4003f4060fc49dfe624011e198c327f4 100644 GIT binary patch literal 656 zcmV;B0&o58)A$2#Q1Pr+2LrVjwGfYY=P*cBXCm>IW!VLlBvQfpzSr~ds**+l!A>RS z(qV&5RP|<8$Y!%>3nvZAV!t8X_f84U*CO!>AHBDX8tX}%Uk>%<$|M2WXsj>sa{qDs z>$v3rdY{D_2pj{RN>oTJt`xIZJM~qfSN&6HAaBRJPM$95XG{{{FplrT@nJ@+{fPAa zFlehuG2VHd|k` zEcMt{)cW`qzCaL9T_%d-g)`d-iGO|i>OBam4IWR~`>2X-OWf-Wz+?@4*e{sCBw{9O zahG&^=>`J|^H#1&2dz=-j1P%N3cuEHEnXY+wlr!`DxREq@uvn8P`4Go%VihFTaNzd zz31(Chpw`c)gC^(Ql{n@pYM;^g1(TuIHI%7fhVZkt!lLBCX^4A*yfQ{9}IgwL#Kkv zpA9%c(Nf`SbhRwMusYc7c~0@BPZrhO@9HJ!kav}cehMi#Y{O3~!o|ERmNN2Ha>QEv zk6SjPut)Fm3%rk}sVw{~Hv8?+1HV{O$eNV*o<)5lFa?a2p*jp#_v#Bk`!GURis&0u zk}X1sI^I{ybHw&9bHgiGW4ia;?v2%3s3Cwy8=c3;zEk8T^&K8cMmW75_%G({4 q31Vd)L=0B|E}#0y-07-Z1Zc3g1{4*-|23EgKBu8@uu~vV0xjl70ZP6A literal 804 zcmV+<1Ka$ZN{LD11nHA7s)}1d9tPIyc?1y9qyf5y{EYinD3q6BoReEJrOPn$3FFyA zHbbiy-4_8uf?LWOamM-`2d$}cJ#e{MAqYl;3=kk7>7^<6DXAOw#)E@l9u~Xo3~Z7w zS%XjOR?+|{4`pRl$$4^SG;_blOTiFOE1o15G-vq(xG0xOvkVL%{tQnGf+0_p5y!02 zeZiZs^LxPV?PevOqu4T>pbgBa8_-<#k#!p&!waooVPxxHtKWz{8NP6^Ou{v{o8(@Q z>?*e&pNYSh^PqOt%Y1K*ukIE_WWjca6GXq%fTtapoZWwgXy5||bi&AXN0s)tx0du& z-W`0h0e9URvhj||`sPU7$V_`IX(Lm8;!UQwO-Cx?Rrq*rzf!edl&(9a)RBJLC|?(A z7M8*f=5#n+R-Ilfru}+>UCmakmgg_sISz0^!!kR;wXQ-~ABuZgo>__!V&aiL#`IOZSna z*@JpR!hSvS%O{*#S`Ke70^r%x&B8k-*6;!^C2lriRm>a+X4{*+Fxc(e~wvU{zi}S_p2o)BO z8=R40;x2n%DichXE%^xl>@UIrD%QS}+=@eCKa;2c diff --git a/fuzz/corpus/wal/checkpoint-restart b/fuzz/corpus/wal/checkpoint-restart index 861691c785761b6c4702825a276e3d82b80c4b5e..41839bf2eadcf32fc046c8257dbc5c8e600f4831 100644 GIT binary patch literal 360 zcmV-u0hj)+Ec-Eg?3C0(RXh2qAfUb9hU3c+dWpwj_B)$!`C!aHS&O3=bqaj#@bFfE zd!Ry*g4-kBBq2nzOjkvSE0Xl1*RjRAx5pER3T&ULU+yz>f_eM01~Ad6VC#rEC9Cxb zad>rE?YSUANcdQzTqh;GR3Uuz7L;pH*I!5ZWl0AGY=S! z{pvG(+4Ea~7P6HEgL!T72b*a>ZFAbsl+KrBz}-c)JQ2wHKfIAT5M11M$;-Da#BRMB zbN=ZQaj;9a%G@-@{Ha&bN%XA5d8MTD?#?xZZrkW>1v+0G_pAv3Ht;rW@|S3A;_#5Y zWKO=+UY(t%#(5NgIc0zEYRN7G=Oapcry7+G)T+EC?^ViB5W%jFf_Ef@~ui>4yUiCx#rt GI(s3hbhdK< literal 619 zcmV-x0+judO^;zLrLe*%HskVWYf_%%l|Vz_7iIliS(JsiB56T{4vEVUYBRXO4qH1MQ;}Ebz9w3v zz?lyPZP+LS9eiDjh6E56W5tDQYmn%<|Dt1e9$;VbxA5!T#N%ASDPPglR+0jI{HIUAn|MZABT$RR}Bmqh&ms}zxVm!kQ3)GEV z)B`_8?yLo3Cjl7iO^zLCl{CW>Hq<2X97f+DzgQ0tALnBN7j8KGID`@j&2SPdFSnQz z6nw%gyg5Fr+zHf1v^c0|k0;3nzStg_p@TN0{gVW{XT&cRQ;xlHy;*MUCdwHbeE6n) zb<@EIHc{bTrWWGIS)#Z&7JzlBRT+oxVLMjpVhzz{6YMl2+b(k8`=f2`p(sTH44ZeW zy#@$w#wjnqZ#%9hm|PTlnYQq;p$o~~4`#M#pjCFLL2G0O1^!>dMa{%D|GK=j%rk-H zh1V=Pbe!>gm@-Iw_k{|ZknYp<2su5)fo`r@#de?Qwap$3RRt)LK-r;^A}up z!T!T_9}S077wF&Z{1H$he&UWvT(chL3qe>Z>DI@_u-G^SgV%q@I7_@gsgTqL@XVZz Fee@0PAte9+ diff --git a/fuzz/corpus/wal/checkpoint-truncate b/fuzz/corpus/wal/checkpoint-truncate index 0d0ded20f2f2d13496415c8f4d28dcec8a654151..e7f2bd2bd2868066ebaef6c0fd3bd087cf80a8bb 100644 GIT binary patch literal 1248 zcmV<61RwiIVuAx2VImb}g&f@$}O%IFeC{{zN^` zZuf@FXY30Md}oBmf>;+wf7TRrRF;gNMm}HgmfJz7+Gp7_w&^-8iAfQ)VRJQesqytU z@ke3!r<&0!KN6JG!7-qsUjAeIHoJG8hp$;u^by~%Astt=(qfjB6dF)ZxM@6_nA?NVUV zsRDxX!K7Re|GACMLAE_Sjq^2tL(n9~%I$=cSXsG~C$-f;i9tML&geJbLa<%r*dV6i-Rmy5%D$Qxy zRT&5vcV^fM0LkI$vrPtaokLscOE_CYYn-z1Zm>}Z6sM|agte;pRYr5O(Wb8Zn}O4*ezN8w{`6t)sH4j^{Cm%B5zl18#%#rB$-QOg~O<*!!6i zhLzO#dpeZRS*>8~B9!IH2Sd*d!nOiok_A7qLTHE7xAtqFYtD3GUm{s%{scF=H?xxb zo{kB|?K3t&N4xw3<)9isAL!69NziF<65y>?$>GPUsYAv^VHc$yTsbELYHyk@&N&!v zZwI4!|EZ8YrV2?z)z6mSd2rA4W6KaDN%g?fjs)KFhXj&FlI@1pF#xzqDh^@rxe#Ck z$0t#hpzPWYaHcUX!?(q|El|o4Vrn_^mnV$SkkUESV9eY;gw;>)U3`K*t7N6^W?gi9 zD=o_X!_OuF62!u_T-6%-+F8IUQI}{%h-A67++K612xHJGgg85YzaBrsC%}F1^E60L z#4VZ1GZECGMp~pr)7MIQbk~U(^rq=W_G4cE6nR|-)kH)s)<|NN<)!lK(vlvCW72?1 zdO)Byw-H4vAbv>Ra!aHeyu+GVo&*N4TVJL-f3ibby7pSn`E2?H>Tjs_)Qf0Tpo{kl zMs3cMuXx$j-53HuMHwWqQE5=&Ldrx4mGFmGm+PAu5}?Aa%x_HbdM-mQ9CYlo0P0Sk zD<;l9QlN*4Eq#)+46dI&rXj8)sztVY7i7v~9Pit!3rP`8j9E6g(i>BFf3g$+?TgD( K56mG=XqePH?r{tN literal 471 zcmV;|0Vw_rU@6dG>Cm|2oyu0TW<^up?zrlz;H@KRT)G2KYLhfN;z+UJBRXdD&6 zmIL{KAO(|fQ#I8k2$?bLH-&iKR<`^Xx=7@}0YV61L2jcHeWZhp^wwn5xblo~sbHMJ zQW$j0kfoaS(rC{iOu-L`Sgvv6ATBx0@ZJv3MA%XiJ)@tvA!dO$a;wdT{t_g9E7_0T z?P5kX3jYiCy{1qi!EppRgsYApr=KnKN$tUO>1MgN*XugVSsl2vRAO3&;ZlrdaJB^Z ziM&M$(B6s5*X3+-JuYaYL$!4yJJ|NH1u|s*iK2>PQ8xyG{xD!XL!|7g N!1uqpp`M2vhU?oU?B4(Y diff --git a/fuzz/corpus/wal/cipher-aegis b/fuzz/corpus/wal/cipher-aegis index 8ea709f7d569150da84a9b7d632447372646452d..5455ff7a68ffc7e5af368e244125cde52e880c30 100644 GIT binary patch literal 212 zcmV;_04x8#8Oq))1oFt*AZ*p!^QV?9$XxJZ729m?B&*?|-568wV>_E=32cnbK5Zal z^*Jgx2e~aT7Hi!NXI9;?{PzId{(u)xm{0R()zD+R=2uPKc+Qn`s3q|XoANvZ@dGq| z%;TaBq=|s)0=x0AX~Li)(D&%XP1eeYf%yPNjioU%%t+=grN0T%`4z}7 z{xFmVXt0YG9NC)CRho0L5&6g1+9mI~x*CrmTF-n!%BFa-(UjJMvc+U;L$H?+6Lu7d=QK Ws7bg;>$kP3ka13DllTE#VZ%$p!X8Zk diff --git a/fuzz/corpus/wal/cipher-aes128 b/fuzz/corpus/wal/cipher-aes128 index 292323f318421bd3cbf9e35c467e144be71bc8c2..dffc4f3b76788d4f469a1005a275139ef9a09864 100644 GIT binary patch literal 545 zcmV++0^a@jH83XNrps%Pf;`M5p`yrRFsCS8Stz2Vp@u^eCHNr~!YFV=?B9SZjZCRJ z;s*|1XO;ri+?uPlizpsdAEJcsregJ$Tmd`7yoa{Aru83XBiJO}x%bk*d7S|_KXwyHv>oEwP2kbxt>6SB*%aq+8Nqs5ZTTXC1f<|M~kM78Jg2cD- z2uj;o>8T_>bVH_xG zs3F7)&zegIz2PTAR4$rwaaBb&kZwacgHEfgVeOdg3NvUylBf+#;zLl$Ga|Tfj^ybs jfX6PvBznU2lYn^e9`#3TjXT6GBM!W>0nhrmd&)$~fK3oa literal 360 zcmV-u0hj((#2zM?sczIoI5$SlU|+I}iv`0d;vRe&$c|hj_7zdASfYnzlYJRSC%BEU zNiAohAmKfl=}i%-Gi%X!U$o2%DAod8X#_V;J35TScsGp6IiA<(o=S`Hq@AI5Xu zD2-jBY8|Z|CB4;%7d+x^4wzMRCw-wZg|NzApp)WYyQK7>#FkKjn8b+6j}7f&@u6Q) zVou)tDeNJZ&9MSL_6ZLRK#((=Crwo7^pJiBD?EaAJV!-=eb|Ur+BT{QXJxr(hJ70m34 zi&ZgPzwR<6()2wz;*y|sO<8gm5lMcgNOBf}2Q6e0-`)!``|PSPE~{(RdaIYlBhyps ziAumesIYowx4zjnbRq%D`BwOz^D|I)9oZ&4&9|OH6FUy}3VU2j&p}*hlg`3qopb%d G?yuWJEUv-; diff --git a/fuzz/corpus/wal/cipher-aes256 b/fuzz/corpus/wal/cipher-aes256 index d193f2890da3162251e8efde12810a425aa7b338..8989f91e043294052fcd73747256172466d0c35b 100644 GIT binary patch literal 1322 zcmV+_1=aeU_{B`&Z$jQ$iRBZDbAB(qrAgU&Qg&4#Y9EU9WXRj5-s_nsHHgv577KbdBqgOi z2HCW8nLwY;naa%Y22ZwWP2u4zbEf~|-125n`z6B&IIY=Doe#FEH{q_t(js`0# zyF`6j6IQuRzlnD%_bU4y32qxVJW^*=08(^?>`GHsyVQpJu3^gEzs6 z?~lD)2}(KO?r^1P#5@2*;l(A=YwN9y10No4Mx6k*q4+l{WP;HTm8~!bxHJ zZ&kMHDJCUmevV?iclSpBYgD7{buae*?m3fHLR?|)KoxnXzPzu_i`zmFB*(n;a z*`V~}a0mHIdmKb0=Q0_GSmZs3j5`WnD}RuP+(|kjQ+8J9(YXogDR8OkljXbfc>XXj z_{ocq38#8z;KVtw@{F+u*?eJ*e#|dDwYdDGld;fjV&}P|Argbsk+ncifu^l_h`X&@ z&Zux5O3puax7%emIu?!cwh3FO+t0^<(whL1E+_-M$TBp}?V#8Oh$7}6ploxKYg!zk#RoXc(4^F=+5FvVgjk(aPg71>xMupD9jUjo$YuVp_ne=oag@P!Sqhi_oroy zS{3!I(u?Lr;}LelHMR-i?KSF+!Y9vM6p@7q5&4qhK`JE_stYj99XqsvmZUCKuH!#{ zz^m(MpNMlE#~^vt8*4gBUCWY9YFQkeu4CTRm@aTXZADPuLx9{N$pk=ON9Al_94aYz z+WUbU`8)b4|Bsnex3gWr?c+A z`nTXu!e2O$#vHc&VtC=sA*ce%QmZU@t1{*#C{BCXrH zZseh5ltI3uVGtO1k3vv%SzLNksg7knj_Fw__S9^vbHWI?$!T_RZxUGI``T8oh-*bp zXI$>V%U`=&gmW9Gdp*b?ajVyuVuK4|0?F`kZsh}hfn=g_}LO>*7@umwtAjM)8 zP)pW_yFHPOQ89!_`q6+*^03d<8IiVSLp|{M@1HY~R#&TnE(wxcO`eK_V_n$c!m#8C zH=T_6w8N3MD&Dpq!*bdJjoB8W>iRme8CPuf*I{I4(Ml#PZK g=*4SNq`ENvCyuLY9%T~y7e)x}olqyVHq)$ literal 175 zcmV;g08syovv4>m-aOR@#Qz(X_Zc7O=)s0hV%!X dX+~b3OQwu-^YYUs&JIw7hTJIS7C#Xz%UuE1Rf7Nk diff --git a/fuzz/corpus/wal/cipher-ascon128 b/fuzz/corpus/wal/cipher-ascon128 index 8a95629..4ec9943 100644 --- a/fuzz/corpus/wal/cipher-ascon128 +++ b/fuzz/corpus/wal/cipher-ascon128 @@ -1 +1 @@ -Lପ/çVìß5P 훹ÂúךÜ&À õJt};ÊÅ͘�•ƒ¯XO‡’ð]‘Œ #tËs³ßM î³þü( \ No newline at end of file +«=XÁÛ~oÝQ§ÈI ¢¾‹s{̸N]ÆuùiÑV|=¬¾‚мSIšÃ»¢6•Ûó´±+óiTMÑ|hƒikH»Bw´óÂÇGø’òêí„ÉCƒÄã¯@*Nõˆ¤bÓxQ\D \ No newline at end of file diff --git a/fuzz/corpus/wal/cipher-chacha20 b/fuzz/corpus/wal/cipher-chacha20 index 26a5a69dd66352b4544e2526cb4d831d57cb4e0f..86ca0e09189de40e6336c7511a20abcf58172ecf 100644 GIT binary patch literal 582 zcmV-M0=fMx15{f@d%!gW^8G3vg3eAw4Ef3IZjmzs{X&{vOG}ql^^^05a(}slB2b6v zda*f+_>aKZXy1!~XWcUc7+051GrQ-ctc|k6cq^Bh3lR*h;0$dbaYFNGEm(<``Rw5# z6b`OxPMPcyTD5rqLkG7pf!-){1+~;`sm*zH6UjA_Y&Dhbk%zAcDB|WfmuIsXp$Bi+y2;dX?iDWcoX;^~ZVb zN-hOdi|Q1`!AQpFSKkIkeREl&QBn zodUcO(}eMp7fzpqv+UyoofQ?{WDm#|P$*+iGr?gWB%fZ@+wHcElZ=3&sRPNY^MT4uW7e=OX(Vp{plaLs(>TgjSdR9Y`a01D44RP{6)`W&5 zKCtN7$`XD%lWq%S=y!J4tMfu$2g2tDs&*9qze(3jAM>cZjX*E$Wfl%q+Yi|rRL<1R zCsc^;q*WazIN)dS$g?-J-?CNrPV65W#b(G~O1gPS&k&$;^9H>%ch8yco7&ThdRD{P z!xYfIPw7!yepV4AUwN?3g-viUSk3Z5r&~B1$JSeuXf4MX>F4-iRZJLxV|6usbsSA_ UR^vEchL)up#T5? literal 64 zcmV-G0KflX?RsF0rU<7^fY|6{{IEa3y>CTUOcL&`&Ig4#qlSxrd?G^t diff --git a/fuzz/corpus/wal/cipher-rc4 b/fuzz/corpus/wal/cipher-rc4 deleted file mode 100644 index 4c9f638..0000000 --- a/fuzz/corpus/wal/cipher-rc4 +++ /dev/null @@ -1,4 +0,0 @@ -ŸœxÇÚ¢ÀØ™ÿ¿ã„îþtaÖžf%ŽÆ=DÖí{ýß¼·²™’,Sp@ëßgHSFˆ·AÇCòÓ'â“f¶•Fùqx½9ímD‹©¢í¼7n‡Ø†MÅ4ôGô`¿‰Å7¨Ùc”éŸíÓê6Ñ¡4–ôY¹L·¾ÆŸ-W¥ñ æJíè³i…dæÄžCižÀcÖçëÌÍñD¦3(À,Â>7¹T™‹^XàxW Ú4;²’æ�-ݳ‰óÏñô¼)œ’Ó´Á“+Ë¥\1gn[¥Lû‡/FÚ¼hË<¶¬Ÿ¤gß ó¦lqÊ®“ž.|Je¾ÀœéðfR¡z÷€œ‰¥,ÔwE¥æ«™î%ù>7 6Xá†Í2í1¯þ\¿ -qhDŸQþ -Z<p޲&^ÿF êãé…aüî^°\B;B£öê››5gFÝЫ£ëxv\ó˜@èŒc€‰]ý)`úPµ?¥ç׿¶¸éT/z²õPT<ùåá -ê¥FE[ï–ïøØœµˆ…ÆCp ÔµÃØn;WOϕ唋2þÇ­ØSõù#†Ì@z¢=çkòFLÊ+·ÂÄ'¶ä?yÍ­�S¤Ž‰þ5ËŠ(§†B \ No newline at end of file diff --git a/fuzz/corpus/wal/cipher-sqlcipher b/fuzz/corpus/wal/cipher-sqlcipher new file mode 100644 index 0000000000000000000000000000000000000000..6884e21c35d951290c6134fa3074cbf6054e2d7b GIT binary patch literal 249 zcmVL>DiXId9vW8qvWRy4_x!3f~>lO7o{sFsDh znfT`KZXC>m(gMG;gs6BblvzoW$sGb&M*A0k;xEbwZW?;AZ5ZyGz-h(+=^qCgrMr~U zsLH2&N_`o?a+RHelwTbeWm0C#>fBW-p4;#HX`q*f)YI14+jh&YI@7xngu7)%Po0+~Ux$fxe9U&^Wd*-kT39<;MtaHKcZ7Y`!m;8H^E=Z*7NBX2Mdlnz$zpbXi>o zV{8u?$uffx)gq0h|NPCKJA7YwG0cMbpUOy%{rBzSGrm9l2z(JS`KcGUk|_2$ByxhT literal 0 HcmV?d00001 diff --git a/fuzz/corpus/wal/legacy-wal-and-truncation b/fuzz/corpus/wal/legacy-wal-and-truncation index 9775b0dd2b3416e2c051b1dc38b85bb2a8e9ba94..68acc3ce4a5d644568d4aa14fbc8d498e080172e 100644 GIT binary patch literal 101 zcmV-r0Gj`j+m`x-h+<%Lzql733G##@C?khi5}ABBH(dO5PdXZ5$>whkSx>8Fp1l0e z@4|e>oRV(CEpP$vFSwj0?Dm&2o=OGb{?>Q{D1CjKw~Utn$AxH+^NpL1etgz(IwViz HaPxx}=Lj;$ literal 286 zcmV+(0pb3nPYD{X#h%%re7v7(`aQ$_y|bF5LEF`-s=McXma@q9u`nw|6;`%UR<;A- znddBOY+V_K=q8*YgkC?H2nV|I*}EBNVqnTBN}E7uL@(FeYl825uQ<#31U4Eo+=Nd= z2?;GL3xQukyQj>ohr+#^$lzhR$FCDrKiC+3VGljJd(%J>b~{!{QtR^3CDH*sh~*bg z3h3-oC)jCVgUy~nCJ|SfUJFUXS6dtM|S#j@*ga7~l diff --git a/fuzz/corpus/wal/legacy-wal-false b/fuzz/corpus/wal/legacy-wal-false index 09b6eb29baa631608c664e9b7b2dc569056bb160..487a26a99e21c21d926d06df74f5cf5376a1e1d2 100644 GIT binary patch literal 64 zcmV-G0KfkYV&-q5=E#Y1gU!$Y7Jd^CnZcJ_rEryL@YlqbDnc|po@V-P~CO65*s@J literal 101 zcmV-r0Gj`b=Uy!lC~AUDABN+$#br(2zEROhNKs$$9?DneS1>j_Q)3WcXS-9HP1QQj z))3q4#bwsLB-=Y`rHyGd~m4KRVw)m=M{ap{o;F4)DhXvoN^77kw_flj;|n+ z4|I-bk2K?;>vxN_X1j5ao|uUF49K!3voz8FR72+Y1;?u#cb$stRF&*=5zurp+c$CJdQ>yJhu d?4N}>NilAjr!4D!n>Ti3fKgo7;B;b}c9{+ZTPFYj literal 64 zcmV-G0KflP?MUg@A15rSE>8v|PhUdsOZPI^d8(dn}4c8lW)VUixE9)SQNZ!(;A W7Ge%+4TrnYVe$?4*(y|7>O!RJjvjyj diff --git a/fuzz/corpus/wal/many-ops b/fuzz/corpus/wal/many-ops index ac430fb6b688afcc1968204afc2fb66fcef44689..7847b60c93bab059380d58b2a8a8e457cb45d46d 100644 GIT binary patch literal 2742 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

44GRQ zFuQ<(!Yl+;ipko7+Ef$p7-X=Kx7VImvf!MLTNcXMML)a462>-o$)6>L_4c8c1_fQ+ z*yxofZ^+0gD^VQNvW>@aoVTO?xZRYW=LiM|wq&r;V2~|qcW|cVM(?3JEc*&cUYWRc zn*?w3E!A!Hpty#ukn--vK*(#JCq*m8F>Q-|B9ZIWA}6;5$l84m{BNw;R}j1mSw$wa!9nvDUSXJ69lXS zp;5_#NwCZ#BPP4W>YN)ByVXwyCayp;og&cGY@XV;p{E81BHuX}$9h}iNPxdgHs(0= z^_1hzjQ^q!nvrM|I|4>OOOT$kz^@2y>(}zC$L=iM!G# zUU}_Ot!@(S>ss$w=`SI>BiBih1=T^ZYhXM%^97!4cIVvcaT%XM&GVKlLI0MD)<$5+ zzZvO?gGv67j2S#cSc{%lDh5;*U9zxAztrx>oVXa-^8^;^QEO)X7dI-33HV zxwgELiG|K&W7eavC4oYCNM)%aM?%pCm%o!5T+W2f$>Y-$$j!XX>ilFh<7=1)i6c(~ z($vJMOT${McH?(nFwmdNAGZ)&hye04o~d!{HGtmWzwcT7KMn6nI#;|&osGOC%%2&A z>F&caDxxPc59=AeM0}GHTu0|brmhqJG>QoX*mt698h$2uCZ9l6c8>VLyraup=MIXb zhshvf&+tAm^l`Jqtt5zt89l9o$1sZ*4A*_ z-=oo7vn=s_p&yO61Tu$J8pMgTn=Zr$0>jlp#9+{KrKc!y?W2V>F{= zC+)i&qg$b5b8qmOk0(pvIn9rXwhB;0f*nG?_HO%Q3HlK-a%m&W*x=kQrVFUR)NY_D zW1#JVgaI-U8@SNitR7WD<0wkU5ZwSPvMHz0gb^O}noo;voVw%a1H zbh5g3@i`vT%8KXk`OtUjB$w&P3;y!PApEO3 HraErt+z>%v diff --git a/fuzz/corpus/wal/wal-truncation-absent b/fuzz/corpus/wal/wal-truncation-absent index f43683b092a1c89559c814f867d39a501c2c05ab..2b7a43967e4e9e95dcb52749c108ab9d98cd19e5 100644 GIT binary patch literal 65 zcmV-H0KWfkpX03~?HWI7!VOtpCe84T6R1?fO}!D1;+S9@gY<(IRA>-re3p7w&Z3+O XA6)X0oH(lxP6eue#sOh*dXZ lZ{JB`cZt3fIk)}@921e^o*=Uqy007#^{hu=&&MZ}rlG#HDoy|Z diff --git a/fuzz/corpus/wal/wal-truncation-present b/fuzz/corpus/wal/wal-truncation-present index 5daeb8adde604bb8f5afa9306c7faf23d441cfac..cc25128980be899cee488b05e9d9c15a86911559 100644 GIT binary patch literal 101 zcmV-r0Gj_B7yGn(O=3_o`3r@@Sv}A3?M-9145q+p?@k=KFnOvdxmj!Gxn2$Ahxj{Di H%1G|})4VZ! literal 101 zcmV-r0Gj_nKyT6>qG8>g(&3F$2)G}P%z-Y)7SN>_m;h=^tNnd#AjCK|Gy6C;e*`Zx zdG2T~BekTX=gwQNxa~8*y?!v!m(dBuH34*|UR8iIpE8!D)~B){x!21F2aUCK6LjC1 Hp}Sp7qQ@}} diff --git a/fuzz/examples/gen_native_seeds.rs b/fuzz/examples/gen_native_seeds.rs index d198cfb..679e717 100644 --- a/fuzz/examples/gen_native_seeds.rs +++ b/fuzz/examples/gen_native_seeds.rs @@ -1,13 +1,13 @@ -//! Builds `corpus/native` the same way `gen_seeds` builds `corpus/differential`: rejection -//! sampling through the real `Arbitrary` impl, keeping the first draw that lands on each target -//! parameter family, after confirming the case runs without panicking. +//! Builds `corpus/native`: rejection sampling through the real `Arbitrary` impl, keeping the +//! first *clean* draw that lands on each target parameter family, after confirming the case +//! runs without panicking. use std::path::Path; use sqlite3mc_src_fuzz::{ run_native, seedgen::{run_search, DivergencePolicy, Family, Rng}, - Cipher, NativeCase, NativeKey, + Algorithm, Cipher, NativeCase, NativeKey, }; const fn has_ops(case: &NativeCase) -> bool { @@ -29,13 +29,22 @@ fn families() -> &'static [Family] { matches: |c| c.config.cipher == Cipher::ChaCha20 && has_ops(c), }, Family { - name: "cipher-rc4", - matches: |c| c.config.cipher == Cipher::Rc4 && has_ops(c), + name: "cipher-sqlcipher", + matches: |c| c.config.cipher == Cipher::SqlCipher && has_ops(c), }, Family { name: "cipher-ascon128", matches: |c| c.config.cipher == Cipher::Ascon128 && has_ops(c), }, + Family { + name: "sqlcipher-sha1-damage", + matches: |c| { + c.config.cipher == Cipher::SqlCipher + && c.config.hmac_algorithm == Some(Algorithm::Sha1) + && !c.damage.is_empty() + && has_ops(c) + }, + }, Family { name: "cipher-aegis", matches: |c| c.config.cipher == Cipher::Aegis && has_ops(c), @@ -57,12 +66,12 @@ fn families() -> &'static [Family] { matches: |c| c.config.plaintext_header_size.is_some_and(|n| n > 0) && has_ops(c), }, Family { - name: "legacy-set", - matches: |c| c.config.legacy.is_some() && has_ops(c), + name: "sqlcipher-hmac-off", + matches: |c| c.config.hmac_use == Some(false) && has_ops(c), }, Family { - name: "page-size-set", - matches: |c| c.config.page_size.is_some() && has_ops(c), + name: "sqlcipher-hmac-sha1", + matches: |c| c.config.hmac_algorithm == Some(Algorithm::Sha1) && has_ops(c), }, Family { name: "aegis-256", @@ -74,15 +83,11 @@ fn families() -> &'static [Family] { }, Family { name: "damage-present-authenticated", - matches: |c| c.config.cipher.authenticated() && !c.damage.is_empty() && has_ops(c), + matches: |c| c.config.authenticated() && !c.damage.is_empty() && has_ops(c), }, Family { name: "damage-present-unauthenticated", - matches: |c| !c.config.cipher.authenticated() && !c.damage.is_empty() && has_ops(c), - }, - Family { - name: "many-ops", - matches: |c| c.ops.len() >= 20, + matches: |c| !c.config.authenticated() && !c.damage.is_empty() && has_ops(c), }, ] } diff --git a/fuzz/examples/gen_rekey_seeds.rs b/fuzz/examples/gen_rekey_seeds.rs index c964ac6..7e5cec3 100644 --- a/fuzz/examples/gen_rekey_seeds.rs +++ b/fuzz/examples/gen_rekey_seeds.rs @@ -32,8 +32,8 @@ fn families() -> &'static [Family] { matches: |c| c.config.cipher == Cipher::ChaCha20 && has_ops(c), }, Family { - name: "cipher-rc4", - matches: |c| c.config.cipher == Cipher::Rc4 && has_ops(c), + name: "cipher-sqlcipher", + matches: |c| c.config.cipher == Cipher::SqlCipher && has_ops(c), }, Family { name: "cipher-ascon128", @@ -63,10 +63,6 @@ fn families() -> &'static [Family] { name: "plaintext-header-present", matches: |c| c.config.plaintext_header_size.is_some_and(|n| n > 0) && has_ops(c), }, - Family { - name: "legacy-set", - matches: |c| c.config.legacy.is_some() && has_ops(c), - }, Family { name: "many-ops-before", matches: |c| c.ops_before.len() >= 10, diff --git a/fuzz/examples/gen_seeds.rs b/fuzz/examples/gen_seeds.rs deleted file mode 100644 index 9dfa54b..0000000 --- a/fuzz/examples/gen_seeds.rs +++ /dev/null @@ -1,163 +0,0 @@ -//! Builds `corpus/differential` by rejection sampling: draws random bytes, decodes them through -//! the real `Arbitrary` impl exactly as libFuzzer would, and keeps the first draw that lands on -//! each target parameter family, after confirming the case runs without panicking. One committed -//! seed is therefore guaranteed to decode to a genuine, already-passing case, not a hand-built one -//! the harness never actually sees bytes for. A divergence is itself interesting input, so the -//! first panicking draw per family is kept too, in place, rather than searched past. - -use std::path::Path; - -use sqlite3mc_src_fuzz::{ - run, - seedgen::{run_search, DivergencePolicy, Family, Rng}, - Algorithm, Case, Key, Side, -}; - -const fn has_ops(case: &Case) -> bool { - !case.ops.is_empty() -} - -#[expect( - clippy::too_many_lines, - reason = "a flat table of Family entries, one per matcher, not control flow to split" -)] -fn families() -> &'static [Family] { - &[ - Family { - name: "writer-sqlcipher", - matches: |c| c.writer == Side::SqlCipher && has_ops(c), - }, - Family { - name: "writer-sqlite3mc", - matches: |c| c.writer == Side::Sqlite3mc && has_ops(c), - }, - Family { - name: "compat-1", - matches: |c| c.config.compatibility == 1 && has_ops(c), - }, - Family { - name: "compat-2", - matches: |c| c.config.compatibility == 2 && has_ops(c), - }, - Family { - name: "compat-3", - matches: |c| c.config.compatibility == 3 && has_ops(c), - }, - Family { - name: "compat-4", - matches: |c| c.config.compatibility == 4 && has_ops(c), - }, - Family { - name: "page-size-default", - matches: |c| c.config.page_size.is_none() && has_ops(c), - }, - Family { - name: "page-size-512", - matches: |c| c.config.page_size == Some(512) && has_ops(c), - }, - Family { - name: "page-size-65536", - matches: |c| c.config.page_size == Some(65536) && has_ops(c), - }, - Family { - name: "kdf-default", - matches: |c| c.config.kdf_algorithm.is_none() && has_ops(c), - }, - Family { - name: "kdf-sha1", - matches: |c| c.config.kdf_algorithm == Some(Algorithm::Sha1) && has_ops(c), - }, - Family { - name: "kdf-sha256", - matches: |c| c.config.kdf_algorithm == Some(Algorithm::Sha256) && has_ops(c), - }, - Family { - name: "kdf-sha512", - matches: |c| c.config.kdf_algorithm == Some(Algorithm::Sha512) && has_ops(c), - }, - Family { - name: "hmac-default", - matches: |c| c.config.hmac.is_none() && has_ops(c), - }, - Family { - name: "hmac-off", - matches: |c| c.config.hmac == Some(false) && has_ops(c), - }, - Family { - name: "hmac-on", - matches: |c| c.config.hmac == Some(true) && has_ops(c), - }, - Family { - name: "hmac-algorithm-sha1", - matches: |c| c.config.hmac_algorithm == Some(Algorithm::Sha1) && has_ops(c), - }, - Family { - name: "hmac-algorithm-sha256", - matches: |c| c.config.hmac_algorithm == Some(Algorithm::Sha256) && has_ops(c), - }, - Family { - name: "hmac-algorithm-sha512", - matches: |c| c.config.hmac_algorithm == Some(Algorithm::Sha512) && has_ops(c), - }, - Family { - name: "key-raw", - matches: |c| matches!(c.config.key, Key::Raw(_)) && has_ops(c), - }, - Family { - name: "key-raw-with-salt-no-header", - matches: |c| { - matches!( - c.config.key, - Key::RawWithSalt { - plaintext_header: 0, - .. - } - ) && has_ops(c) - }, - }, - Family { - name: "key-raw-with-salt-and-header", - matches: |c| { - matches!( - c.config.key, - Key::RawWithSalt { - plaintext_header, .. - } if plaintext_header > 0 - ) && has_ops(c) - }, - }, - Family { - name: "key-passphrase", - matches: |c| matches!(c.config.key, Key::Passphrase { .. }) && has_ops(c), - }, - Family { - name: "corruption-present", - matches: |c| !c.damage.is_empty() && has_ops(c), - }, - Family { - name: "corruption-present-hmac-off", - matches: |c| !c.damage.is_empty() && c.config.hmac == Some(false) && has_ops(c), - }, - Family { - name: "corruption-present-hmac-on", - matches: |c| !c.damage.is_empty() && c.config.hmac == Some(true) && has_ops(c), - }, - Family { - name: "many-ops", - matches: |c| c.ops.len() >= 20, - }, - ] -} - -fn main() { - let dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/corpus/differential")); - run_search( - families(), - Rng::new(0x9e37_79b9_7f4a_7c15), - dir, - 6000, - 200_000, - run, - &DivergencePolicy::KeepFirstDraw, - ); -} diff --git a/fuzz/examples/gen_wal_seeds.rs b/fuzz/examples/gen_wal_seeds.rs index 0867cb4..e5d415c 100644 --- a/fuzz/examples/gen_wal_seeds.rs +++ b/fuzz/examples/gen_wal_seeds.rs @@ -1,8 +1,9 @@ //! Builds `corpus/wal` the same way `gen_rekey_seeds` builds `corpus/rekey`: rejection sampling //! through the real `Arbitrary` impl, keeping the first *clean* draw that lands on each target -//! parameter family. A draw that panics is never committed to `corpus/wal` (it would permanently -//! fail the replay test); the first one found per family is saved to `corpus/findings/` instead, -//! which nothing replays, and the search continues past it for a clean representative. +//! parameter family. A draw that panics is never committed to `corpus/wal` (it would +//! permanently fail the replay test); the first one found per family is saved to +//! `corpus/findings/` instead, which nothing replays, and the search continues past it for a +//! clean representative. use std::path::Path; @@ -31,8 +32,8 @@ fn families() -> &'static [Family] { matches: |c| c.config.cipher == Cipher::ChaCha20 && has_ops(c), }, Family { - name: "cipher-rc4", - matches: |c| c.config.cipher == Cipher::Rc4 && has_ops(c), + name: "cipher-sqlcipher", + matches: |c| c.config.cipher == Cipher::SqlCipher && has_ops(c), }, Family { name: "cipher-ascon128", diff --git a/fuzz/fuzz_targets/differential.rs b/fuzz/fuzz_targets/differential.rs deleted file mode 100755 index 6035142..0000000 --- a/fuzz/fuzz_targets/differential.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![no_main] - -libfuzzer_sys::fuzz_target!(|case: sqlite3mc_src_fuzz::Case| sqlite3mc_src_fuzz::run(&case)); diff --git a/fuzz/sqlcipher-entropy.c b/fuzz/sqlcipher-entropy.c deleted file mode 100644 index b1eaf4e..0000000 --- a/fuzz/sqlcipher-entropy.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SQLCipher's entropy hook, giving its LibTomCrypt RNG the harness's deterministic getentropy. */ -long sqlcipher_wasm_no_clock(void) { abort(); } - -/* Fails closed so rng_get_bytes never falls through to the clock. */ -static unsigned long sqlcipher_wasm_rng(unsigned char *out, unsigned long len, void (*callback)(void)) { - (void)callback; - if (getentropy(out, len) != 0) abort(); - return len; -} - -int sqlcipher_wasm_extra_init(const char *arg) { - ltc_rng = sqlcipher_wasm_rng; - return sqlcipher_extra_init(arg); -} diff --git a/fuzz/sqlcipher-ltc.h b/fuzz/sqlcipher-ltc.h deleted file mode 100644 index 3857e89..0000000 --- a/fuzz/sqlcipher-ltc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* The LibTomCrypt configuration SQLCipher and every libtomcrypt source in the unit share. */ -#ifndef SQLCIPHER_LTC_H -#define SQLCIPHER_LTC_H - -#define LTC_NOTHING -#define LTC_RIJNDAEL -#define LTC_CBC_MODE -#define LTC_SHA1 -#define LTC_SHA256 -#define LTC_SHA512 -#define LTC_HASH_HELPERS -#define LTC_HMAC -#define LTC_FORTUNA -#define LTC_PKCS_5 -#define LTC_RNG_GET_BYTES -#define LTC_PRNG_ENABLE_LTC_RNG -#define LTC_NO_TEST -#define LTC_NO_FILE -#define LTC_NO_ASM -#define LTC_NO_MATH -#define LTC_CLEAN_STACK -/* Bad arguments return CRYPT_INVALID_ARG instead of raising a signal, which the fuzzer would count as a crash. */ -#define ARGTYPE 4 -/* rng_get_bytes always ends in a clock-jitter generator, so reaching it must abort. */ -#define XCLOCK sqlcipher_wasm_no_clock -#define XCLOCKS_PER_SEC 1 -long sqlcipher_wasm_no_clock(void); - -#endif diff --git a/fuzz/sqlcipher-wrapper.c b/fuzz/sqlcipher-wrapper.c deleted file mode 100644 index 5d23bda..0000000 --- a/fuzz/sqlcipher-wrapper.c +++ /dev/null @@ -1,18 +0,0 @@ -/* SQLCipher's configuration, heading the one unit build.rs assembles with libtomcrypt and the entropy hook. */ -#define SQLITE_HAS_CODEC 1 -#define SQLCIPHER_CRYPTO_LIBTOMCRYPT 1 -/* Installs the entropy hook before SQLCipher's own init runs. */ -#define SQLITE_EXTRA_INIT sqlcipher_wasm_extra_init -#define SQLITE_EXTRA_SHUTDOWN sqlcipher_extra_shutdown -/* SQLCipher's log needs a timestamp and a device the harness does not keep. */ -#define SQLCIPHER_OMIT_LOG 1 -#define SQLCIPHER_OMIT_LOG_DEVICE 1 -#define OMIT_MEMLOCK 1 -/* SQLCipher refuses SQLITE_THREADSAFE=0, and the harness runs single-threaded, so no-op mutexes suffice. */ -#undef SQLITE_THREADSAFE -#define SQLITE_THREADSAFE 1 -#define SQLITE_MUTEX_NOOP 1 - -#define LTC_SOURCE -#include "sqlcipher-ltc.h" -#include "sqlcipher.c" diff --git a/fuzz/src/db.rs b/fuzz/src/db.rs index b65efa4..0ad724c 100644 --- a/fuzz/src/db.rs +++ b/fuzz/src/db.rs @@ -1,4 +1,5 @@ //! Safe owners for connections and statements, keeping every raw handle inside this module. +//! Each handle is released by exactly one matching amalgamation call, in its own `Drop`. use core::{ ffi::{c_char, c_int, c_void, CStr}, @@ -7,10 +8,7 @@ use core::{ slice, }; -use crate::ffi::{ - Api, Sqlite3, Stmt, SQLITE_BLOB, SQLITE_DONE, SQLITE_FLOAT, SQLITE_INTEGER, SQLITE_OK, - SQLITE_ROW, SQLITE_TEXT, -}; +use crate::ffi; /// An SQLite primary result code, the low byte of an extended one. #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -23,7 +21,7 @@ impl Code { } const fn check(rc: c_int) -> Result<(), Code> { - if rc == SQLITE_OK { + if rc == ffi::SQLITE_OK { Ok(()) } else { Err(Code::of(rc)) @@ -55,37 +53,35 @@ pub(crate) enum Param<'a> { Blob(&'a [u8]), } -/// `sqlite3_enable_shared_cache`: process-wide, not tied to any one connection. Every connection -/// opened after this call defaults to shared-cache mode (`SQLITE_OPEN_PRIVATECACHE` overrides it -/// per connection, not used anywhere in this harness). -pub(crate) fn enable_shared_cache(api: &Api, enable: bool) -> Result<(), Code> { +/// `sqlite3_enable_shared_cache`: process-wide, so every connection opened after the call +/// defaults to shared-cache mode. +pub(crate) fn enable_shared_cache(enable: bool) -> Result<(), Code> { // SAFETY: takes a plain `c_int`, touches no pointers, safe to call at any time. - check(unsafe { (api.enable_shared_cache)(c_int::from(enable)) }) + check(unsafe { ffi::sqlite3_enable_shared_cache(c_int::from(enable)) }) } /// An open connection, closed on drop. -pub(crate) struct Connection<'a> { - api: &'a Api, - db: NonNull, +pub(crate) struct Connection { + db: NonNull, } -impl<'a> Connection<'a> { - pub(crate) fn open(api: &'a Api, path: &CStr, flags: c_int) -> Result { +impl Connection { + pub(crate) fn open(path: &CStr, flags: c_int) -> Result { let mut db = ptr::null_mut(); - // SAFETY: `path` is NUL-terminated and outlives the call, the VFS name is NULL for the - // default, and `db` is a valid place for SQLite to store the new handle or NULL. - let rc = unsafe { (api.open_v2)(path.as_ptr(), &raw mut db, flags, ptr::null()) }; + // SAFETY: `path` is NUL-terminated and outlives the call, the VFS name is NULL for + // the default, and `db` is a valid place for SQLite to store the new handle or NULL. + let rc = unsafe { ffi::sqlite3_open_v2(path.as_ptr(), &raw mut db, flags, ptr::null()) }; let db = NonNull::new(db); match (rc, db) { - (SQLITE_OK, Some(db)) => Ok(Self { api, db }), + (ffi::SQLITE_OK, Some(db)) => Ok(Self { db }), (_, db) => { if let Some(db) = db { // SAFETY: a failed open still returns a handle SQLite requires closing, and // nothing else holds it. - unsafe { (api.close_v2)(db.as_ptr()) }; + unsafe { ffi::sqlite3_close_v2(db.as_ptr()) }; } // SQLITE_ERROR stands in for an OK code that came without a handle. - Err(Code::of(if rc == SQLITE_OK { 1 } else { rc })) + Err(Code::of(if rc == ffi::SQLITE_OK { 1 } else { rc })) } } } @@ -94,7 +90,7 @@ impl<'a> Connection<'a> { let len = c_int::try_from(key.len()).expect("keys are short"); // SAFETY: `self.db` is open, and `key` is valid for `len` bytes, which SQLite copies // before returning. - check(unsafe { (self.api.key)(self.db.as_ptr(), key.as_ptr().cast(), len) }) + check(unsafe { ffi::sqlite3_key(self.db.as_ptr(), key.as_ptr().cast(), len) }) } /// Changes the key an already-open connection uses, empty bytes decrypting the database. @@ -102,21 +98,13 @@ impl<'a> Connection<'a> { let len = c_int::try_from(key.len()).expect("keys are short"); // SAFETY: `self.db` is open, and `key` is valid for `len` bytes, which SQLite copies // before returning. - check(unsafe { (self.api.rekey)(self.db.as_ptr(), key.as_ptr().cast(), len) }) - } - - const fn sqlite3mc(&self) -> &crate::ffi::Sqlite3mcApi { - self.api - .sqlite3mc - .as_ref() - .expect("only SQLite3MC has sqlite3mc_config") + check(unsafe { ffi::sqlite3_rekey(self.db.as_ptr(), key.as_ptr().cast(), len) }) } /// Sets a connection-wide SQLite3MC parameter, returning the value now in effect or -1. pub(crate) fn sqlite3mc_config(&self, param: &CStr, value: c_int) -> c_int { - let config = self.sqlite3mc().config; // SAFETY: `self.db` is open and `param` is NUL-terminated for the whole call. - unsafe { config(self.db.as_ptr(), param.as_ptr(), value) } + unsafe { ffi::sqlite3mc_config(self.db.as_ptr(), param.as_ptr(), value) } } /// Sets a cipher parameter, returning the value now in effect or -1. @@ -126,16 +114,16 @@ impl<'a> Connection<'a> { param: &CStr, value: c_int, ) -> c_int { - let config_cipher = self.sqlite3mc().config_cipher; // SAFETY: `self.db` is open and both names are NUL-terminated for the whole call. - unsafe { config_cipher(self.db.as_ptr(), cipher.as_ptr(), param.as_ptr(), value) } + unsafe { + ffi::sqlite3mc_config_cipher(self.db.as_ptr(), cipher.as_ptr(), param.as_ptr(), value) + } } /// The index `sqlite3mc_config` takes for the cipher named `name`. - pub(crate) fn sqlite3mc_cipher_index(&self, name: &CStr) -> c_int { - let cipher_index = self.sqlite3mc().cipher_index; + pub(crate) fn sqlite3mc_cipher_index(name: &CStr) -> c_int { // SAFETY: `name` is NUL-terminated for the whole call. - unsafe { cipher_index(name.as_ptr()) } + unsafe { ffi::sqlite3mc_cipher_index(name.as_ptr()) } } pub(crate) fn prepare(&self, sql: &CStr) -> Result, Code> { @@ -143,7 +131,7 @@ impl<'a> Connection<'a> { // SAFETY: `self.db` is open, `sql` is NUL-terminated (length -1 reads up to the NUL), // `stmt` is a valid place for the handle, and the tail pointer is not requested. let rc = unsafe { - (self.api.prepare_v2)( + ffi::sqlite3_prepare_v2( self.db.as_ptr(), sql.as_ptr(), -1, @@ -154,7 +142,6 @@ impl<'a> Connection<'a> { check(rc)?; let stmt = NonNull::new(stmt).expect("the harness never prepares empty SQL"); Ok(Statement { - api: self.api, stmt, _connection: PhantomData, }) @@ -165,82 +152,74 @@ impl<'a> Connection<'a> { self.prepare(sql)?.run(params) } - /// Starts a backup into `self` (as `dest_name`) from `src` (as `src_name`). `None` when the - /// pair is refused outright, SQLite's own built-in restrictions or SQLite3MC's - /// `sqlite3mcIsBackupSupported` compatibility guard alike. + /// Starts a backup into `self` from `src`, `None` when SQLite's own restrictions or + /// SQLite3MC's compatibility guard refuse the pair. pub(crate) fn backup_init( &self, dest_name: &CStr, src: &Self, src_name: &CStr, - ) -> Option> { + ) -> Option { // SAFETY: both connections are open for the call's duration, both names are // NUL-terminated, and the returned handle, if any, is owned by the new `BackupJob`. let handle = unsafe { - (self.api.backup_init)( + ffi::sqlite3_backup_init( self.db.as_ptr(), dest_name.as_ptr(), src.db.as_ptr(), src_name.as_ptr(), ) }; - NonNull::new(handle).map(|handle| BackupJob { - api: self.api, - handle, - }) + NonNull::new(handle).map(|handle| BackupJob { handle }) } } -/// A `sqlite3_backup` in progress. [`BackupJob::finish`] is the intended end; dropping one that -/// was never finished calls `sqlite3_backup_finish` anyway, so an early-abandoned backup is -/// still released. -pub(crate) struct BackupJob<'a> { - api: &'a Api, - handle: NonNull, +/// A `sqlite3_backup` in progress; dropping one never finished still calls +/// `sqlite3_backup_finish`. +pub(crate) struct BackupJob { + handle: NonNull, } -impl BackupJob<'_> { - /// Runs up to `n_page` pages (negative for "all remaining"), returning the raw result code: - /// callers need `SQLITE_DONE` (101) distinguished from a plain `SQLITE_OK` (0) success. +impl BackupJob { + /// Runs up to `n_page` pages (negative for all remaining), returning the raw code so callers + /// can tell `SQLITE_DONE` from plain success. pub(crate) fn step(&self, n_page: c_int) -> c_int { // SAFETY: the handle is valid until `finish`/drop, and `step` never invalidates it. - unsafe { (self.api.backup_step)(self.handle.as_ptr(), n_page) } + unsafe { ffi::sqlite3_backup_step(self.handle.as_ptr(), n_page) } } - /// Ends the backup. Finishes it immediately, then forgets `self` so [`BackupJob`]'s own - /// `Drop` never runs and finishes the same handle a second time. + /// Ends the backup, then forgets `self` so `Drop` never finishes the same handle twice. pub(crate) fn finish(self) -> Result<(), Code> { // SAFETY: `handle` came from a successful `backup_init`; `mem::forget` below is what // keeps this the only call that finishes it. - let result = check(unsafe { (self.api.backup_finish)(self.handle.as_ptr()) }); + let result = check(unsafe { ffi::sqlite3_backup_finish(self.handle.as_ptr()) }); core::mem::forget(self); result } } -impl Drop for BackupJob<'_> { +impl Drop for BackupJob { fn drop(&mut self) { // SAFETY: only reached when `finish` was never called, since `finish` forgets `self` // first; `self.handle` is still valid and this is its only release. unsafe { - (self.api.backup_finish)(self.handle.as_ptr()); + ffi::sqlite3_backup_finish(self.handle.as_ptr()); } } } -impl Drop for Connection<'_> { +impl Drop for Connection { fn drop(&mut self) { // SAFETY: `self.db` came from a successful open and is closed only here. Statements // borrow the connection, so all of them were finalized before this runs. - unsafe { (self.api.close_v2)(self.db.as_ptr()) }; + unsafe { ffi::sqlite3_close_v2(self.db.as_ptr()) }; } } /// A prepared statement, finalized on drop and unable to outlive its connection. pub(crate) struct Statement<'c> { - api: &'c Api, - stmt: NonNull, - _connection: PhantomData<&'c Connection<'c>>, + stmt: NonNull, + _connection: PhantomData<&'c Connection>, } impl Statement<'_> { @@ -248,48 +227,48 @@ impl Statement<'_> { pub(crate) fn run(&mut self, params: &[Param<'_>]) -> Result<(), Code> { let result = self.bind(params).and_then(|()| loop { match self.step() { - SQLITE_ROW => {} - SQLITE_DONE => break Ok(()), + ffi::SQLITE_ROW => {} + ffi::SQLITE_DONE => break Ok(()), rc => break Err(Code::of(rc)), } }); // SAFETY: `self.stmt` is a live statement owned by `self`. - unsafe { (self.api.reset)(self.stmt.as_ptr()) }; + unsafe { ffi::sqlite3_reset(self.stmt.as_ptr()) }; // SAFETY: as above. After this SQLite holds no pointer into `params`. - unsafe { (self.api.clear_bindings)(self.stmt.as_ptr()) }; + unsafe { ffi::sqlite3_clear_bindings(self.stmt.as_ptr()) }; result } fn step(&mut self) -> c_int { // SAFETY: `self.stmt` is a live statement, and every bound buffer outlives the step, // since `run` clears bindings before its borrows end. - unsafe { (self.api.step)(self.stmt.as_ptr()) } + unsafe { ffi::sqlite3_step(self.stmt.as_ptr()) } } - fn bind(&mut self, params: &[Param<'_>]) -> Result<(), Code> { + fn bind(&self, params: &[Param<'_>]) -> Result<(), Code> { let stmt = self.stmt.as_ptr(); for (index, param) in (1..).zip(params) { let rc = match *param { // SAFETY: `stmt` is live and `index` counts from 1 as SQLite expects. - Param::Null => unsafe { (self.api.bind_null)(stmt, index) }, + Param::Null => unsafe { ffi::sqlite3_bind_null(stmt, index) }, // SAFETY: as above. - Param::Integer(v) => unsafe { (self.api.bind_int64)(stmt, index, v) }, + Param::Integer(v) => unsafe { ffi::sqlite3_bind_int64(stmt, index, v) }, // SAFETY: as above. - Param::Real(v) => unsafe { (self.api.bind_double)(stmt, index, v) }, + Param::Real(v) => unsafe { ffi::sqlite3_bind_double(stmt, index, v) }, Param::Text(v) => { let len = c_int::try_from(v.len()).expect("text fits an int"); // SAFETY: `v` is valid for `len` bytes, and SQLITE_STATIC (the `None` // destructor) is sound because `run` clears the binding before `v`'s // borrow ends. unsafe { - (self.api.bind_text)(stmt, index, v.as_ptr().cast::(), len, None) + ffi::sqlite3_bind_text(stmt, index, v.as_ptr().cast::(), len, None) } } Param::Blob(v) => { let len = c_int::try_from(v.len()).expect("blob fits an int"); // SAFETY: as for text. unsafe { - (self.api.bind_blob)(stmt, index, v.as_ptr().cast::(), len, None) + ffi::sqlite3_bind_blob(stmt, index, v.as_ptr().cast::(), len, None) } } }; @@ -301,12 +280,12 @@ impl Statement<'_> { /// The next row, `None` once the statement is done. pub(crate) fn next_row(&mut self) -> Result>, Code> { match self.step() { - SQLITE_ROW => {} - SQLITE_DONE => return Ok(None), + ffi::SQLITE_ROW => {} + ffi::SQLITE_DONE => return Ok(None), rc => return Err(Code::of(rc)), } // SAFETY: the statement is live and positioned on a row. - let columns = unsafe { (self.api.column_count)(self.stmt.as_ptr()) }; + let columns = unsafe { ffi::sqlite3_column_count(self.stmt.as_ptr()) }; Ok(Some((0..columns).map(|i| self.column(i)).collect())) } @@ -315,20 +294,22 @@ impl Statement<'_> { let stmt = self.stmt.as_ptr(); // SAFETY: the statement is positioned on a row and `i` is in range, which holds for // every accessor below. - match unsafe { (self.api.column_type)(stmt, i) } { + match unsafe { ffi::sqlite3_column_type(stmt, i) } { // SAFETY: as above. - SQLITE_INTEGER => Value::Integer(unsafe { (self.api.column_int64)(stmt, i) }), + ffi::SQLITE_INTEGER => Value::Integer(unsafe { ffi::sqlite3_column_int64(stmt, i) }), // SAFETY: as above. - SQLITE_FLOAT => Value::Real(unsafe { (self.api.column_double)(stmt, i) }.to_bits()), - SQLITE_TEXT => { + ffi::SQLITE_FLOAT => { + Value::Real(unsafe { ffi::sqlite3_column_double(stmt, i) }.to_bits()) + } + ffi::SQLITE_TEXT => { // SAFETY: as above. The pointer is fetched before its length, the order SQLite // documents for a stable result. - let text = unsafe { (self.api.column_text)(stmt, i) }; + let text = unsafe { ffi::sqlite3_column_text(stmt, i) }; Value::Text(self.copy(text, i)) } - SQLITE_BLOB => { + ffi::SQLITE_BLOB => { // SAFETY: as for text. - let blob = unsafe { (self.api.column_blob)(stmt, i) }.cast::(); + let blob = unsafe { ffi::sqlite3_column_blob(stmt, i) }.cast::(); Value::Blob(self.copy(blob, i)) } _ => Value::Null, @@ -339,7 +320,7 @@ impl Statement<'_> { fn copy(&self, data: *const u8, i: c_int) -> Vec { // SAFETY: the statement is on a row and `i` is in range, and asking for the length // after the pointer leaves the pointer valid. - let len = unsafe { (self.api.column_bytes)(self.stmt.as_ptr(), i) }; + let len = unsafe { ffi::sqlite3_column_bytes(self.stmt.as_ptr(), i) }; let len = usize::try_from(len).expect("SQLite reports non-negative lengths"); if data.is_null() || len == 0 { return Vec::new(); @@ -353,6 +334,6 @@ impl Statement<'_> { impl Drop for Statement<'_> { fn drop(&mut self) { // SAFETY: `self.stmt` came from a successful prepare and is finalized only here. - unsafe { (self.api.finalize)(self.stmt.as_ptr()) }; + unsafe { ffi::sqlite3_finalize(self.stmt.as_ptr()) }; } } diff --git a/fuzz/src/entropy.rs b/fuzz/src/entropy.rs deleted file mode 100644 index a65a274..0000000 --- a/fuzz/src/entropy.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Replaces libc's `getentropy`, the call SQLCipher's RNG makes directly (`sqlcipher_wasm_rng` in -//! `sqlcipher-entropy.c`), with a deterministic stream reset once per [`run`](crate::run::run) call, so -//! the same [`Case`](crate::Case) produces the same salts and IVs on every repeat, not just the same -//! workload. SQLite3MC's own RNG reads `/dev/urandom` first and falls back to `getentropy` only if -//! that open fails, so this does not make SQLite3MC's own writes deterministic; it is enough for any -//! divergence whose randomness comes from SQLCipher's own side, which is where it is drawn from. - -use std::cell::Cell; - -thread_local! { - static STATE: Cell = const { Cell::new(0x9e37_79b9_7f4a_7c15) }; -} - -/// Reseeds the deterministic stream `getentropy` below draws from. Call once per [`run`] invocation, -/// before anything that might key or write a page, with a seed derived from the case itself so two -/// different cases draw different streams but the same case always draws the same one. -pub(crate) fn reset(seed: u64) { - STATE.with(|state| state.set(seed | 1)); -} - -/// xorshift64*, fast and good enough to stand in for real entropy in a replay-friendly harness. -fn next(state: &Cell) -> u64 { - let mut x = state.get(); - x ^= x << 13; - x ^= x >> 7; - x ^= x << 17; - state.set(x); - x.wrapping_mul(0x2545_f491_4f6c_dd1d) -} - -/// # Safety -/// `buf` must be valid for `len` writable bytes for the duration of this call, the same contract -/// libc's own `getentropy` has; the caller owns and allocates the buffer, this function only fills it. -#[unsafe(no_mangle)] -pub(crate) unsafe extern "C" fn getentropy(buf: *mut u8, len: usize) -> i32 { - STATE.with(|state| { - let mut filled = 0usize; - while filled < len { - let word = next(state).to_le_bytes(); - let take = word.len().min(len - filled); - // SAFETY: `buf..buf+len` is valid for writes for the whole call per this function's own - // caller contract, `u8` has no alignment requirement so `buf.add(filled)` needs no - // alignment check, `filled + take <= len` by construction so the destination range - // stays in bounds, `word` is a local stack array with no aliasing to `buf` possible, - // and `take <= word.len()` so the source read stays in bounds too. - unsafe { - std::ptr::copy_nonoverlapping(word.as_ptr(), buf.add(filled), take); - } - filled += take; - } - }); - 0 -} diff --git a/fuzz/src/ffi.rs b/fuzz/src/ffi.rs index 1ac6a48..ce60110 100644 --- a/fuzz/src/ffi.rs +++ b/fuzz/src/ffi.rs @@ -1,4 +1,8 @@ -//! The C API of both libraries, reached through the renamed symbols `build.rs` produces. +//! The C API of the vendored amalgamation, its `sqlite3mc_*` extensions included. +//! +//! Every handle is an opaque foreign allocation owned by SQLite3MC, moved through +//! [`crate::db`] as a `NonNull` and released by exactly one matching call. Every `&CStr` +//! parameter is NUL-terminated and must outlive the call; the amalgamation copies what it keeps. use core::ffi::{c_char, c_double, c_int, c_void}; @@ -34,157 +38,67 @@ pub(crate) const SQLITE_FLOAT: c_int = 2; pub(crate) const SQLITE_TEXT: c_int = 3; pub(crate) const SQLITE_BLOB: c_int = 4; -/// One library's entry points, so the harness drives either side through the same code. -pub(crate) struct Api { - pub(crate) open_v2: - unsafe extern "C" fn(*const c_char, *mut *mut Sqlite3, c_int, *const c_char) -> c_int, - pub(crate) close_v2: unsafe extern "C" fn(*mut Sqlite3) -> c_int, - pub(crate) key: unsafe extern "C" fn(*mut Sqlite3, *const c_void, c_int) -> c_int, - pub(crate) rekey: unsafe extern "C" fn(*mut Sqlite3, *const c_void, c_int) -> c_int, - pub(crate) prepare_v2: unsafe extern "C" fn( - *mut Sqlite3, - *const c_char, - c_int, - *mut *mut Stmt, - *mut *const c_char, - ) -> c_int, - pub(crate) step: unsafe extern "C" fn(*mut Stmt) -> c_int, - pub(crate) reset: unsafe extern "C" fn(*mut Stmt) -> c_int, - pub(crate) clear_bindings: unsafe extern "C" fn(*mut Stmt) -> c_int, - pub(crate) finalize: unsafe extern "C" fn(*mut Stmt) -> c_int, - pub(crate) bind_null: unsafe extern "C" fn(*mut Stmt, c_int) -> c_int, - pub(crate) bind_int64: unsafe extern "C" fn(*mut Stmt, c_int, i64) -> c_int, - pub(crate) bind_double: unsafe extern "C" fn(*mut Stmt, c_int, c_double) -> c_int, - pub(crate) bind_text: - unsafe extern "C" fn(*mut Stmt, c_int, *const c_char, c_int, Destructor) -> c_int, - pub(crate) bind_blob: - unsafe extern "C" fn(*mut Stmt, c_int, *const c_void, c_int, Destructor) -> c_int, - pub(crate) column_count: unsafe extern "C" fn(*mut Stmt) -> c_int, - pub(crate) column_type: unsafe extern "C" fn(*mut Stmt, c_int) -> c_int, - pub(crate) column_int64: unsafe extern "C" fn(*mut Stmt, c_int) -> i64, - pub(crate) column_double: unsafe extern "C" fn(*mut Stmt, c_int) -> c_double, - pub(crate) column_text: unsafe extern "C" fn(*mut Stmt, c_int) -> *const u8, - pub(crate) column_blob: unsafe extern "C" fn(*mut Stmt, c_int) -> *const c_void, - pub(crate) column_bytes: unsafe extern "C" fn(*mut Stmt, c_int) -> c_int, - pub(crate) backup_init: unsafe extern "C" fn( - *mut Sqlite3, - *const c_char, - *mut Sqlite3, - *const c_char, - ) -> *mut Backup, - pub(crate) backup_step: unsafe extern "C" fn(*mut Backup, c_int) -> c_int, - pub(crate) backup_finish: unsafe extern "C" fn(*mut Backup) -> c_int, - pub(crate) enable_shared_cache: unsafe extern "C" fn(c_int) -> c_int, - pub(crate) sqlite3mc: Option, +unsafe extern "C" { + pub(crate) fn sqlite3_open_v2( + dbfilename: *const c_char, + db: *mut *mut Sqlite3, + flags: c_int, + vfs: *const c_char, + ) -> c_int; + pub(crate) fn sqlite3_close_v2(db: *mut Sqlite3) -> c_int; + pub(crate) fn sqlite3_key(db: *mut Sqlite3, key: *const c_void, keylen: c_int) -> c_int; + pub(crate) fn sqlite3_rekey(db: *mut Sqlite3, key: *const c_void, keylen: c_int) -> c_int; + pub(crate) fn sqlite3_prepare_v2( + db: *mut Sqlite3, + zsql: *const c_char, + nbyte: c_int, + stmt: *mut *mut Stmt, + tail: *mut *const c_char, + ) -> c_int; + pub(crate) fn sqlite3_step(stmt: *mut Stmt) -> c_int; + pub(crate) fn sqlite3_reset(stmt: *mut Stmt) -> c_int; + pub(crate) fn sqlite3_clear_bindings(stmt: *mut Stmt) -> c_int; + pub(crate) fn sqlite3_finalize(stmt: *mut Stmt) -> c_int; + pub(crate) fn sqlite3_bind_null(stmt: *mut Stmt, index: c_int) -> c_int; + pub(crate) fn sqlite3_bind_int64(stmt: *mut Stmt, index: c_int, value: i64) -> c_int; + pub(crate) fn sqlite3_bind_double(stmt: *mut Stmt, index: c_int, value: c_double) -> c_int; + pub(crate) fn sqlite3_bind_text( + stmt: *mut Stmt, + index: c_int, + value: *const c_char, + nbyte: c_int, + destructor: Destructor, + ) -> c_int; + pub(crate) fn sqlite3_bind_blob( + stmt: *mut Stmt, + index: c_int, + value: *const c_void, + nbyte: c_int, + destructor: Destructor, + ) -> c_int; + pub(crate) fn sqlite3_column_count(stmt: *mut Stmt) -> c_int; + pub(crate) fn sqlite3_column_type(stmt: *mut Stmt, i: c_int) -> c_int; + pub(crate) fn sqlite3_column_int64(stmt: *mut Stmt, i: c_int) -> i64; + pub(crate) fn sqlite3_column_double(stmt: *mut Stmt, i: c_int) -> c_double; + pub(crate) fn sqlite3_column_text(stmt: *mut Stmt, i: c_int) -> *const u8; + pub(crate) fn sqlite3_column_blob(stmt: *mut Stmt, i: c_int) -> *const c_void; + pub(crate) fn sqlite3_column_bytes(stmt: *mut Stmt, i: c_int) -> c_int; + pub(crate) fn sqlite3_backup_init( + dest: *mut Sqlite3, + destname: *const c_char, + src: *mut Sqlite3, + srcname: *const c_char, + ) -> *mut Backup; + pub(crate) fn sqlite3_backup_step(p: *mut Backup, n_page: c_int) -> c_int; + pub(crate) fn sqlite3_backup_finish(p: *mut Backup) -> c_int; + pub(crate) fn sqlite3_enable_shared_cache(enable: c_int) -> c_int; + /// SQLite3MC's own entry points, absent from upstream SQLite. + pub(crate) fn sqlite3mc_config(db: *mut Sqlite3, param: *const c_char, value: c_int) -> c_int; + pub(crate) fn sqlite3mc_config_cipher( + db: *mut Sqlite3, + cipher: *const c_char, + param: *const c_char, + value: c_int, + ) -> c_int; + pub(crate) fn sqlite3mc_cipher_index(name: *const c_char) -> c_int; } - -/// SQLite3MC's configuration entry points, which SQLCipher lacks. -pub(crate) struct Sqlite3mcApi { - pub(crate) config: unsafe extern "C" fn(*mut Sqlite3, *const c_char, c_int) -> c_int, - pub(crate) config_cipher: - unsafe extern "C" fn(*mut Sqlite3, *const c_char, *const c_char, c_int) -> c_int, - pub(crate) cipher_index: unsafe extern "C" fn(*const c_char) -> c_int, -} - -macro_rules! bindings { - ($module:ident, $prefix:literal, { $($name:ident($($arg:ty),*) $(-> $ret:ty)?;)* }) => { - mod $module { - use super::{c_char, c_double, c_int, c_void, Backup, Destructor, Sqlite3, Stmt}; - - unsafe extern "C" { - $( - #[link_name = concat!($prefix, stringify!($name))] - pub(super) fn $name($(_: $arg),*) $(-> $ret)?; - )* - } - } - }; -} - -macro_rules! common { - ($module:ident, $prefix:literal $(, $extra:ident($($arg:ty),*) -> $ret:ty)*) => { - bindings!($module, $prefix, { - sqlite3_open_v2(*const c_char, *mut *mut Sqlite3, c_int, *const c_char) -> c_int; - sqlite3_close_v2(*mut Sqlite3) -> c_int; - sqlite3_key(*mut Sqlite3, *const c_void, c_int) -> c_int; - sqlite3_rekey(*mut Sqlite3, *const c_void, c_int) -> c_int; - sqlite3_prepare_v2(*mut Sqlite3, *const c_char, c_int, *mut *mut Stmt, *mut *const c_char) -> c_int; - sqlite3_step(*mut Stmt) -> c_int; - sqlite3_reset(*mut Stmt) -> c_int; - sqlite3_clear_bindings(*mut Stmt) -> c_int; - sqlite3_finalize(*mut Stmt) -> c_int; - sqlite3_bind_null(*mut Stmt, c_int) -> c_int; - sqlite3_bind_int64(*mut Stmt, c_int, i64) -> c_int; - sqlite3_bind_double(*mut Stmt, c_int, c_double) -> c_int; - sqlite3_bind_text(*mut Stmt, c_int, *const c_char, c_int, Destructor) -> c_int; - sqlite3_bind_blob(*mut Stmt, c_int, *const c_void, c_int, Destructor) -> c_int; - sqlite3_column_count(*mut Stmt) -> c_int; - sqlite3_column_type(*mut Stmt, c_int) -> c_int; - sqlite3_column_int64(*mut Stmt, c_int) -> i64; - sqlite3_column_double(*mut Stmt, c_int) -> c_double; - sqlite3_column_text(*mut Stmt, c_int) -> *const u8; - sqlite3_column_blob(*mut Stmt, c_int) -> *const c_void; - sqlite3_column_bytes(*mut Stmt, c_int) -> c_int; - sqlite3_backup_init(*mut Sqlite3, *const c_char, *mut Sqlite3, *const c_char) -> *mut Backup; - sqlite3_backup_step(*mut Backup, c_int) -> c_int; - sqlite3_backup_finish(*mut Backup) -> c_int; - sqlite3_enable_shared_cache(c_int) -> c_int; - $($extra($($arg),*) -> $ret;)* - }); - }; -} - -common!( - mc, - "mc_", - sqlite3mc_config(*mut Sqlite3, *const c_char, c_int) -> c_int, - sqlite3mc_config_cipher(*mut Sqlite3, *const c_char, *const c_char, c_int) -> c_int, - sqlite3mc_cipher_index(*const c_char) -> c_int -); -common!(sc, "sc_"); - -macro_rules! api { - ($module:ident, $sqlite3mc:expr) => { - Api { - open_v2: $module::sqlite3_open_v2, - close_v2: $module::sqlite3_close_v2, - key: $module::sqlite3_key, - rekey: $module::sqlite3_rekey, - prepare_v2: $module::sqlite3_prepare_v2, - step: $module::sqlite3_step, - reset: $module::sqlite3_reset, - clear_bindings: $module::sqlite3_clear_bindings, - finalize: $module::sqlite3_finalize, - bind_null: $module::sqlite3_bind_null, - bind_int64: $module::sqlite3_bind_int64, - bind_double: $module::sqlite3_bind_double, - bind_text: $module::sqlite3_bind_text, - bind_blob: $module::sqlite3_bind_blob, - column_count: $module::sqlite3_column_count, - column_type: $module::sqlite3_column_type, - column_int64: $module::sqlite3_column_int64, - column_double: $module::sqlite3_column_double, - column_text: $module::sqlite3_column_text, - column_blob: $module::sqlite3_column_blob, - column_bytes: $module::sqlite3_column_bytes, - backup_init: $module::sqlite3_backup_init, - backup_step: $module::sqlite3_backup_step, - backup_finish: $module::sqlite3_backup_finish, - enable_shared_cache: $module::sqlite3_enable_shared_cache, - sqlite3mc: $sqlite3mc, - } - }; -} - -/// SQLite3 Multiple Ciphers, from `sqlite3mc-src`. -pub(crate) static SQLITE3MC: Api = api!( - mc, - Some(Sqlite3mcApi { - config: mc::sqlite3mc_config, - config_cipher: mc::sqlite3mc_config_cipher, - cipher_index: mc::sqlite3mc_cipher_index, - }) -); - -/// SQLCipher with its libtomcrypt provider, from `sqlcipher-src`. -pub(crate) static SQLCIPHER: Api = api!(sc, None); diff --git a/fuzz/src/input.rs b/fuzz/src/input.rs index e64ea07..d8b9143 100644 --- a/fuzz/src/input.rs +++ b/fuzz/src/input.rs @@ -1,17 +1,8 @@ -//! What one execution does, decoded from fuzzer bytes into values both libraries accept. +//! What one execution does, decoded from fuzzer bytes into values SQLite3MC accepts. use arbitrary::{Arbitrary, Result, Unstructured}; -/// The library that writes the database. The other one reads it. -#[derive(Arbitrary, Debug, Clone, Copy, PartialEq, Eq)] -pub enum Side { - /// SQLCipher, the reference. - SqlCipher, - /// SQLite3MC's `sqlcipher` scheme. - Sqlite3mc, -} - -/// A hash both sides offer for key derivation and page authentication. +/// A hash the `sqlcipher` scheme takes for key derivation and page authentication. #[derive(Arbitrary, Debug, Clone, Copy, PartialEq, Eq)] pub enum Algorithm { /// SHA-1. @@ -22,129 +13,6 @@ pub enum Algorithm { Sha512, } -/// How the database is keyed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Key { - /// A raw 32-byte key, which skips key derivation. - Raw([u8; 32]), - /// A raw key with an explicit 16-byte salt, which also lets page 1 keep a plaintext header. - RawWithSalt { - /// The key. - key: [u8; 32], - /// The salt. - salt: [u8; 16], - /// Bytes of page 1 left unencrypted, a multiple of 16 up to 96, or 0. - plaintext_header: u8, - }, - /// A passphrase run through PBKDF2 `kdf_iter` times. - Passphrase { - /// The passphrase, never empty. - bytes: Vec, - /// Iterations, 1 to 16. - kdf_iter: u8, - }, -} - -/// The cipher settings, as SQLCipher compatibility defaults plus optional overrides. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Config { - /// SQLCipher major version whose defaults apply, 1 to 4. - pub compatibility: u8, - /// Page size, a power of two from 512 to 65536, or the version's default. - pub page_size: Option, - /// Key derivation hash, or the version's default. - pub kdf_algorithm: Option, - /// Page authentication hash, or the version's default. - pub hmac_algorithm: Option, - /// Whether pages carry an HMAC, or the version's default. - pub hmac: Option, - /// The key. - pub key: Key, -} - -impl Config { - /// Whether the key names a salt that SQLite3MC replaces with the file's, lacking a plaintext header. - #[must_use] - pub const fn explicit_salt_unused_by_sqlite3mc(&self) -> bool { - matches!(self.key, Key::RawWithSalt { .. }) && self.plaintext_header() == 0 - } - - /// Page 1's plaintext header size in effect, which only compatibility 4 honours. - #[must_use] - pub const fn plaintext_header(&self) -> u8 { - match self.key { - Key::RawWithSalt { - plaintext_header, .. - } if self.compatibility == 4 => plaintext_header, - _ => 0, - } - } - - /// Bytes each page reserves for the IV plus, with HMAC on, the digest padded to 16 bytes. - #[must_use] - pub fn reserved(&self) -> u32 { - let hmac = self.hmac.unwrap_or(self.compatibility >= 2); - let algorithm = self.hmac_algorithm.unwrap_or(if self.compatibility == 4 { - Algorithm::Sha512 - } else { - Algorithm::Sha1 - }); - let digest: u32 = match algorithm { - Algorithm::Sha1 => 20, - Algorithm::Sha256 => 32, - Algorithm::Sha512 => 64, - }; - 16 + if hmac { digest.next_multiple_of(16) } else { 0 } - } -} - -impl<'a> Arbitrary<'a> for Config { - fn arbitrary(u: &mut Unstructured<'a>) -> Result { - let compatibility = u.int_in_range(1..=4)?; - let page_size = if u.arbitrary()? { - Some(1 << u.int_in_range(9..=16)?) - } else { - None - }; - let kdf_algorithm = u.arbitrary()?; - let hmac_algorithm = u.arbitrary()?; - let hmac = u.arbitrary()?; - let key = match u.int_in_range(0..=2)? { - 0 => Key::Raw(u.arbitrary()?), - 1 => Key::RawWithSalt { - key: u.arbitrary()?, - salt: u.arbitrary()?, - plaintext_header: 16 * u.int_in_range(0..=6)?, - }, - _ => { - let len = u.int_in_range(1..=64)?; - let mut bytes = u.bytes(len)?.to_vec(); - // SQLite3MC documents `raw:` as raw key syntax for every cipher, SQLCipher has none. - if bytes.starts_with(b"raw:") { - bytes[0] = b'R'; - } - Key::Passphrase { - bytes, - kdf_iter: u.int_in_range(1..=16)?, - } - } - }; - let mut config = Self { - compatibility, - page_size, - kdf_algorithm, - hmac_algorithm, - hmac, - key, - }; - // `sqlite3BtreeSetPageSize` enlarges 512-byte pages to 1024 when more than 32 bytes are reserved. - if config.page_size == Some(512) && config.reserved() > 32 { - config.page_size = Some(1024); - } - Ok(config) - } -} - /// One of the three tables a workload can touch. #[derive(Arbitrary, Debug, Clone, Copy, PartialEq, Eq)] pub enum Table { @@ -236,65 +104,16 @@ pub struct Flip { pub mask: u8, } -/// One execution. -#[derive(Debug, Clone, PartialEq)] -pub struct Case { - /// The library that writes the database. - pub writer: Side, - /// Cipher settings, identical on both sides. - pub config: Config, - /// Workload the writer runs, at most [`MAX_OPS`] steps of it. - pub ops: Vec, - /// Damage applied to a copy of the finished file, at most [`MAX_FLIPS`] flips of it. - pub damage: Vec, -} - -/// [`Case`] as decoded, before the exclusions in [`Case::from`]. -#[derive(Arbitrary)] -struct Draw { - writer: Side, - config: Config, - ops: Vec, - damage: Vec, -} - -impl From for Case { - fn from(draw: Draw) -> Self { - let mut config = draw.config; - // SQLCipher 4.19.0 cannot write 512-byte pages (upstream/sqlcipher-512-page-size.md). - if draw.writer == Side::SqlCipher && config.page_size == Some(512) { - config.page_size = Some(1024); - } - Self { - writer: draw.writer, - config, - ops: draw.ops, - damage: draw.damage, - } - } -} - -impl<'a> Arbitrary<'a> for Case { - fn arbitrary(u: &mut Unstructured<'a>) -> Result { - Draw::arbitrary(u).map(Self::from) - } - - fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { - Draw::arbitrary_take_rest(u).map(Self::from) - } -} - -/// Workload steps beyond this are ignored, bounding one execution's time. Shared by every input -/// model that runs a workload, not just [`Case`]. +/// Workload steps beyond this are ignored, bounding one execution's time. Shared by every +/// input model that runs a workload. pub(crate) const MAX_OPS: usize = 64; /// Flips beyond this are ignored. Shared the same way as [`MAX_OPS`]. pub(crate) const MAX_FLIPS: usize = 16; -/// One of SQLite3MC's native cipher schemes, every one but `sqlcipher`. +/// One of SQLite3MC's own cipher schemes. /// -/// The differential fuzzer above already covers `sqlcipher` against a real second implementation. -/// These have none, so they are tested for self-consistency instead: round-trip, a wrong key never -/// succeeding, and, where the scheme actually authenticates its pages, tamper detection. +/// Each is tested for self-consistency: round-trip, a wrong key never succeeding, and, where +/// the scheme actually authenticates its pages, tamper detection. #[derive(Arbitrary, Debug, Clone, Copy, PartialEq, Eq)] pub enum Cipher { /// `aes128cbc`. No KDF parameter, no raw key (`GenerateKeyAES128Cipher` always pads and @@ -307,16 +126,16 @@ pub enum Cipher { /// `chacha20`. Settable PBKDF2 `kdf_iter`, a raw key with an optional embedded salt /// (`sqlite3mcExtractRawKey`), a plaintext header, a 16-byte per-page authentication tag. ChaCha20, - /// `rc4`. `legacy` is present but fixed at `RC4_LEGACY_DEFAULT` (min equals max), no raw key - /// (`GenerateKeyRC4Cipher` always SHA1-digests the given bytes as a passphrase), no plaintext - /// header, no page authentication (the weakest scheme on purpose, kept for legacy databases). - Rc4, - /// `ascon128`. No legacy variant. Settable PBKDF2 `kdf_iter`, a raw key with an optional + /// `sqlcipher`, SQLite3MC's own SQLCipher-compatible scheme. Settable PBKDF2 `kdf_iter` + /// (`kdf_algorithm` picks its hash), a raw key with an optional embedded salt, a plaintext + /// header, and, with `hmac_use` on, a page HMAC whose digest `hmac_algorithm` sizes. + SqlCipher, + /// `ascon128`. No `legacy` parameter. Settable PBKDF2 `kdf_iter`, a raw key with an optional /// embedded salt, a plaintext header, a 16-byte per-page authentication tag. Ascon128, - /// `aegis`. No legacy variant. Argon2id key derivation, a raw key with an optional embedded - /// salt, a plaintext header, AEAD by design. `algorithm` picks AEGIS-128 (16-byte key) or - /// AEGIS-256 (32-byte key). + /// `aegis`. No `legacy` parameter. Argon2id key derivation, a raw key with an optional + /// embedded salt, a plaintext header, AEAD by design. `algorithm` picks AEGIS-128 (16-byte + /// key) or AEGIS-256 (32-byte key). Aegis, } @@ -328,26 +147,19 @@ impl Cipher { Self::Aes128 => "aes128cbc", Self::Aes256 => "aes256cbc", Self::ChaCha20 => "chacha20", - Self::Rc4 => "rc4", + Self::SqlCipher => "sqlcipher", Self::Ascon128 => "ascon128", Self::Aegis => "aegis", } } - /// Whether `legacy` is actually settable, as opposed to merely present but fixed, as it is - /// for `Rc4` (`RC4_LEGACY_DEFAULT` is both its minimum and its maximum). - #[must_use] - pub const fn has_legacy(self) -> bool { - matches!(self, Self::Aes128 | Self::Aes256 | Self::ChaCha20) - } - - /// Whether `legacy_page_size` is one of this scheme's own parameters. Unlike - /// [`Cipher::has_legacy`], `Rc4` has this even though its own `legacy` is fixed. + /// Whether the scheme's own parameter table has `legacy`, which the harness pins to `0` + /// so a changed upstream default never re-enables legacy encryption. #[must_use] - pub const fn has_legacy_page_size(self) -> bool { + pub const fn has_legacy_param(self) -> bool { matches!( self, - Self::Aes128 | Self::Aes256 | Self::ChaCha20 | Self::Rc4 + Self::Aes128 | Self::Aes256 | Self::ChaCha20 | Self::SqlCipher ) } @@ -356,43 +168,45 @@ impl Cipher { /// its own, different, Argon2id parameters instead. #[must_use] pub const fn has_kdf_iter(self) -> bool { - matches!(self, Self::ChaCha20 | Self::Ascon128) + matches!(self, Self::ChaCha20 | Self::SqlCipher | Self::Ascon128) } - /// Whether this scheme's key setup ever calls `sqlite3mcExtractRawKey`, so a raw key, with or - /// without an embedded salt, bypasses derivation entirely. `Aes128`, `Aes256` and `Rc4` always - /// treat whatever bytes `key()` is given as a passphrase, so a hex string drawn to look like a - /// raw key would just be hashed as one. + /// Whether this scheme's key setup ever calls `sqlite3mcExtractRawKey`, so a raw key, with + /// or without an embedded salt, bypasses derivation entirely. `Aes128` and `Aes256` always + /// treat whatever bytes `key()` is given as a passphrase, so a hex string drawn to look like + /// a raw key would just be hashed as one. #[must_use] pub const fn supports_raw_key(self) -> bool { - matches!(self, Self::ChaCha20 | Self::Ascon128 | Self::Aegis) + matches!( + self, + Self::ChaCha20 | Self::SqlCipher | Self::Ascon128 | Self::Aegis + ) } - /// Whether `plaintext_header_size` is one of this scheme's own parameters. Every scheme that - /// has it also has [`Cipher::supports_raw_key`], not a coincidence: a plaintext header leaves - /// the file's own salt bytes unencrypted, so recovering the salt to rederive a passphrase key - /// on reopen needs it supplied back explicitly, which only a raw key with an embedded salt - /// does ([`NativeConfig::arbitrary`] only draws a plaintext header for that key form). + /// Whether `plaintext_header_size` is one of this scheme's own parameters. Every scheme + /// that has it also has [`Cipher::supports_raw_key`], not a coincidence: a plaintext header + /// leaves the file's own salt bytes unencrypted, so recovering the salt to rederive a + /// passphrase key on reopen needs it supplied back explicitly, which only a raw key with an + /// embedded salt does ([`NativeConfig::arbitrary`] only draws a plaintext header for that + /// key form). #[must_use] pub const fn has_plaintext_header(self) -> bool { - matches!(self, Self::ChaCha20 | Self::Ascon128 | Self::Aegis) - } - - /// Whether this scheme authenticates its pages, so tampering is expected to be caught. - #[must_use] - pub const fn authenticated(self) -> bool { - matches!(self, Self::ChaCha20 | Self::Ascon128 | Self::Aegis) + matches!( + self, + Self::ChaCha20 | Self::SqlCipher | Self::Ascon128 | Self::Aegis + ) } /// How many leading bytes of a passphrase this scheme's own `GenerateKey*Cipher` actually - /// reads, when it reads fewer than the whole thing. `Aes128` and `Aes256` both pad or truncate - /// through `sqlite3mcPadPassword`, which copies at most 32 bytes; every other scheme consumes - /// the full password (PBKDF2, Argon2id, or a plain hash all take an explicit length). + /// reads, when it reads fewer than the whole thing. `Aes128` and `Aes256` both pad or + /// truncate through `sqlite3mcPadPassword`, which copies at most 32 bytes; every other + /// scheme consumes the full password (PBKDF2, Argon2id, or a plain hash all take an + /// explicit length). #[must_use] pub const fn passphrase_prefix_len(self) -> Option { match self { Self::Aes128 | Self::Aes256 => Some(32), - Self::ChaCha20 | Self::Rc4 | Self::Ascon128 | Self::Aegis => None, + Self::ChaCha20 | Self::SqlCipher | Self::Ascon128 | Self::Aegis => None, } } @@ -400,8 +214,8 @@ impl Cipher { #[must_use] pub const fn key_len(self, aegis_algorithm_256: bool) -> usize { match self { - Self::Aes128 | Self::Rc4 => 16, - Self::Aes256 | Self::ChaCha20 | Self::Ascon128 => 32, + Self::Aes128 => 16, + Self::Aes256 | Self::ChaCha20 | Self::SqlCipher | Self::Ascon128 => 32, Self::Aegis => { if aegis_algorithm_256 { 32 @@ -415,9 +229,9 @@ impl Cipher { /// How a native-cipher database is keyed. /// -/// Unlike [`Key`], the raw forms are only ever drawn for a [`Cipher`] that -/// [`Cipher::supports_raw_key`] allows, [`NativeConfig::arbitrary`] enforces it; every other -/// scheme treats whatever bytes it is given as a passphrase. +/// The raw forms are only ever drawn for a [`Cipher`] that [`Cipher::supports_raw_key`] +/// allows, [`NativeConfig::arbitrary`] enforces it; every other scheme treats whatever bytes +/// it is given as a passphrase. #[derive(Debug, Clone, PartialEq, Eq)] pub enum NativeKey { /// A raw key, truncated to the scheme's own key length when applied. @@ -430,7 +244,7 @@ pub enum NativeKey { salt: [u8; 16], }, /// A passphrase, run through this scheme's own KDF when it has one, or hashed by its fixed - /// legacy scheme when it does not. + /// scheme when it does not. Passphrase { /// The passphrase, never empty. bytes: Vec, @@ -476,20 +290,22 @@ impl<'a> Arbitrary<'a> for NativeKey { } } -/// The cipher settings for one native-scheme execution, only the fields [`Cipher`] itself supports -/// ever drawn or applied. +/// The cipher settings for one native-scheme execution, only the fields [`Cipher`] itself +/// supports ever drawn or applied. #[derive(Debug, Clone, PartialEq, Eq)] pub struct NativeConfig { /// Which scheme. pub cipher: Cipher, - /// `legacy`, when [`Cipher::has_legacy`]. - pub legacy: Option, - /// `legacy_page_size`, a power of two from 512 to 65536, when [`Cipher::has_legacy_page_size`]. - pub page_size: Option, + /// `kdf_algorithm`, `SqlCipher` only, or the scheme's default when `None`. + pub kdf_algorithm: Option, + /// `hmac_algorithm`, `SqlCipher` only, or the scheme's default when `None`. + pub hmac_algorithm: Option, + /// `hmac_use`, `SqlCipher` only, or the scheme's default when `None`. + pub hmac_use: Option, /// `plaintext_header_size`, when [`Cipher::has_plaintext_header`] and the key is - /// [`NativeKey::RawWithSalt`]. A passphrase key's salt would otherwise be lost on reopen, since - /// a plaintext header leaves no encrypted copy of it anywhere in the file (issue #209 on - /// `SQLite3MultipleCiphers`, which documents `cipher_salt` as the required workaround). + /// [`NativeKey::RawWithSalt`]. A passphrase key's salt would otherwise be lost on reopen, + /// since a plaintext header leaves no encrypted copy of it anywhere in the file (issue #209 + /// on `SQLite3MultipleCiphers`, which documents `cipher_salt` as the required workaround). pub plaintext_header_size: Option, /// `algorithm`, `Aegis` only: `true` picks AEGIS-256 (32-byte key), `false` AEGIS-128. pub aegis_algorithm_256: bool, @@ -500,11 +316,10 @@ pub struct NativeConfig { impl<'a> Arbitrary<'a> for NativeConfig { fn arbitrary(u: &mut Unstructured<'a>) -> Result { let cipher: Cipher = u.arbitrary()?; - let legacy = cipher.has_legacy().then(|| u.arbitrary()).transpose()?; - let page_size = if cipher.has_legacy_page_size() && u.arbitrary()? { - Some(1 << u.int_in_range(9..=16)?) + let (kdf_algorithm, hmac_algorithm, hmac_use) = if matches!(cipher, Cipher::SqlCipher) { + (u.arbitrary()?, u.arbitrary()?, u.arbitrary()?) } else { - None + (None, None, None) }; let aegis_algorithm_256 = matches!(cipher, Cipher::Aegis) && u.arbitrary()?; let key = NativeKey::arbitrary_for(u, cipher)?; @@ -516,8 +331,9 @@ impl<'a> Arbitrary<'a> for NativeConfig { }; Ok(Self { cipher, - legacy, - page_size, + kdf_algorithm, + hmac_algorithm, + hmac_use, plaintext_header_size, aegis_algorithm_256, key, @@ -531,30 +347,30 @@ impl NativeConfig { pub fn same_layout(&self, other: &Self) -> bool { let Self { cipher, - legacy, - page_size, + kdf_algorithm, + hmac_algorithm, + hmac_use, plaintext_header_size, aegis_algorithm_256, key: _, } = self; *cipher == other.cipher - && *legacy == other.legacy - && *page_size == other.page_size + && *kdf_algorithm == other.kdf_algorithm + && *hmac_algorithm == other.hmac_algorithm + && *hmac_use == other.hmac_use && *plaintext_header_size == other.plaintext_header_size && *aegis_algorithm_256 == other.aegis_algorithm_256 } - /// Whether this configuration encrypts page 1's header bytes 16 to 23, so nothing on disk - /// tells SQLite the page size before the key is set: `rc4` always, and `aes128cbc`, - /// `aes256cbc` and `chacha20` in `legacy` mode unless a plaintext header covers them. + /// Whether this configuration authenticates its pages, so tampering is expected to be + /// caught. `SqlCipher` does so only while `hmac_use` holds, its own default being on. #[must_use] - pub fn hides_page_size(&self) -> bool { - let whole_page_one = match self.cipher { - Cipher::Rc4 => true, - Cipher::Aes128 | Cipher::Aes256 | Cipher::ChaCha20 => self.legacy == Some(true), - Cipher::Ascon128 | Cipher::Aegis => false, - }; - whole_page_one && self.plaintext_header_size.unwrap_or(0) < 24 + pub fn authenticated(&self) -> bool { + match self.cipher { + Cipher::Aes128 | Cipher::Aes256 => false, + Cipher::ChaCha20 | Cipher::Ascon128 | Cipher::Aegis => true, + Cipher::SqlCipher => self.hmac_use.unwrap_or(true), + } } } @@ -566,7 +382,8 @@ pub struct NativeCase { /// Workload, at most [`MAX_OPS`] steps of it. pub ops: Vec, /// Damage applied to a copy of the finished file, at most [`MAX_FLIPS`] flips of it. Only - /// meaningful, and only applied, when [`Cipher::authenticated`]. + /// meaningful, and only applied, when the configuration [`NativeConfig::authenticated`] + /// authenticates its pages. pub damage: Vec, /// A key to reopen with after the workload, almost certainly not the one that wrote it. pub wrong_key: NativeKey, @@ -651,8 +468,8 @@ pub struct WalCase { /// The cipher and key. pub config: NativeConfig, /// `mc_legacy_wal`: `true` selects the older WAL frame encryption, which the project's own - /// source comments recommend only for recovering journals written before version 1.3.0, not - /// for general use. + /// source comments recommend only for recovering journals written before version 1.3.0, + /// not for general use. pub legacy_wal: bool, /// Workload, at most [`MAX_OPS`] steps of it. pub ops: Vec, @@ -712,11 +529,8 @@ pub struct AttachCase { pub detach_reattach: bool, } -/// A `PRAGMA page_size` value, a power of two from 512 to 65536. -/// -/// Distinct from [`NativeConfig::page_size`] (the cipher's own `legacy_page_size` parameter): -/// this is the ordinary SQLite btree page size, set through SQL rather than -/// `sqlite3mc_config_cipher`. +/// A `PRAGMA page_size` value, a power of two from 512 to 65536, the ordinary SQLite btree +/// page size, set through SQL rather than `sqlite3mc_config_cipher`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PageSize(u32); @@ -738,8 +552,8 @@ impl<'a> Arbitrary<'a> for PageSize { /// unrelated content, then runs `sqlite3_backup_init`/`_step`/`_finish` between them. /// /// SQLite3MC's own compatibility guard (`sqlite3mcIsBackupSupported`, called from -/// `sqlite3_backup_init`) lets pairs disagreeing on reserved bytes through, so a backup between them -/// corrupts the destination (`upstream/sqlite3mc-backup-guard-ignores-reserve.md`). +/// `sqlite3_backup_init`) lets pairs disagreeing on reserved bytes through, so a backup between +/// them corrupts the destination (`upstream/sqlite3mc-backup-guard-ignores-reserve.md`). /// /// Oracle: when [`BackupCase::src`] and [`BackupCase::dest`] are laid out identically, every /// cipher setting but the key and the `PRAGMA page_size` equal, and every step reports success, diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index 7aef8e5..9248adf 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -1,6 +1,6 @@ -//! Fuzzing SQLite3MC against SQLCipher differentially, its own native ciphers for -//! self-consistency, its rekey support, its WAL journal mode, its `ATTACH DATABASE` support, its -//! `sqlite3_backup_*` API, and its shared-cache mode, on the same SQLite. +//! Fuzzing SQLite3MC's own cipher schemes for self-consistency, its rekey support, its WAL +//! journal mode, its `ATTACH DATABASE` support, its `sqlite3_backup_*` API, and its shared-cache +//! mode. #![expect( clippy::redundant_pub_crate, @@ -8,14 +8,13 @@ )] mod db; -mod entropy; mod ffi; mod input; mod run; pub mod seedgen; pub use input::{ - Algorithm, AttachCase, BackupCase, Case, Checkpoint, Cipher, Config, Key, NativeCase, - NativeKey, Op, RekeyAction, RekeyCase, SharedCacheCase, SiblingKey, Side, Table, WalCase, + Algorithm, AttachCase, BackupCase, Checkpoint, Cipher, NativeCase, NativeKey, Op, RekeyAction, + RekeyCase, SharedCacheCase, SiblingKey, Table, WalCase, }; -pub use run::{run, run_attach, run_backup, run_native, run_rekey, run_shared_cache, run_wal}; +pub use run::{run_attach, run_backup, run_native, run_rekey, run_shared_cache, run_wal}; diff --git a/fuzz/src/run.rs b/fuzz/src/run.rs index b45666e..0360ddd 100644 --- a/fuzz/src/run.rs +++ b/fuzz/src/run.rs @@ -1,9 +1,9 @@ -//! One execution: write with one side, read with both, damage a copy, read that with both. +//! One execution: write, read back, damage a copy, read that, through SQLite3MC's own ciphers. use core::ffi::{c_int, CStr}; use std::{ ffi::CString, - fmt::{Debug, Write as _}, + fmt::Write as _, fs, os::unix::ffi::OsStrExt, path::{Path, PathBuf}, @@ -12,15 +12,11 @@ use std::{ use crate::{ db::{Code, Connection, Param, Value}, - ffi::{ - Api, SQLCIPHER, SQLITE3MC, SQLITE_DONE, SQLITE_OPEN_CREATE, SQLITE_OPEN_READONLY, - SQLITE_OPEN_READWRITE, - }, + ffi::{SQLITE_DONE, SQLITE_OPEN_CREATE, SQLITE_OPEN_READONLY, SQLITE_OPEN_READWRITE}, input::{ - Algorithm, AttachCase, AttachedDb, BackupCase, Case, Cell, Cipher, Column, Config, Key, - NativeCase, NativeConfig, NativeKey, Op, PageSize, RekeyAction, RekeyCase, SharedCacheCase, - SiblingKey, Side, Table, WalCase, MAX_ATTACHED, MAX_ATTACH_ROWS, MAX_FLIPS, MAX_OPS, - MAX_SIBLINGS, + Algorithm, AttachCase, AttachedDb, BackupCase, Cell, Cipher, Column, NativeCase, + NativeConfig, NativeKey, Op, PageSize, RekeyAction, RekeyCase, SharedCacheCase, SiblingKey, + Table, WalCase, MAX_ATTACHED, MAX_ATTACH_ROWS, MAX_FLIPS, MAX_OPS, MAX_SIBLINGS, }, }; @@ -41,77 +37,8 @@ const TABLE_NAMES: [&str; 3] = ["t0", "t1", "t2"]; /// every native scheme leaves outside its AEAD coverage, independent of `plaintext_header_size`. const CIPHER_PAGE1_OFFSET: usize = 24; -/// Runs `case`, panicking when the libraries disagree or the writer cannot read its own file. -/// -/// # Panics -/// -/// On a divergence, or when a library refuses a setting or step the harness generates as valid. -pub fn run(case: &Case) { - static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); - - let dir = WORKDIR.as_path(); - let clean = dir.join("clean.db"); - let damaged = dir.join("damaged.db"); - remove(&clean); - remove(&damaged); - - let writer = case.writer; - let reader = match writer { - Side::SqlCipher => Side::Sqlite3mc, - Side::Sqlite3mc => Side::SqlCipher, - }; - write(writer, &clean, case); - - let own = dump(api(writer), &clean, |c| configure(c, writer, &case.config)); - assert!( - clean_read(&own), - "{} cannot read back its own file for {case:#?}: {}", - name(writer), - describe(own.iter().rev().take(3)), - ); - compare( - case, - "the clean file", - writer, - &own, - reader, - &dump(api(reader), &clean, |c| configure(c, reader, &case.config)), - ); - - let mut bytes = fs::read(&clean).expect("the clean file exists"); - let flips = &case.damage[..case.damage.len().min(MAX_FLIPS)]; - if !bytes.is_empty() && !flips.is_empty() { - let len = u64::try_from(bytes.len()).expect("file length fits u64"); - for flip in flips { - let offset = - usize::try_from(u64::from(flip.offset) % len).expect("offset is below the length"); - // SQLite3MC reads this salt from the file (upstream/sqlite3mc-sqlcipher-explicit-salt.md). - if offset < 16 && case.config.explicit_salt_unused_by_sqlite3mc() { - continue; - } - bytes[offset] ^= flip.mask; - } - fs::write(&damaged, &bytes).expect("the work directory is writable"); - let by_writer = dump(api(writer), &damaged, |c| { - configure(c, writer, &case.config) - }); - let by_reader = dump(api(reader), &damaged, |c| { - configure(c, reader, &case.config) - }); - compare( - case, - "the damaged file", - writer, - &by_writer, - reader, - &by_reader, - ); - } - - remove(&clean); - remove(&damaged); -} +/// The page size the native targets see: they never set `PRAGMA page_size`. +const PAGE_SIZE: usize = 4096; /// Whether `log` is a full, successful dump: no failed step, ending in an `ok` integrity check. fn clean_read(log: &[Record]) -> bool { @@ -133,7 +60,7 @@ fn clean_read(log: &[Record]) -> bool { /// When SQLite3MC refuses a setting or step the harness generates as valid, or an oracle fails. pub fn run_native(case: &NativeCase) { static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); + let _serial = begin_run(&SERIAL); let dir = WORKDIR.as_path(); let clean = dir.join("native-clean.db"); @@ -173,7 +100,7 @@ pub fn run_native(case: &NativeCase) { ); } - if cipher.authenticated() { + if case.config.authenticated() { let original = fs::read(&clean).expect("the clean file exists"); let mut bytes = original.clone(); let flips = &case.damage[..case.damage.len().min(MAX_FLIPS)]; @@ -184,12 +111,19 @@ pub fn run_native(case: &NativeCase) { // docs state); tampering it is never expected to be caught. let unauthenticated = usize::from(case.config.plaintext_header_size.unwrap_or(0)).max(CIPHER_PAGE1_OFFSET); + // `sqlcipher` with a SHA1 HMAC stores its digest in a 32-byte per-page slot but verifies + // only the first 20 bytes, so each page's last 12 slot bytes are unauthenticated. + let page_pad = usize::from( + cipher == Cipher::SqlCipher && case.config.hmac_algorithm == Some(Algorithm::Sha1), + ) * 12; if !bytes.is_empty() && !flips.is_empty() { let len = u64::try_from(bytes.len()).expect("file length fits u64"); for flip in flips { let offset = usize::try_from(u64::from(flip.offset) % len) .expect("offset is below the length"); - if offset < unauthenticated { + if offset < unauthenticated + || (page_pad > 0 && offset % PAGE_SIZE >= PAGE_SIZE - page_pad) + { continue; } bytes[offset] ^= flip.mask; @@ -215,7 +149,7 @@ pub fn run_native(case: &NativeCase) { /// Everything SQLite3MC can read back from `path` with `config`'s key, up to the first failure. fn dump_native(path: &Path, config: &NativeConfig) -> Vec { - dump(&SQLITE3MC, path, |c| configure_native(c, config)) + dump(path, |c| configure_native(c, config)) } /// Runs `case` against SQLite3MC's rekey support. @@ -230,7 +164,7 @@ fn dump_native(path: &Path, config: &NativeConfig) -> Vec { /// valid, or an oracle fails. pub fn run_rekey(case: &RekeyCase) { static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); + let _serial = begin_run(&SERIAL); let dir = WORKDIR.as_path(); let clean = dir.join("rekey.db"); @@ -275,7 +209,7 @@ pub fn run_rekey(case: &RekeyCase) { RekeyAction::Decrypt => None, }; let own = after_config.as_ref().map_or_else( - || dump(&SQLITE3MC, &clean, |_| Ok(())), + || dump(&clean, |_| Ok(())), |config| dump_native(&clean, config), ); assert!( @@ -316,7 +250,7 @@ pub fn run_rekey(case: &RekeyCase) { /// When SQLite3MC refuses a setting or step the harness generates as valid, or the oracle fails. pub fn run_wal(case: &WalCase) { static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); + let _serial = begin_run(&SERIAL); let dir = WORKDIR.as_path(); let clean = dir.join("wal.db"); @@ -389,7 +323,7 @@ pub fn run_wal(case: &WalCase) { /// file fails to read back cleanly afterward. pub fn run_attach(case: &AttachCase) { static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); + let _serial = begin_run(&SERIAL); let dir = WORKDIR.as_path(); let main_path = dir.join("attach-main.db"); @@ -514,7 +448,7 @@ fn write_native(path: &Path, config: &NativeConfig, rows: usize) { /// after a failed `ATTACH` is skipped; every other step is tolerated to fail, a wrong or /// inherited key means they are expected to. fn exercise_attached( - connection: &Connection<'_>, + connection: &Connection, index: usize, attached: &AttachedDb, cross_copy: bool, @@ -557,10 +491,7 @@ fn exercise_attached( /// identically, every cipher setting but the key and the `PRAGMA page_size` equal, has to reopen /// cleanly with the destination's own true key after the backup reports full success. A failure /// there is the defect `utelle/SQLite3MultipleCiphers` issue #158 described, and exactly what this -/// harness exists to catch a recurrence of. The one identically laid out pair exempt is a -/// destination that hides its page size and has `PRAGMA page_size` below the page size SQLite3MC -/// assumes on reopen, `legacy_page_size` or 4096 bytes, which it cannot reopen at all, backup or -/// not (`upstream/sqlite3mc-rc4-short-read-skips-decryption.md`). +/// harness exists to catch a recurrence of. /// /// # Panics /// @@ -568,7 +499,7 @@ fn exercise_attached( /// two identically laid out databases reported full success and left an unreadable destination. pub fn run_backup(case: &BackupCase) { static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); + let _serial = begin_run(&SERIAL); let dir = WORKDIR.as_path(); let src_path = dir.join("backup-src.db"); @@ -586,10 +517,6 @@ pub fn run_backup(case: &BackupCase) { && finish_result.is_ok() && case.src_page_size == case.dest_page_size && case.src.same_layout(&case.dest) - && !(case.dest.hides_page_size() - && case - .dest_page_size - .is_some_and(|size| size.get() < case.dest.page_size.unwrap_or(4096))) { drop(src); drop(dest); @@ -611,12 +538,12 @@ pub fn run_backup(case: &BackupCase) { /// Opens a new SQLite3MC file at `path`, stages and applies `config`'s cipher and key, sets /// `page_size` through `PRAGMA page_size` first when given, then runs `ops`. -fn open_for_backup<'a>( +fn open_for_backup( path: &Path, config: &NativeConfig, page_size: Option, ops: &[Op], -) -> Connection<'a> { +) -> Connection { let connection = open_native(path, config, "file"); if let Some(page_size) = page_size { let text = sql(&format!("PRAGMA page_size={}", page_size.get())); @@ -636,7 +563,7 @@ fn open_for_backup<'a>( /// key when given, omitting the `KEY` clause entirely otherwise (which SQLite3MC resolves by /// copying the main database's own current codec verbatim). Returns whether it succeeded. fn attach( - connection: &Connection<'_>, + connection: &Connection, db_name: &str, path_str: &str, attach_key: Option<&NativeConfig>, @@ -679,10 +606,9 @@ fn attach( /// codec (`utelle/SQLite3MultipleCiphers` issue #281), so such a run skips the file check. pub fn run_shared_cache(case: &SharedCacheCase) { static SERIAL: Mutex<()> = Mutex::new(()); - let _serial = begin_run(&SERIAL, case); + let _serial = begin_run(&SERIAL); - crate::db::enable_shared_cache(&SQLITE3MC, true) - .expect("SQLite3MC accepts sqlite3_enable_shared_cache(1)"); + crate::db::enable_shared_cache(true).expect("SQLite3MC accepts sqlite3_enable_shared_cache(1)"); let dir = WORKDIR.as_path(); let path = dir.join("shared-cache.db"); @@ -702,11 +628,9 @@ pub fn run_shared_cache(case: &SharedCacheCase) { let mut one_key = true; let mut foreign_write = false; for sibling in case.siblings.iter().take(MAX_SIBLINGS) { - let Ok(connection) = Connection::open( - &SQLITE3MC, - &c_path(&path), - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - ) else { + let Ok(connection) = + Connection::open(&c_path(&path), SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) + else { continue; }; let config = match &sibling.key { @@ -750,20 +674,6 @@ pub fn run_shared_cache(case: &SharedCacheCase) { remove(&path); } -const fn api(side: Side) -> &'static Api { - match side { - Side::SqlCipher => &SQLCIPHER, - Side::Sqlite3mc => &SQLITE3MC, - } -} - -const fn name(side: Side) -> &'static str { - match side { - Side::SqlCipher => "SQLCipher", - Side::Sqlite3mc => "SQLite3MC", - } -} - /// A per-process directory on tmpfs where there is one. static WORKDIR: LazyLock = LazyLock::new(|| { let shm = Path::new("/dev/shm"); @@ -777,17 +687,12 @@ static WORKDIR: LazyLock = LazyLock::new(|| { dir }); -/// Locks `serial` and reseeds the deterministic entropy stream from `case`, so the same case -/// always draws the same salts and IVs on replay, but different cases are not forced to start -/// from the identical stream. The returned guard must stay alive for the whole run, SQLCipher is -/// compiled with no-op mutexes and every execution reuses one directory. -fn begin_run<'a>(serial: &'a Mutex<()>, case: &impl Debug) -> MutexGuard<'a, ()> { +/// Locks `serial` so the fixed file names in the shared work directory see one run at a time. +/// The guard must stay alive for the whole run. +fn begin_run(serial: &Mutex<()>) -> MutexGuard<'_, ()> { let guard = serial .lock() .unwrap_or_else(std::sync::PoisonError::into_inner); - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - std::hash::Hash::hash(&format!("{case:?}"), &mut hasher); - crate::entropy::reset(std::hash::Hasher::finish(&hasher)); guard } @@ -813,33 +718,6 @@ fn hex(bytes: &[u8], out: &mut String) { } } -fn key_bytes(key: &Key) -> Vec { - match key { - Key::Raw(key) => { - let mut text = String::from("x'"); - hex(key, &mut text); - text.push('\''); - text.into_bytes() - } - Key::RawWithSalt { key, salt, .. } => { - let mut text = String::from("x'"); - hex(key, &mut text); - hex(salt, &mut text); - text.push('\''); - text.into_bytes() - } - Key::Passphrase { bytes, .. } => bytes.clone(), - } -} - -/// Applies `config` and the key, returning only a refused key as an observation. -fn configure(connection: &Connection<'_>, side: Side, config: &Config) -> Result<(), Code> { - match side { - Side::Sqlite3mc => configure_sqlite3mc(connection, config), - Side::SqlCipher => configure_sqlcipher(connection, config), - } -} - const fn sqlite3mc_algorithm(algorithm: Algorithm) -> c_int { match algorithm { Algorithm::Sha1 => 0, @@ -848,95 +726,6 @@ const fn sqlite3mc_algorithm(algorithm: Algorithm) -> c_int { } } -fn configure_sqlite3mc(connection: &Connection<'_>, config: &Config) -> Result<(), Code> { - let cipher = connection.sqlite3mc_cipher_index(c"sqlcipher"); - assert_eq!( - connection.sqlite3mc_config(c"cipher", cipher), - cipher, - "SQLite3MC refused its sqlcipher scheme" - ); - let set = |param: &CStr, value: c_int| { - let set = connection.sqlite3mc_config_cipher(c"sqlcipher", param, value); - assert_eq!(set, value, "SQLite3MC refused {param:?} = {value}"); - }; - // `legacy` first, since it resets the other parameters to that version's defaults. - set(c"legacy", c_int::from(config.compatibility)); - if let Some(page_size) = config.page_size { - set( - c"legacy_page_size", - c_int::try_from(page_size).expect("page sizes fit an int"), - ); - } - if let Some(algorithm) = config.kdf_algorithm { - set(c"kdf_algorithm", sqlite3mc_algorithm(algorithm)); - } - if let Some(algorithm) = config.hmac_algorithm { - set(c"hmac_algorithm", sqlite3mc_algorithm(algorithm)); - } - if let Some(hmac) = config.hmac { - set(c"hmac_use", c_int::from(hmac)); - } - if let Key::Passphrase { kdf_iter, .. } = config.key { - set(c"kdf_iter", c_int::from(kdf_iter)); - } - if config.plaintext_header() > 0 { - set( - c"plaintext_header_size", - c_int::from(config.plaintext_header()), - ); - } - connection.key(&key_bytes(&config.key)) -} - -fn configure_sqlcipher(connection: &Connection<'_>, config: &Config) -> Result<(), Code> { - // SQLCipher ignores cipher pragmas until the key has created the codec. - connection.key(&key_bytes(&config.key))?; - let pragma = |text: String| { - let result = connection.execute(&sql(&text), &[]); - assert_eq!(result, Ok(()), "SQLCipher refused {text}"); - }; - pragma(format!( - "PRAGMA cipher_compatibility = {}", - config.compatibility - )); - if let Some(page_size) = config.page_size { - pragma(format!("PRAGMA cipher_page_size = {page_size}")); - } - let hash = |algorithm| match algorithm { - Algorithm::Sha1 => "SHA1", - Algorithm::Sha256 => "SHA256", - Algorithm::Sha512 => "SHA512", - }; - if let Some(algorithm) = config.kdf_algorithm { - pragma(format!( - "PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_{}", - hash(algorithm) - )); - } - if let Some(algorithm) = config.hmac_algorithm { - pragma(format!( - "PRAGMA cipher_hmac_algorithm = HMAC_{}", - hash(algorithm) - )); - } - if let Some(hmac) = config.hmac { - pragma(format!( - "PRAGMA cipher_use_hmac = {}", - if hmac { "ON" } else { "OFF" } - )); - } - if let Key::Passphrase { kdf_iter, .. } = config.key { - pragma(format!("PRAGMA kdf_iter = {kdf_iter}")); - } - if config.plaintext_header() > 0 { - pragma(format!( - "PRAGMA cipher_plaintext_header_size = {}", - config.plaintext_header() - )); - } - Ok(()) -} - /// `key`'s bytes, truncated to `key_len` where that is shorter than the form's own natural /// length, matching what [`Cipher::key_len`] says the scheme actually consumes. fn native_key_bytes(key: &NativeKey, key_len: usize) -> Vec { @@ -1008,9 +797,9 @@ const fn aegis_algorithm(select_256: bool) -> c_int { /// Sets every SQLite3MC cipher parameter `config` carries, without touching the key. The /// resulting pending state is consumed by whichever key-setup call runs next on this /// connection: [`Connection::key`], `ATTACH ... KEY`, or [`Connection::rekey`]. -fn stage_cipher(connection: &Connection<'_>, config: &NativeConfig) { +fn stage_cipher(connection: &Connection, config: &NativeConfig) { let cipher_name = CString::new(config.cipher.name()).expect("cipher names have no NUL"); - let index = connection.sqlite3mc_cipher_index(&cipher_name); + let index = Connection::sqlite3mc_cipher_index(&cipher_name); assert_eq!( connection.sqlite3mc_config(c"cipher", index), index, @@ -1026,14 +815,20 @@ fn stage_cipher(connection: &Connection<'_>, config: &NativeConfig) { config.cipher.name() ); }; - if let Some(legacy) = config.legacy { - set(c"legacy", c_int::from(legacy)); + // `legacy` first, since setting it resets the other parameters to that version's defaults. + if config.cipher.has_legacy_param() { + set(c"legacy", 0); } - if let Some(page_size) = config.page_size { - set( - c"legacy_page_size", - c_int::try_from(page_size).expect("page sizes fit an int"), - ); + if matches!(config.cipher, Cipher::SqlCipher) { + if let Some(algorithm) = config.kdf_algorithm { + set(c"kdf_algorithm", sqlite3mc_algorithm(algorithm)); + } + if let Some(algorithm) = config.hmac_algorithm { + set(c"hmac_algorithm", sqlite3mc_algorithm(algorithm)); + } + if let Some(hmac_use) = config.hmac_use { + set(c"hmac_use", c_int::from(hmac_use)); + } } if matches!(config.cipher, Cipher::Aegis) { set(c"algorithm", aegis_algorithm(config.aegis_algorithm_256)); @@ -1050,7 +845,7 @@ fn stage_cipher(connection: &Connection<'_>, config: &NativeConfig) { /// Applies `config` and the key to SQLite3MC's own native scheme, returning only a refused key as /// an observation. -fn configure_native(connection: &Connection<'_>, config: &NativeConfig) -> Result<(), Code> { +fn configure_native(connection: &Connection, config: &NativeConfig) -> Result<(), Code> { stage_cipher(connection, config); connection.key(&native_key_bytes( &config.key, @@ -1061,19 +856,15 @@ fn configure_native(connection: &Connection<'_>, config: &NativeConfig) -> Resul /// Opens a new SQLite3MC file at `path` and applies `config`'s cipher and key, panicking with /// `what` (e.g. `"file"`, `"main database"`) naming the file in the message if SQLite3MC refuses /// to create or key it. -fn open_native<'a>(path: &Path, config: &NativeConfig, what: &str) -> Connection<'a> { +fn open_native(path: &Path, config: &NativeConfig, what: &str) -> Connection { let cipher = config.cipher; - let connection = Connection::open( - &SQLITE3MC, - &c_path(path), - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - ) - .unwrap_or_else(|code| { - panic!( - "SQLite3MC cannot create a {} {what}: {code:?}", - cipher.name() - ) - }); + let connection = Connection::open(&c_path(path), SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) + .unwrap_or_else(|code| { + panic!( + "SQLite3MC cannot create a {} {what}: {code:?}", + cipher.name() + ) + }); if let Err(code) = configure_native(&connection, config) { panic!( "SQLite3MC refused the key of a new {} {what}: {code:?}", @@ -1131,25 +922,10 @@ impl<'a> Owned<'a> { } } -/// Creates the database and runs the workload, whose steps are all valid SQL. -fn write(side: Side, path: &Path, case: &Case) { - let connection = Connection::open( - api(side), - &c_path(path), - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - ) - .unwrap_or_else(|code| panic!("{} cannot create a database: {code:?}", name(side))); - if let Err(code) = configure(&connection, side, &case.config) { - panic!("{} refused the key of a new database: {code:?}", name(side)); - } - run_workload(&connection, name(side), &case.ops, case); -} - /// Runs `ops` against an already-open, already-configured connection, panicking with `label` and -/// `context`'s own Debug output naming what failed. Shared by the differential writer and any -/// other input model that drives a workload against one connection it expects to always work. +/// `context`'s own Debug output naming what failed. pub(crate) fn run_workload( - connection: &Connection<'_>, + connection: &Connection, label: &str, ops: &[Op], context: &D, @@ -1167,7 +943,7 @@ pub(crate) fn run_workload( /// Runs `ops` against an already-open, already-configured connection, silently stopping at the /// first statement that fails instead of panicking. For a connection whose own key or cipher may /// be wrong on purpose, where failure is expected and not itself a defect. -pub(crate) fn run_workload_tolerant(connection: &Connection<'_>, ops: &[Op]) { +pub(crate) fn run_workload_tolerant(connection: &Connection, ops: &[Op]) { run_workload_with(connection, ops, |connection, text, params, _op| { connection.execute(&sql(text), params).is_ok() }); @@ -1177,9 +953,9 @@ pub(crate) fn run_workload_tolerant(connection: &Connection<'_>, ops: &[Op]) { /// `run` reports whether its statement succeeded, which decides whether dependent state (a table /// now existing, a transaction now open) advances or the op is treated as never having happened. fn run_workload_with( - connection: &Connection<'_>, + connection: &Connection, ops: &[Op], - mut run: impl FnMut(&Connection<'_>, &str, &[Param<'_>], &Op) -> bool, + mut run: impl FnMut(&Connection, &str, &[Param<'_>], &Op) -> bool, ) { let mut created = [false; 3]; // Tables created inside a transaction disappear again on rollback. @@ -1247,15 +1023,11 @@ fn run_workload_with( } } -/// Everything `api` can read from the file at `path` with the key `configure` applies, up to the -/// first failure. -fn dump( - api: &Api, - path: &Path, - configure: impl FnOnce(&Connection<'_>) -> Result<(), Code>, -) -> Vec { +/// Everything SQLite3MC can read from the file at `path` with the key `configure` applies, up +/// to the first failure. +fn dump(path: &Path, configure: impl FnOnce(&Connection) -> Result<(), Code>) -> Vec { let mut log = Vec::new(); - let connection = match Connection::open(api, &c_path(path), SQLITE_OPEN_READONLY) { + let connection = match Connection::open(&c_path(path), SQLITE_OPEN_READONLY) { Ok(connection) => connection, Err(code) => { log.push(Record::Failed("open", code)); @@ -1287,12 +1059,7 @@ fn dump( type Step = Result<(), (&'static str, Code)>; -fn rows( - connection: &Connection<'_>, - stage: &'static str, - query: &CStr, - log: &mut Vec, -) -> Step { +fn rows(connection: &Connection, stage: &'static str, query: &CStr, log: &mut Vec) -> Step { let mut statement = connection.prepare(query).map_err(|code| (stage, code))?; while let Some(row) = statement.next_row().map_err(|code| (stage, code))? { log.push(Record::Row(stage, row)); @@ -1301,7 +1068,7 @@ fn rows( } /// Logs every page's content area, cutting the reserved bytes page 1's header byte 20 names. -fn pages(connection: &Connection<'_>, log: &mut Vec) -> Step { +fn pages(connection: &Connection, log: &mut Vec) -> Step { const STAGE: &str = "sqlite_dbpage"; let mut statement = connection .prepare(c"SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno") @@ -1322,58 +1089,6 @@ fn pages(connection: &Connection<'_>, log: &mut Vec) -> Step { Ok(()) } -fn compare(case: &Case, file: &str, a: Side, a_log: &[Record], b: Side, b_log: &[Record]) { - if a_log == b_log { - return; - } - let at = a_log.iter().zip(b_log).take_while(|(x, y)| x == y).count(); - let (sqlcipher, sqlite3mc) = if a == Side::SqlCipher { - (a_log, b_log) - } else { - (b_log, a_log) - }; - if case.config.reserved() > 16 - && swallowed_hmac_failure( - at, - case.config.plaintext_header() > 0, - sqlcipher.get(at), - sqlite3mc.get(at), - ) - { - return; - } - panic!( - "{} and {} disagree on {file} from record {at} (of {} and {}).\n{}:{}\n{}:{}\nfor {case:#?}", - name(a), - name(b), - a_log.len(), - b_log.len(), - name(a), - describe(&a_log[at..]), - name(b), - describe(&b_log[at..]), - ); -} - -/// SQLCipher 4.19.0 zero-fills a page that fails its HMAC check instead of reporting the failure. -fn swallowed_hmac_failure( - at: usize, - plaintext_header: bool, - sqlcipher: Option<&Record>, - sqlite3mc: Option<&Record>, -) -> bool { - match (sqlcipher, sqlite3mc) { - (Some(Record::Page(_, data)), Some(Record::Failed("sqlite_dbpage", Code(11)))) => { - data.iter().all(|&b| b == 0) - } - ( - Some(Record::Failed("sqlite_dbpage", Code(11))), - Some(Record::Failed("sqlite_dbpage", Code(26))), - ) => at == 0 && plaintext_header, - _ => false, - } -} - /// Up to six records, one per line, each cut to a readable length. fn describe<'r>(records: impl IntoIterator) -> String { let mut out = String::new(); diff --git a/fuzz/tests/replay.rs b/fuzz/tests/replay.rs index 49015c3..ee64f37 100644 --- a/fuzz/tests/replay.rs +++ b/fuzz/tests/replay.rs @@ -1,33 +1,13 @@ -//! Replays the committed corpora, differential against both libraries, native for -//! self-consistency, rekey for its own round-trip, WAL mode for its own crash tolerance, ATTACH -//! for cross-database isolation, the backup API for its own compatibility guard, and -//! shared-cache mode for not corrupting a sibling connection's live session, without libFuzzer. +//! Replays the committed corpora for self-consistency across the native cipher schemes, rekey +//! round-trips, WAL-mode crash tolerance, `ATTACH DATABASE` cross-database isolation, the backup +//! API's compatibility guard, and shared-cache mode, without libFuzzer. use arbitrary::{Arbitrary, Unstructured}; use sqlite3mc_src_fuzz::{ - run, run_attach, run_backup, run_native, run_rekey, run_shared_cache, run_wal, AttachCase, - BackupCase, Case, NativeCase, RekeyCase, SharedCacheCase, WalCase, + run_attach, run_backup, run_native, run_rekey, run_shared_cache, run_wal, AttachCase, + BackupCase, NativeCase, RekeyCase, SharedCacheCase, WalCase, }; -#[test] -fn committed_corpus_agrees_with_sqlcipher() { - let dir = concat!(env!("CARGO_MANIFEST_DIR"), "/corpus/differential"); - let mut seeds: Vec<_> = std::fs::read_dir(dir) - .expect("the committed corpus exists") - .map(|entry| entry.expect("the corpus is readable").path()) - .collect(); - seeds.sort(); - assert!(!seeds.is_empty(), "{dir} holds no seeds"); - for seed in seeds { - let bytes = std::fs::read(&seed).expect("seeds are readable"); - // libFuzzer's `fuzz_target!` decodes the same way, taking the rest of the input last. - let case = Case::arbitrary_take_rest(Unstructured::new(&bytes)) - .unwrap_or_else(|e| panic!("{} does not decode: {e}", seed.display())); - eprintln!("{}", seed.display()); - run(&case); - } -} - #[test] fn committed_native_corpus_is_self_consistent() { let dir = concat!(env!("CARGO_MANIFEST_DIR"), "/corpus/native");