diff options
author | Frank Denis | 2025-02-25 15:03:50 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2025-03-12 20:43:23 +0100 |
commit | 779a850e0fb967aac79124c7e18b14706d5f2652 (patch) | |
tree | 5220a72c4b22a01c74f8d48f4787c4dae9cb1cbe /internal/configfile | |
parent | 106470d940f7d9fa584463c92f7b2f4f51bce215 (diff) |
Add optional support for AEGIS encryption
AEGIS is a new family of authenticated encryption algorithms that offers
stronger security, higher usage limits, and better performance than AES-GCM.
This pull request adds support for a new `-aegis` command-line flag, allowing
AEGIS-128X2 to be used as an alternative to AES-GCM on CPUs with AES acceleration.
It also introduces the ability to use ciphers with different key sizes.
More information on AEGIS is available here:
- https://cfrg.github.io/draft-irtf-cfrg-aegis-aead/draft-irtf-cfrg-aegis-aead.html
- https://github.com/cfrg/draft-irtf-cfrg-aegis-aead
gocryptfs -speed speed on Apple M1:
AES-GCM-256-OpenSSL 3718.79 MB/s
AES-GCM-256-Go 5083.43 MB/s (selected in auto mode)
AES-SIV-512-Go 625.20 MB/s
XChaCha20-Poly1305-OpenSSL 1358.63 MB/s (selected in auto mode)
XChaCha20-Poly1305-Go 832.11 MB/s
Aegis128X2-Go 11818.73 MB/s
gocryptfs -speed speed on AMD Zen 4:
AES-GCM-256-OpenSSL 5215.86 MB/s
AES-GCM-256-Go 6918.01 MB/s (selected in auto mode)
AES-SIV-512-Go 449.61 MB/s
XChaCha20-Poly1305-OpenSSL 2643.48 MB/s
XChaCha20-Poly1305-Go 3727.46 MB/s (selected in auto mode)
Aegis128X2-Go 28109.92 MB/s
Diffstat (limited to 'internal/configfile')
-rw-r--r-- | internal/configfile/config_file.go | 16 | ||||
-rw-r--r-- | internal/configfile/feature_flags.go | 3 | ||||
-rw-r--r-- | internal/configfile/scrypt.go | 8 | ||||
-rw-r--r-- | internal/configfile/validate.go | 7 |
4 files changed, 24 insertions, 10 deletions
diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index 995a0c8..5e10228 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -32,7 +32,7 @@ type FIDO2Params struct { // FIDO2 credential CredentialID []byte // FIDO2 hmac-secret salt - HMACSalt []byte + HMACSalt []byte AssertOptions []string } @@ -75,6 +75,7 @@ type CreateArgs struct { Fido2AssertOptions []string DeterministicNames bool XChaCha20Poly1305 bool + Aegis bool LongNameMax uint8 Masterkey []byte } @@ -92,6 +93,8 @@ func Create(args *CreateArgs) error { cf.setFeatureFlag(FlagHKDF) if args.XChaCha20Poly1305 { cf.setFeatureFlag(FlagXChaCha20Poly1305) + } else if args.Aegis { + cf.setFeatureFlag(FlagAegis) } else { // 128-bit IVs are mandatory for AES-GCM (default is 96!) and AES-SIV, // XChaCha20Poly1305 uses even an even longer IV of 192 bits. @@ -119,9 +122,9 @@ func Create(args *CreateArgs) error { if len(args.Fido2CredentialID) > 0 { cf.setFeatureFlag(FlagFIDO2) cf.FIDO2 = &FIDO2Params{ - CredentialID: args.Fido2CredentialID, - HMACSalt: args.Fido2HmacSalt, - AssertOptions: args.Fido2AssertOptions, + CredentialID: args.Fido2CredentialID, + HMACSalt: args.Fido2HmacSalt, + AssertOptions: args.Fido2AssertOptions, } } // Catch bugs and invalid cli flag combinations early @@ -133,7 +136,7 @@ func Create(args *CreateArgs) error { key := args.Masterkey if key == nil { // Generate new random master key - key = cryptocore.RandBytes(cryptocore.KeyLen) + key = cryptocore.RandBytes(cryptocore.MaxKeyLen) } tlog.PrintMasterkeyReminder(key) // Encrypt it using the password @@ -327,6 +330,9 @@ func (cf *ConfFile) ContentEncryption() (algo cryptocore.AEADTypeEnum, err error if cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) { return cryptocore.BackendXChaCha20Poly1305, nil } + if cf.IsFeatureFlagSet(FlagAegis) { + return cryptocore.BackendAegis, nil + } if cf.IsFeatureFlagSet(FlagAESSIV) { return cryptocore.BackendAESSIV, nil } diff --git a/internal/configfile/feature_flags.go b/internal/configfile/feature_flags.go index d6627a5..2722831 100644 --- a/internal/configfile/feature_flags.go +++ b/internal/configfile/feature_flags.go @@ -34,6 +34,8 @@ const ( FlagFIDO2 // FlagXChaCha20Poly1305 means we use XChaCha20-Poly1305 file content encryption FlagXChaCha20Poly1305 + // FlagAegis means we use Aegis file content encryption + FlagAegis ) // knownFlags stores the known feature flags and their string representation @@ -49,6 +51,7 @@ var knownFlags = map[flagIota]string{ FlagHKDF: "HKDF", FlagFIDO2: "FIDO2", FlagXChaCha20Poly1305: "XChaCha20Poly1305", + FlagAegis: "AEGIS", } // isFeatureFlagKnown verifies that we understand a feature flag. diff --git a/internal/configfile/scrypt.go b/internal/configfile/scrypt.go index 0ce8777..b82a431 100644 --- a/internal/configfile/scrypt.go +++ b/internal/configfile/scrypt.go @@ -49,7 +49,7 @@ type ScryptKDF struct { // NewScryptKDF returns a new instance of ScryptKDF. func NewScryptKDF(logN int) ScryptKDF { var s ScryptKDF - s.Salt = cryptocore.RandBytes(cryptocore.KeyLen) + s.Salt = cryptocore.RandBytes(cryptocore.MaxKeyLen) if logN <= 0 { s.N = 1 << ScryptDefaultLogN } else { @@ -57,7 +57,7 @@ func NewScryptKDF(logN int) ScryptKDF { } s.R = 8 // Always 8 s.P = 1 // Always 1 - s.KeyLen = cryptocore.KeyLen + s.KeyLen = cryptocore.MaxKeyLen return s } @@ -98,8 +98,8 @@ func (s *ScryptKDF) validateParams() error { if len(s.Salt) < scryptMinSaltLen { return fmt.Errorf("Fatal: scrypt salt length below minimum: value=%d, min=%d", len(s.Salt), scryptMinSaltLen) } - if s.KeyLen < cryptocore.KeyLen { - return fmt.Errorf("Fatal: scrypt parameter KeyLen below minimum: value=%d, min=%d", s.KeyLen, cryptocore.KeyLen) + if s.KeyLen < cryptocore.MinKeyLen { + return fmt.Errorf("Fatal: scrypt parameter KeyLen below minimum: value=%d, min=%d", s.KeyLen, cryptocore.MinKeyLen) } return nil } diff --git a/internal/configfile/validate.go b/internal/configfile/validate.go index ab8917d..333eea6 100644 --- a/internal/configfile/validate.go +++ b/internal/configfile/validate.go @@ -38,8 +38,13 @@ func (cf *ConfFile) Validate() error { return fmt.Errorf("XChaCha20Poly1305 requires HKDF feature flag") } } + if cf.IsFeatureFlagSet(FlagAegis) { + if cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("AEGIS conflicts with GCMIV128 feature flag") + } + } // The absence of other flags means AES-GCM (oldest algorithm) - if !cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && !cf.IsFeatureFlagSet(FlagAESSIV) { + if !cf.IsFeatureFlagSet(FlagAegis) && !cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && !cf.IsFeatureFlagSet(FlagAESSIV) { if !cf.IsFeatureFlagSet(FlagGCMIV128) { return fmt.Errorf("AES-GCM requires GCMIV128 feature flag") } |