diff options
| author | Jakob Unterwurzacher | 2021-08-23 22:10:23 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2021-08-23 22:10:23 +0200 | 
| commit | 806334eacf2e50d712844761aca2b11014ec99df (patch) | |
| tree | 5d531146e92f7770a02e03107afdcb2fcc7a0ab1 | |
| parent | b12ad292d4dfef1c00567fe3def7e73461d3c217 (diff) | |
cryptocore: add NonceSize to AEADTypeEnum
Have the information in one centralized place,
and access it from main as needed.
| -rw-r--r-- | internal/configfile/config_file.go | 15 | ||||
| -rw-r--r-- | internal/cryptocore/cryptocore.go | 55 | ||||
| -rw-r--r-- | internal/siv_aead/siv_aead.go | 9 | ||||
| -rw-r--r-- | mount.go | 24 | 
4 files changed, 54 insertions, 49 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,42 +19,34 @@ 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 +type AEADTypeEnum struct { +	Name      string +	NonceSize 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 -) +// BackendOpenSSL specifies the OpenSSL backend. +// "AES-GCM-256-OpenSSL" in gocryptfs -speed. +var BackendOpenSSL AEADTypeEnum = AEADTypeEnum{"AES-GCM-256-OpenSSL", 16} -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) -	} -} +// 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 { @@ -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" @@ -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 | 
