cryptocore: add NonceSize to AEADTypeEnum

Have the information in one centralized place,
and access it from main as needed.
This commit is contained in:
Jakob Unterwurzacher 2021-08-23 22:10:23 +02:00
parent b12ad292d4
commit 806334eacf
4 changed files with 55 additions and 50 deletions

View File

@ -325,3 +325,18 @@ func getKeyEncrypter(scryptHash []byte, useHKDF bool) *contentenc.ContentEnc {
ce := contentenc.New(cc, 4096, false) ce := contentenc.New(cc, 4096, false)
return ce 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
}

View File

@ -6,7 +6,6 @@ import (
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/sha512" "crypto/sha512"
"fmt"
"log" "log"
"runtime" "runtime"
@ -20,43 +19,35 @@ import (
) )
const ( 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 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 AuthTagLen = 16
) )
// AEADTypeEnum indicates the type of AEAD backend in use. // AEADTypeEnum indicates the type of AEAD backend in use.
type AEADTypeEnum int type AEADTypeEnum struct {
Name string
const ( NonceSize int
// 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)
}
} }
// 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. // CryptoCore is the low level crypto implementation.
type CryptoCore struct { type CryptoCore struct {
// EME is used for filename encryption. // EME is used for filename encryption.
@ -174,7 +165,7 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec
log.Panic(err) log.Panic(err)
} }
} else { } else {
log.Panicf("unknown cipher backend %q", aeadType.String()) log.Panicf("unknown cipher backend %q", aeadType.Name)
} }
if aeadCipher.NonceSize()*8 != IVBitLen { if aeadCipher.NonceSize()*8 != IVBitLen {
@ -203,7 +194,7 @@ type wiper interface {
func (c *CryptoCore) Wipe() { func (c *CryptoCore) Wipe() {
be := c.AEADBackend be := c.AEADBackend
if be == BackendOpenSSL || be == BackendAESSIV { 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 // We don't use "x, ok :=" because we *want* to crash loudly if the
// type assertion fails. // type assertion fails.
w := c.AEADCipher.(wiper) w := c.AEADCipher.(wiper)

View File

@ -19,6 +19,11 @@ const (
// KeyLen is the required key length. The SIV algorithm supports other lengths, // KeyLen is the required key length. The SIV algorithm supports other lengths,
// but we only support 64. // but we only support 64.
KeyLen = 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. // New returns a new cipher.AEAD implementation.
@ -42,11 +47,11 @@ func new2(keyIn []byte) cipher.AEAD {
func (s *sivAead) NonceSize() int { func (s *sivAead) NonceSize() int {
// SIV supports any nonce size, but in gocryptfs we exclusively use 16. // SIV supports any nonce size, but in gocryptfs we exclusively use 16.
return 16 return NonceSize
} }
func (s *sivAead) Overhead() int { func (s *sivAead) Overhead() int {
return 16 return Overhead
} }
// Seal encrypts "in" using "nonce" and "authData" and appends the result to "dst" // Seal encrypts "in" using "nonce" and "authData" and appends the result to "dst"

View File

@ -292,24 +292,18 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f
frontendArgs.DeterministicNames = !confFile.IsFeatureFlagSet(configfile.FlagDirIV) frontendArgs.DeterministicNames = !confFile.IsFeatureFlagSet(configfile.FlagDirIV)
args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64) args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64)
args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF) args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF)
if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) { cryptoBackend, err = confFile.ContentEncryption()
cryptoBackend = cryptocore.BackendAESSIV if err != nil {
IVBits = contentenc.DefaultIVBits tlog.Fatal.Printf("%v", err)
} else if args.reverse { 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") tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file")
os.Exit(exitcodes.Usage) os.Exit(exitcodes.Usage)
} }
if confFile.IsFeatureFlagSet(configfile.FlagXChaCha20Poly1305) { if cryptoBackend == cryptocore.BackendGoGCM && args.openssl {
cryptoBackend = cryptocore.BackendXChaCha20Poly1305 cryptoBackend = cryptocore.BackendOpenSSL
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 allow_other is set and we run as root, try to give newly created files to // If allow_other is set and we run as root, try to give newly created files to