From 97d8340bd81ddd60baac598d3e25ebfb4decb50c Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 21 Aug 2021 21:43:26 +0200 Subject: configfile: add Validate() function, support FlagXChaCha20Poly1305 We used to do validation using lists of mandatory feature flags. With the introduction of XChaCha20Poly1305, this became too simplistic, as it uses a different IV length, hence disabling GCMIV128. Add a dedicated function, Validate(), with open-coded validation logic. The validation and creation logic also gets XChaCha20Poly1305 support, and gocryptfs -init -xchacha now writes the flag into gocryptfs.conf. --- internal/configfile/validate.go | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 internal/configfile/validate.go (limited to 'internal/configfile/validate.go') diff --git a/internal/configfile/validate.go b/internal/configfile/validate.go new file mode 100644 index 0000000..511f704 --- /dev/null +++ b/internal/configfile/validate.go @@ -0,0 +1,67 @@ +package configfile + +import ( + "fmt" + + "github.com/rfjakob/gocryptfs/v2/internal/contentenc" +) + +// Validate that the combination of settings makes sense and is supported +func (cf *ConfFile) Validate() error { + if cf.Version != contentenc.CurrentVersion { + return fmt.Errorf("Unsupported on-disk format %d", cf.Version) + } + // scrypt params ok? + if err := cf.ScryptObject.validateParams(); err != nil { + return err + } + // All feature flags that are in the config file are known? + for _, flag := range cf.FeatureFlags { + if !isFeatureFlagKnown(flag) { + return fmt.Errorf("Unknown feature flag %q", flag) + } + } + // File content encryption + { + switch { + case cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && cf.IsFeatureFlagSet(FlagAESSIV): + return fmt.Errorf("Can't have both XChaCha20Poly1305 and AESSIV feature flags") + case cf.IsFeatureFlagSet(FlagAESSIV): + if !cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("AESSIV requires GCMIV128 feature flag") + } + case cf.IsFeatureFlagSet(FlagXChaCha20Poly1305): + if cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("XChaCha20Poly1305 conflicts with GCMIV128 feature flag") + } + if !cf.IsFeatureFlagSet(FlagHKDF) { + return fmt.Errorf("XChaCha20Poly1305 requires HKDF feature flag") + } + // The absence of other flags means AES-GCM (oldest algorithm) + case !cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && !cf.IsFeatureFlagSet(FlagAESSIV): + if !cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("AES-GCM requires GCMIV128 feature flag") + } + } + } + // Filename encryption + { + switch { + case cf.IsFeatureFlagSet(FlagPlaintextNames) && cf.IsFeatureFlagSet(FlagEMENames): + return fmt.Errorf("Can't have both PlaintextNames and EMENames feature flags") + case cf.IsFeatureFlagSet(FlagPlaintextNames): + if cf.IsFeatureFlagSet(FlagDirIV) { + return fmt.Errorf("PlaintextNames conflicts with DirIV feature flag") + } + if cf.IsFeatureFlagSet(FlagLongNames) { + return fmt.Errorf("PlaintextNames conflicts with LongNames feature flag") + } + if cf.IsFeatureFlagSet(FlagRaw64) { + return fmt.Errorf("PlaintextNames conflicts with Raw64 feature flag") + } + case cf.IsFeatureFlagSet(FlagEMENames): + // All combinations of DirIV, LongNames, Raw64 allowed + } + } + return nil +} -- cgit v1.2.3