mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Remove cache (side-channel for shared keys).
This commit is contained in:
@@ -72,7 +72,8 @@ func Test_adiantum(t *testing.T) {
|
||||
|
||||
name := "file:" +
|
||||
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db")) +
|
||||
"?vfs=adiantum&textkey=correct+horse+battery+staple"
|
||||
"?vfs=adiantum" +
|
||||
"&hexkey=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
testParallel(t, name, iter)
|
||||
testIntegrity(t, name)
|
||||
}
|
||||
|
||||
@@ -10,19 +10,18 @@ This package wraps an SQLite VFS to offer encryption at rest.
|
||||
|
||||
The `"adiantum"` VFS wraps the default SQLite VFS using the
|
||||
[Adiantum](https://github.com/lukechampine/adiantum)
|
||||
tweakable and length-preserving encryption.
|
||||
|
||||
tweakable and length-preserving encryption.\
|
||||
In general, any HBSH construction can be used to wrap any VFS.
|
||||
|
||||
The default Adiantum construction uses XChaCha12 for its stream cipher,
|
||||
AES for its block cipher, and NH and Poly1305 for hashing.
|
||||
Additionally, we use Argon2id to derive 256-bit keys from plain text.
|
||||
AES for its block cipher, and NH and Poly1305 for hashing.\
|
||||
Additionally, we use [Argon2id](https://pkg.go.dev/golang.org/x/crypto/argon2#hdr-Argon2id)
|
||||
to derive 256-bit keys from plain text.
|
||||
|
||||
The VFS encrypts all files _except_
|
||||
[super journals](https://sqlite.org/tempfiles.html#super_journal_files):
|
||||
these _never_ contain database data, only filenames,
|
||||
they _never_ contain database data, only filenames,
|
||||
and padding them to the block size is problematic.
|
||||
|
||||
Temporary files _are_ encrypted with **random** keys,
|
||||
as they _may_ contain database data.
|
||||
To avoid the overhead of encrypting temporary files,
|
||||
@@ -35,5 +34,11 @@ keep them in memory:
|
||||
> The standard threat model for disk encryption considers an adversary
|
||||
> that can read multiple snapshots of a disk.
|
||||
> The only security property that disk encryption (and this package)
|
||||
> provides is that the only information such an adversary can determine
|
||||
> is whether the data in a sector has or has not changed over time.
|
||||
> provides is that all information such an adversary can obtain
|
||||
> is whether the data in a sector has (or has not) changed over time.
|
||||
|
||||
> [!CAUTION]
|
||||
> This package does not claim protect databases against forgery.
|
||||
> Any encryption scheme that allows constant-time block updates
|
||||
> can't prevent individual blocks from being reverted to former versions of themselves,
|
||||
> so block-level authentication is of limited value.
|
||||
@@ -2,7 +2,6 @@ package adiantum
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/crypto/argon2"
|
||||
"lukechampine.com/adiantum"
|
||||
@@ -26,37 +25,5 @@ func (adiantumCreator) KDF(text string) []byte {
|
||||
n, _ := rand.Read(key)
|
||||
return key[:n]
|
||||
}
|
||||
|
||||
if key := keyCacheGet(text); key != nil {
|
||||
return key[:]
|
||||
}
|
||||
|
||||
key := argon2.IDKey([]byte(text), []byte(pepper), 1, 64*1024, 4, 32)
|
||||
keyCachePut(text, (*[32]byte)(key))
|
||||
return key
|
||||
}
|
||||
|
||||
const keyCacheMaxEntries = 100
|
||||
|
||||
var (
|
||||
// +checklocks:keyCacheMtx
|
||||
keyCache = map[string]*[32]byte{}
|
||||
keyCacheMtx sync.RWMutex
|
||||
)
|
||||
|
||||
func keyCacheGet(text string) *[32]byte {
|
||||
keyCacheMtx.RLock()
|
||||
defer keyCacheMtx.RUnlock()
|
||||
return keyCache[text]
|
||||
}
|
||||
|
||||
func keyCachePut(text string, key *[32]byte) {
|
||||
keyCacheMtx.Lock()
|
||||
defer keyCacheMtx.Unlock()
|
||||
if len(keyCache) >= keyCacheMaxEntries {
|
||||
for k := range keyCache {
|
||||
delete(keyCache, k)
|
||||
}
|
||||
}
|
||||
keyCache[text] = key
|
||||
return argon2.IDKey([]byte(text), []byte(pepper), 1, 64*1024, 4, 32)
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ func Test_crash01_adiantum(t *testing.T) {
|
||||
|
||||
ctx := util.NewContext(newContext(t), true)
|
||||
name := "file:" + filepath.Join(t.TempDir(), "test.db") +
|
||||
"?textkey=correct+horse+battery+staple"
|
||||
"?hexkey=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
cfg := config(ctx).WithArgs("mptest", name, "crash01.test",
|
||||
"--vfs", "adiantum")
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
@@ -265,7 +265,7 @@ func Test_crash01_adiantum_wal(t *testing.T) {
|
||||
|
||||
ctx := util.NewContext(newContext(t), true)
|
||||
name := "file:" + filepath.Join(t.TempDir(), "test.db") +
|
||||
"?textkey=correct+horse+battery+staple"
|
||||
"?hexkey=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
cfg := config(ctx).WithArgs("mptest", name, "crash01.test",
|
||||
"--vfs", "adiantum", "--journalmode", "wal")
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
|
||||
@@ -105,7 +105,7 @@ func Benchmark_adiantum(b *testing.B) {
|
||||
output.Reset()
|
||||
ctx := util.NewContext(context.Background(), true)
|
||||
name := "file:" + filepath.Join(b.TempDir(), "test.db") +
|
||||
"?textkey=correct+horse+battery+staple"
|
||||
"?hexkey=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
args := append(options, "--vfs", "adiantum", "--size", strconv.Itoa(b.N), name)
|
||||
cfg := wazero.NewModuleConfig().
|
||||
WithArgs(args...).WithName("speedtest1").
|
||||
|
||||
Reference in New Issue
Block a user