From 4764a9bde093f6b61d0370653c6c9d12949ed145 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 21 Aug 2021 12:08:37 +0200 Subject: Add partial XChaCha20-Poly1305 support (mount flag only) Mount flag only at the moment, not saved to gocryptfs.conf. https://github.com/rfjakob/gocryptfs/issues/452 --- internal/cryptocore/cryptocore.go | 30 ++++++++++++++++++++++++++++-- internal/cryptocore/hkdf.go | 7 ++++--- 2 files changed, 32 insertions(+), 5 deletions(-) (limited to 'internal/cryptocore') diff --git a/internal/cryptocore/cryptocore.go b/internal/cryptocore/cryptocore.go index 5da88db..3e6f5e8 100644 --- a/internal/cryptocore/cryptocore.go +++ b/internal/cryptocore/cryptocore.go @@ -10,6 +10,8 @@ import ( "log" "runtime" + "golang.org/x/crypto/chacha20poly1305" + "github.com/rfjakob/eme" "github.com/rfjakob/gocryptfs/v2/internal/siv_aead" @@ -29,11 +31,17 @@ 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 { @@ -78,7 +86,7 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec if len(key) != KeyLen { log.Panicf("Unsupported key length of %d bytes", len(key)) } - if IVBitLen != 96 && IVBitLen != 128 { + if IVBitLen != 96 && IVBitLen != 128 && IVBitLen != chacha20poly1305.NonceSizeX*8 { log.Panicf("Unsupported IV length of %d bits", IVBitLen) } @@ -152,8 +160,26 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec for i := range key64 { key64[i] = 0 } + } else if aeadType == BackendXChaCha20Poly1305 { + // We don't support legacy modes with XChaCha20-Poly1305 + if IVBitLen != chacha20poly1305.NonceSizeX*8 { + log.Panicf("XChaCha20-Poly1305 must use 192-bit IVs, you wanted %d", IVBitLen) + } + if !useHKDF { + log.Panic("XChaCha20-Poly1305 must use HKDF, but it is disabled") + } + derivedKey := hkdfDerive(key, hkdfInfoXChaChaPoly1305Content, chacha20poly1305.KeySize) + aeadCipher, err = chacha20poly1305.NewX(derivedKey) + if err != nil { + log.Panic(err) + } } else { - log.Panic("unknown backend cipher") + log.Panicf("unknown cipher backend %q", aeadType.String()) + } + + if aeadCipher.NonceSize()*8 != IVBitLen { + log.Panicf("Mismatched aeadCipher.NonceSize*8=%d and IVBitLen=%d bits", + aeadCipher.NonceSize()*8, IVBitLen) } return &CryptoCore{ diff --git a/internal/cryptocore/hkdf.go b/internal/cryptocore/hkdf.go index 87ca1b9..b56f507 100644 --- a/internal/cryptocore/hkdf.go +++ b/internal/cryptocore/hkdf.go @@ -10,9 +10,10 @@ import ( const ( // "info" data that HKDF mixes into the generated key to make it unique. // For convenience, we use a readable string. - hkdfInfoEMENames = "EME filename encryption" - hkdfInfoGCMContent = "AES-GCM file content encryption" - hkdfInfoSIVContent = "AES-SIV file content encryption" + hkdfInfoEMENames = "EME filename encryption" + hkdfInfoGCMContent = "AES-GCM file content encryption" + hkdfInfoSIVContent = "AES-SIV file content encryption" + hkdfInfoXChaChaPoly1305Content = "XChaCha20-Poly1305 file content encryption" ) // hkdfDerive derives "outLen" bytes from "masterkey" and "info" using -- cgit v1.2.3