From 89f750a6e96b5869f85f40b638496641ec769965 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Fri, 18 Oct 2024 11:59:36 +0100 Subject: [PATCH] Wrap FilePersistentWAL. --- vfs/README.md | 4 +++- vfs/adiantum/README.md | 16 +++++++++------- vfs/adiantum/hbsh.go | 13 +++++++++++++ vfs/xts/README.md | 17 +++++++++++------ vfs/xts/xts.go | 13 +++++++++++++ 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/vfs/README.md b/vfs/README.md index 1cbf9409..08447e30 100644 --- a/vfs/README.md +++ b/vfs/README.md @@ -94,4 +94,6 @@ The VFS can be customized with a few build tags: - [`github.com/ncruces/go-sqlite3/vfs/memdb`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/memdb) implements an in-memory VFS. - [`github.com/ncruces/go-sqlite3/vfs/readervfs`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/readervfs) - implements a VFS for immutable databases. \ No newline at end of file + implements a VFS for immutable databases. +- [`github.com/ncruces/go-sqlite3/vfs/xts`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/xts) + wraps a VFS to offer encryption at rest. \ No newline at end of file diff --git a/vfs/adiantum/README.md b/vfs/adiantum/README.md index bc3f094b..da75f45a 100644 --- a/vfs/adiantum/README.md +++ b/vfs/adiantum/README.md @@ -39,10 +39,12 @@ This means that an adversary who can get ahold of multiple snapshots (e.g. backups) of a database file can learn precisely: which blocks changed, which ones didn't, which got reverted. -This is slightly weaker than other forms of SQLite encryption -that include *some* nondeterminism; with limited nondeterminism, -an adversary can't distinguish between -blocks that actually changed, and blocks that got reverted. +This is weaker than other forms of SQLite encryption +that include *some* nondeterminism. +With limited nondeterminism, an adversary can't distinguish between +pages that actually changed, and pages that got reverted; +a `VACUUM` can fully rebuild the database file, +preventing this differential analysis. > [!CAUTION] > This package does not claim protect databases against tampering or forgery. @@ -52,11 +54,11 @@ if you're keeping `"adiantum"` encrypted backups of your database, and want to protect against forgery, you should sign your backups, and verify signatures before restoring them. -This is slightly weaker than other forms of SQLite encryption +This is weaker than other forms of SQLite encryption that include page-level [MACs](https://en.wikipedia.org/wiki/Message_authentication_code). Page-level MACs can protect against forging individual pages, but can't prevent them from being reverted to former versions of themselves. > [!TIP] -> The [`"xts"`](../xts/README.md) package also offers encryption at rest. -> AES-XTS uses _only_ NIST and FIPS-140 approved cryptographic primitives. \ No newline at end of file +> The [`"xts"`](../xts/README.md) VFS also offers encryption at rest. +> AES-XTS uses _only_ NIST and FIPS 140 approved cryptographic primitives. \ No newline at end of file diff --git a/vfs/adiantum/hbsh.go b/vfs/adiantum/hbsh.go index 02cb63bd..096c1788 100644 --- a/vfs/adiantum/hbsh.go +++ b/vfs/adiantum/hbsh.go @@ -243,6 +243,19 @@ func (h *hbshFile) Overwrite() error { return sqlite3.NOTFOUND } +func (h *hbshFile) PersistentWAL() bool { + if f, ok := h.File.(vfs.FilePersistentWAL); ok { + return f.PersistentWAL() + } + return false +} + +func (h *hbshFile) SetPersistentWAL(keepWAL bool) { + if f, ok := h.File.(vfs.FilePersistentWAL); ok { + f.SetPersistentWAL(keepWAL) + } +} + func (h *hbshFile) CommitPhaseTwo() error { if f, ok := h.File.(vfs.FileCommitPhaseTwo); ok { return f.CommitPhaseTwo() diff --git a/vfs/xts/README.md b/vfs/xts/README.md index 786435de..1e6ed8c1 100644 --- a/vfs/xts/README.md +++ b/vfs/xts/README.md @@ -14,6 +14,9 @@ to derive AES-128 keys from plain text where needed. File contents are encrypted in 512 byte sectors, matching the [minimum](https://sqlite.org/fileformat.html#pages) SQLite page size. +This VFS uses _only_ NIST and FIPS 140-2 approved cryptographic primitives, +which _may_ help you become FIPS compliant. + The VFS encrypts all files _except_ [super journals](https://sqlite.org/tempfiles.html#super_journal_files): these _never_ contain database data, only filenames, @@ -39,10 +42,12 @@ This means that an adversary who can get ahold of multiple snapshots (e.g. backups) of a database file can learn precisely: which sectors changed, which ones didn't, which got reverted. -This is slightly weaker than other forms of SQLite encryption -that include *some* nondeterminism; with limited nondeterminism, -an adversary can't distinguish between -sectors that actually changed, and sectors that got reverted. +This is weaker than other forms of SQLite encryption +that include *some* nondeterminism. +With limited nondeterminism, an adversary can't distinguish between +pages that actually changed, and pages that got reverted; +a `VACUUM` can fully rebuild the database file, +preventing this differential analysis. > [!CAUTION] > This package does not claim protect databases against tampering or forgery. @@ -52,12 +57,12 @@ if you're keeping `"xts"` encrypted backups of your database, and want to protect against forgery, you should sign your backups, and verify signatures before restoring them. -This is slightly weaker than other forms of SQLite encryption +This is weaker than other forms of SQLite encryption that include page-level [MACs](https://en.wikipedia.org/wiki/Message_authentication_code). Page-level MACs can protect against forging individual pages, but can't prevent them from being reverted to former versions of themselves. > [!TIP] -> The [`"adiantum"`](../adiantum/README.md) package also offers encryption at rest. +> The [`"adiantum"`](../adiantum/README.md) VFS also offers encryption at rest. > In general Adiantum performs significantly better, > and as a "wide-block" cipher, _may_ offer improved security. \ No newline at end of file diff --git a/vfs/xts/xts.go b/vfs/xts/xts.go index 1d3107f2..b86eee8b 100644 --- a/vfs/xts/xts.go +++ b/vfs/xts/xts.go @@ -240,6 +240,19 @@ func (x *xtsFile) Overwrite() error { return sqlite3.NOTFOUND } +func (x *xtsFile) PersistentWAL() bool { + if f, ok := x.File.(vfs.FilePersistentWAL); ok { + return f.PersistentWAL() + } + return false +} + +func (x *xtsFile) SetPersistentWAL(keepWAL bool) { + if f, ok := x.File.(vfs.FilePersistentWAL); ok { + f.SetPersistentWAL(keepWAL) + } +} + func (x *xtsFile) CommitPhaseTwo() error { if f, ok := x.File.(vfs.FileCommitPhaseTwo); ok { return f.CommitPhaseTwo()