From 806334eacf2e50d712844761aca2b11014ec99df Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Mon, 23 Aug 2021 22:10:23 +0200 Subject: [PATCH] cryptocore: add NonceSize to AEADTypeEnum Have the information in one centralized place, and access it from main as needed. --- internal/configfile/config_file.go | 15 ++++++++ internal/cryptocore/cryptocore.go | 57 +++++++++++++----------------- internal/siv_aead/siv_aead.go | 9 +++-- mount.go | 24 +++++-------- 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index dba6c47..c1f93af 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -325,3 +325,18 @@ func getKeyEncrypter(scryptHash []byte, useHKDF bool) *contentenc.ContentEnc { ce := contentenc.New(cc, 4096, false) return ce } + +// ContentEncryption tells us which content encryption algorithm is selected +func (cf *ConfFile) ContentEncryption() (algo cryptocore.AEADTypeEnum, err error) { + if err := cf.Validate(); err != nil { + return cryptocore.AEADTypeEnum{}, err + } + if cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) { + return cryptocore.BackendXChaCha20Poly1305, nil + } + if cf.IsFeatureFlagSet(FlagAESSIV) { + return cryptocore.BackendAESSIV, nil + } + // If neither AES-SIV nor XChaCha are selected, we must be using AES-GCM + return cryptocore.BackendGoGCM, nil +} diff --git a/internal/cryptocore/cryptocore.go b/internal/cryptocore/cryptocore.go index 3e6f5e8..8fb7936 100644 --- a/internal/cryptocore/cryptocore.go +++ b/internal/cryptocore/cryptocore.go @@ -6,7 +6,6 @@ import ( "crypto/aes" "crypto/cipher" "crypto/sha512" - "fmt" "log" "runtime" @@ -20,43 +19,35 @@ import ( ) const ( - // KeyLen is the cipher key length in bytes. 32 for AES-256. + // KeyLen is the cipher key length in bytes. All backends use 32 bytes. KeyLen = 32 - // AuthTagLen is the length of a GCM auth tag in bytes. + // AuthTagLen is the length of a authentication tag in bytes. + // All backends use 16 bytes. AuthTagLen = 16 ) // AEADTypeEnum indicates the type of AEAD backend in use. -type AEADTypeEnum int - -const ( - // BackendOpenSSL specifies the OpenSSL backend. - // "AES-GCM-256-OpenSSL" in gocryptfs -speed. - BackendOpenSSL AEADTypeEnum = 3 - // BackendGoGCM specifies the Go based GCM backend. - // "AES-GCM-256-Go" in gocryptfs -speed. - BackendGoGCM AEADTypeEnum = 4 - // BackendAESSIV specifies an AESSIV backend. - // "AES-SIV-512-Go" in gocryptfs -speed. - BackendAESSIV AEADTypeEnum = 5 - // BackendXChaCha20Poly1305 specifies XChaCha20-Poly1305-Go. - // "XChaCha20-Poly1305-Go" in gocryptfs -speed. - BackendXChaCha20Poly1305 AEADTypeEnum = 6 -) - -func (a AEADTypeEnum) String() string { - switch a { - case BackendOpenSSL: - return "BackendOpenSSL" - case BackendGoGCM: - return "BackendGoGCM" - case BackendAESSIV: - return "BackendAESSIV" - default: - return fmt.Sprintf("%d", a) - } +type AEADTypeEnum struct { + Name string + NonceSize int } +// BackendOpenSSL specifies the OpenSSL backend. +// "AES-GCM-256-OpenSSL" in gocryptfs -speed. +var BackendOpenSSL AEADTypeEnum = AEADTypeEnum{"AES-GCM-256-OpenSSL", 16} + +// BackendGoGCM specifies the Go based GCM backend. +// "AES-GCM-256-Go" in gocryptfs -speed. +var BackendGoGCM AEADTypeEnum = AEADTypeEnum{"AES-GCM-256-Go", 16} + +// BackendAESSIV specifies an AESSIV backend. +// "AES-SIV-512-Go" in gocryptfs -speed. +var BackendAESSIV AEADTypeEnum = AEADTypeEnum{"AES-SIV-512-Go", siv_aead.NonceSize} + +// BackendXChaCha20Poly1305 specifies XChaCha20-Poly1305-Go. +// "XChaCha20-Poly1305-Go" in gocryptfs -speed. +var BackendXChaCha20Poly1305 AEADTypeEnum = AEADTypeEnum{"XChaCha20-Poly1305-Go", chacha20poly1305.NonceSizeX} + // CryptoCore is the low level crypto implementation. type CryptoCore struct { // EME is used for filename encryption. @@ -174,7 +165,7 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec log.Panic(err) } } else { - log.Panicf("unknown cipher backend %q", aeadType.String()) + log.Panicf("unknown cipher backend %q", aeadType.Name) } if aeadCipher.NonceSize()*8 != IVBitLen { @@ -203,7 +194,7 @@ type wiper interface { func (c *CryptoCore) Wipe() { be := c.AEADBackend if be == BackendOpenSSL || be == BackendAESSIV { - tlog.Debug.Printf("CryptoCore.Wipe: Wiping AEADBackend %d key", be) + tlog.Debug.Printf("CryptoCore.Wipe: Wiping AEADBackend %s key", be.Name) // We don't use "x, ok :=" because we *want* to crash loudly if the // type assertion fails. w := c.AEADCipher.(wiper) diff --git a/internal/siv_aead/siv_aead.go b/internal/siv_aead/siv_aead.go index eabb5e2..482efd9 100644 --- a/internal/siv_aead/siv_aead.go +++ b/internal/siv_aead/siv_aead.go @@ -19,6 +19,11 @@ const ( // KeyLen is the required key length. The SIV algorithm supports other lengths, // but we only support 64. KeyLen = 64 + // NonceSize is the required nonce/IV length. + // SIV supports any nonce size, but in gocryptfs we exclusively use 16. + NonceSize = 16 + // Overhead is the number of bytes added for integrity checking + Overhead = 16 ) // New returns a new cipher.AEAD implementation. @@ -42,11 +47,11 @@ func new2(keyIn []byte) cipher.AEAD { func (s *sivAead) NonceSize() int { // SIV supports any nonce size, but in gocryptfs we exclusively use 16. - return 16 + return NonceSize } func (s *sivAead) Overhead() int { - return 16 + return Overhead } // Seal encrypts "in" using "nonce" and "authData" and appends the result to "dst" diff --git a/mount.go b/mount.go index f8347f1..44d5878 100644 --- a/mount.go +++ b/mount.go @@ -292,24 +292,18 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f frontendArgs.DeterministicNames = !confFile.IsFeatureFlagSet(configfile.FlagDirIV) args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64) args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF) - if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) { - cryptoBackend = cryptocore.BackendAESSIV - IVBits = contentenc.DefaultIVBits - } else if args.reverse { + cryptoBackend, err = confFile.ContentEncryption() + if err != nil { + tlog.Fatal.Printf("%v", err) + os.Exit(exitcodes.DeprecatedFS) + } + IVBits = cryptoBackend.NonceSize * 8 + if cryptoBackend != cryptocore.BackendAESSIV && args.reverse { tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file") os.Exit(exitcodes.Usage) } - if confFile.IsFeatureFlagSet(configfile.FlagXChaCha20Poly1305) { - cryptoBackend = cryptocore.BackendXChaCha20Poly1305 - IVBits = chacha20poly1305.NonceSizeX * 8 - } - // If neither AES-SIV nor XChaCha are selected, we must be using AES-GCM - if !confFile.IsFeatureFlagSet(configfile.FlagAESSIV) && !confFile.IsFeatureFlagSet(configfile.FlagXChaCha20Poly1305) { - cryptoBackend = cryptocore.BackendGoGCM - if args.openssl { - cryptoBackend = cryptocore.BackendOpenSSL - } - IVBits = contentenc.DefaultIVBits + if cryptoBackend == cryptocore.BackendGoGCM && args.openssl { + cryptoBackend = cryptocore.BackendOpenSSL } } // If allow_other is set and we run as root, try to give newly created files to