From e9bb8b800c6c724125ccd862f4d20946317b31f5 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Mon, 26 Sep 2016 23:25:13 +0200 Subject: reverse: switch from GCM-SIV to AES-SIV GCM-SIV is not yet finalized, and the reference implemenation is painfully slow at about 2 MB/s. Switch to AES-SIV. --- internal/configfile/config_file.go | 8 ++++---- internal/configfile/config_test.go | 8 ++++---- internal/configfile/feature_flags.go | 4 ++-- internal/contentenc/content.go | 12 ++++++------ internal/cryptocore/cryptocore.go | 11 +++++------ internal/stupidgcm/stupidgcm_test.go | 10 ++++------ 6 files changed, 25 insertions(+), 28 deletions(-) (limited to 'internal') diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index fab74a6..f58c51c 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -45,7 +45,7 @@ type ConfFile struct { // CreateConfFile - create a new config with a random key encrypted with // "password" and write it to "filename". // Uses scrypt with cost parameter logN. -func CreateConfFile(filename string, password string, plaintextNames bool, logN int, creator string, gcmsiv bool) error { +func CreateConfFile(filename string, password string, plaintextNames bool, logN int, creator string, aessiv bool) error { var cf ConfFile cf.filename = filename cf.Creator = creator @@ -59,7 +59,7 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN cf.EncryptKey(key, password, logN) // Set feature flags - cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagGCMIV128]) // 128-bit IVs + cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagGCMIV128]) if plaintextNames { cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagPlaintextNames]) } else { @@ -67,8 +67,8 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagEMENames]) cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagLongNames]) } - if gcmsiv { - cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagGCMSIV]) // GCM-SIV encryption mode + if aessiv { + cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV]) } // Write file to disk diff --git a/internal/configfile/config_test.go b/internal/configfile/config_test.go index ac85c8d..81984fe 100644 --- a/internal/configfile/config_test.go +++ b/internal/configfile/config_test.go @@ -71,7 +71,7 @@ func TestCreateConfFile(t *testing.T) { } -func TestCreateConfFileGCMSIV(t *testing.T) { +func TestCreateConfFileAESSIV(t *testing.T) { err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", true) if err != nil { t.Fatal(err) @@ -80,14 +80,14 @@ func TestCreateConfFileGCMSIV(t *testing.T) { if err != nil { t.Fatal(err) } - if !c.IsFeatureFlagSet(FlagGCMSIV) { - t.Error("GCMSIV flag should be set but is not") + if !c.IsFeatureFlagSet(FlagAESSIV) { + t.Error("AESSIV flag should be set but is not") } } func TestIsFeatureFlagKnown(t *testing.T) { // Test a few hardcoded values - testKnownFlags := []string{"DirIV", "PlaintextNames", "EMENames", "GCMIV128", "LongNames", "GCMSIV"} + testKnownFlags := []string{"DirIV", "PlaintextNames", "EMENames", "GCMIV128", "LongNames", "AESSIV"} // And also everything in knownFlags (yes, it is likely that we end up with // some duplicates. Does not matter.) for _, f := range knownFlags { diff --git a/internal/configfile/feature_flags.go b/internal/configfile/feature_flags.go index 90b8c22..ad7bec1 100644 --- a/internal/configfile/feature_flags.go +++ b/internal/configfile/feature_flags.go @@ -8,7 +8,7 @@ const ( FlagEMENames FlagGCMIV128 FlagLongNames - FlagGCMSIV + FlagAESSIV ) // knownFlags stores the known feature flags and their string representation @@ -18,7 +18,7 @@ var knownFlags map[flagIota]string = map[flagIota]string{ FlagEMENames: "EMENames", FlagGCMIV128: "GCMIV128", FlagLongNames: "LongNames", - FlagGCMSIV: "GCMSIV", + FlagAESSIV: "AESSIV", } // Filesystems that do not have these feature flags set are deprecated. diff --git a/internal/contentenc/content.go b/internal/contentenc/content.go index 7561859..86be7d5 100644 --- a/internal/contentenc/content.go +++ b/internal/contentenc/content.go @@ -105,8 +105,8 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileId []b // Extract nonce nonce := ciphertext[:be.cryptoCore.IVLen] - if bytes.Equal(nonce, be.allZeroNonce) && be.cryptoCore.AEADBackend != cryptocore.BackendGCMSIV { - panic("Hit an all-zero nonce with GCMSIV off. This MUST NOT happen!") + if bytes.Equal(nonce, be.allZeroNonce) { + panic("Hit an all-zero nonce. This MUST NOT happen!") } ciphertextOrig := ciphertext ciphertext = ciphertext[be.cryptoCore.IVLen:] @@ -150,13 +150,13 @@ func (be *ContentEnc) EncryptBlock(plaintext []byte, blockNo uint64, fileID []by var nonce []byte switch nMode { case ExternalNonce: - if be.cryptoCore.AEADBackend != cryptocore.BackendGCMSIV { - panic("MUST NOT use deterministic nonces unless in GCMSIV mode!") + if be.cryptoCore.AEADBackend != cryptocore.BackendAESSIV { + panic("MUST NOT use deterministic nonces unless in AESSIV mode!") } nonce = externalNonce case ReverseDeterministicNonce: - if be.cryptoCore.AEADBackend != cryptocore.BackendGCMSIV { - panic("MUST NOT use deterministic nonces unless in GCMSIV mode!") + if be.cryptoCore.AEADBackend != cryptocore.BackendAESSIV { + panic("MUST NOT use deterministic nonces unless in AESSIV mode!") } l := be.cryptoCore.IVLen nonce = make([]byte, l) diff --git a/internal/cryptocore/cryptocore.go b/internal/cryptocore/cryptocore.go index 0913ed0..23dc26e 100644 --- a/internal/cryptocore/cryptocore.go +++ b/internal/cryptocore/cryptocore.go @@ -7,9 +7,8 @@ import ( "crypto/cipher" "fmt" + "github.com/rfjakob/gocryptfs/internal/siv_aead" "github.com/rfjakob/gocryptfs/internal/stupidgcm" - - "github.com/rfjakob/gcmsiv" ) type BackendTypeEnum int @@ -21,13 +20,13 @@ const ( _ = iota // Skip zero BackendOpenSSL BackendTypeEnum = iota BackendGoGCM BackendTypeEnum = iota - BackendGCMSIV BackendTypeEnum = iota + BackendAESSIV BackendTypeEnum = iota ) type CryptoCore struct { // AES-256 block cipher. This is used for EME filename encryption. BlockCipher cipher.Block - // GCM or GCM-SIV. This is used for content encryption. + // GCM or AES-SIV. This is used for content encryption. AEADCipher cipher.AEAD // Which backend is behind AEADCipher? AEADBackend BackendTypeEnum @@ -64,8 +63,8 @@ func New(key []byte, backend BackendTypeEnum, IVBitLen int) *CryptoCore { gcm = stupidgcm.New(key) case BackendGoGCM: gcm, err = goGCMWrapper(blockCipher, IVLen) - case BackendGCMSIV: - gcm, err = gcmsiv.NewGCMSIV(key) + case BackendAESSIV: + gcm = siv_aead.New(key) default: panic("unknown backend cipher") } diff --git a/internal/stupidgcm/stupidgcm_test.go b/internal/stupidgcm/stupidgcm_test.go index 1dbfccb..3c11dfe 100644 --- a/internal/stupidgcm/stupidgcm_test.go +++ b/internal/stupidgcm/stupidgcm_test.go @@ -15,7 +15,8 @@ import ( "encoding/hex" "testing" - "github.com/rfjakob/gcmsiv" + // For benchmark comparison + "github.com/rfjakob/gocryptfs/internal/siv_aead" ) // Get "n" random bytes from /dev/urandom or panic @@ -162,16 +163,13 @@ func Benchmark4kEncGoGCM(b *testing.B) { } } -func Benchmark4kEncGCMSIV(b *testing.B) { +func Benchmark4kEncAESSIV(b *testing.B) { key := randBytes(32) authData := randBytes(24) iv := randBytes(16) in := make([]byte, 4096) b.SetBytes(int64(len(in))) - gGCM, err := gcmsiv.NewGCMSIV(key) - if err != nil { - b.Fatal(err) - } + gGCM := siv_aead.New(key) for i := 0; i < b.N; i++ { // Encrypt and append to nonce gGCM.Seal(iv, iv, in, authData) -- cgit v1.2.3