aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-08-21 12:08:37 +0200
committerJakob Unterwurzacher2021-08-23 16:00:41 +0200
commit4764a9bde093f6b61d0370653c6c9d12949ed145 (patch)
treed71078f71ed3eb0c855e54a13e37b5051ca1bc94 /internal
parentb02812f8b3609403e36c0c182fd2f01537dd6e82 (diff)
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
Diffstat (limited to 'internal')
-rw-r--r--internal/configfile/feature_flags.go21
-rw-r--r--internal/cryptocore/cryptocore.go30
-rw-r--r--internal/cryptocore/hkdf.go7
3 files changed, 44 insertions, 14 deletions
diff --git a/internal/configfile/feature_flags.go b/internal/configfile/feature_flags.go
index 45e1853..be5616f 100644
--- a/internal/configfile/feature_flags.go
+++ b/internal/configfile/feature_flags.go
@@ -28,19 +28,22 @@ const (
// FlagFIDO2 means that "-fido2" was used when creating the filesystem.
// The masterkey is protected using a FIDO2 token instead of a password.
FlagFIDO2
+ // FlagXChaCha20Poly1305 means we use XChaCha20-Poly1305 file content encryption
+ FlagXChaCha20Poly1305
)
// knownFlags stores the known feature flags and their string representation
var knownFlags = map[flagIota]string{
- FlagPlaintextNames: "PlaintextNames",
- FlagDirIV: "DirIV",
- FlagEMENames: "EMENames",
- FlagGCMIV128: "GCMIV128",
- FlagLongNames: "LongNames",
- FlagAESSIV: "AESSIV",
- FlagRaw64: "Raw64",
- FlagHKDF: "HKDF",
- FlagFIDO2: "FIDO2",
+ FlagPlaintextNames: "PlaintextNames",
+ FlagDirIV: "DirIV",
+ FlagEMENames: "EMENames",
+ FlagGCMIV128: "GCMIV128",
+ FlagLongNames: "LongNames",
+ FlagAESSIV: "AESSIV",
+ FlagRaw64: "Raw64",
+ FlagHKDF: "HKDF",
+ FlagFIDO2: "FIDO2",
+ FlagXChaCha20Poly1305: "XChaCha20Poly1305",
}
// Filesystems that do not have these feature flags set are deprecated.
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