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 | |
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')
27 files changed, 217 insertions, 51 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") } diff --git a/internal/contentenc/content_test.go b/internal/contentenc/content_test.go index b20ccb1..2a34307 100644 --- a/internal/contentenc/content_test.go +++ b/internal/contentenc/content_test.go @@ -22,7 +22,8 @@ func TestSplitRange(t *testing.T) { {6654, 8945}, } - key := make([]byte, cryptocore.KeyLen) + keyLen := cryptocore.BackendGoGCM.KeyLen + key := make([]byte, keyLen) cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true) f := New(cc, DefaultBS) @@ -50,7 +51,8 @@ func TestCiphertextRange(t *testing.T) { {6654, 8945}, } - key := make([]byte, cryptocore.KeyLen) + keyLen := cryptocore.BackendGoGCM.KeyLen + key := make([]byte, keyLen) cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true) f := New(cc, DefaultBS) @@ -73,7 +75,8 @@ func TestCiphertextRange(t *testing.T) { } func TestBlockNo(t *testing.T) { - key := make([]byte, cryptocore.KeyLen) + keyLen := cryptocore.BackendGoGCM.KeyLen + key := make([]byte, keyLen) cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true) f := New(cc, DefaultBS) diff --git a/internal/contentenc/offsets_test.go b/internal/contentenc/offsets_test.go index b35964a..0118c5e 100644 --- a/internal/contentenc/offsets_test.go +++ b/internal/contentenc/offsets_test.go @@ -9,7 +9,8 @@ import ( // TestSizeToSize tests CipherSizeToPlainSize and PlainSizeToCipherSize func TestSizeToSize(t *testing.T) { - key := make([]byte, cryptocore.KeyLen) + keyLen := cryptocore.BackendGoGCM.KeyLen + key := make([]byte, keyLen) cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true) ce := New(cc, DefaultBS) diff --git a/internal/cryptocore/cryptocore.go b/internal/cryptocore/cryptocore.go index 72c9c23..0848096 100644 --- a/internal/cryptocore/cryptocore.go +++ b/internal/cryptocore/cryptocore.go @@ -11,6 +11,7 @@ import ( "golang.org/x/crypto/chacha20poly1305" + "github.com/aegis-aead/go-libaegis/aegis128x2" "github.com/rfjakob/eme" "github.com/rfjakob/gocryptfs/v2/internal/siv_aead" @@ -19,11 +20,13 @@ import ( ) const ( - // KeyLen is the cipher key length in bytes. All backends use 32 bytes. - KeyLen = 32 // AuthTagLen is the length of a authentication tag in bytes. // All backends use 16 bytes. AuthTagLen = 16 + // Minimum key length + MinKeyLen = 16 + // Maximum key length + MaxKeyLen = 32 ) // AEADTypeEnum indicates the type of AEAD backend in use. @@ -32,6 +35,7 @@ type AEADTypeEnum struct { Algo string // Lib is the library where Algo is implemented. Either "Go" or "OpenSSL". Lib string + KeyLen int NonceSize int } @@ -42,22 +46,24 @@ func (a AEADTypeEnum) String() string { // BackendOpenSSL specifies the OpenSSL AES-256-GCM backend. // "AES-GCM-256-OpenSSL" in gocryptfs -speed. -var BackendOpenSSL = AEADTypeEnum{"AES-GCM-256", "OpenSSL", 16} +var BackendOpenSSL = AEADTypeEnum{"AES-GCM-256", "OpenSSL", 32, 16} // BackendGoGCM specifies the Go based AES-256-GCM backend. // "AES-GCM-256-Go" in gocryptfs -speed. -var BackendGoGCM = AEADTypeEnum{"AES-GCM-256", "Go", 16} +var BackendGoGCM = AEADTypeEnum{"AES-GCM-256", "Go", 32, 16} // BackendAESSIV specifies an AESSIV backend. // "AES-SIV-512-Go" in gocryptfs -speed. -var BackendAESSIV = AEADTypeEnum{"AES-SIV-512", "Go", siv_aead.NonceSize} +var BackendAESSIV = AEADTypeEnum{"AES-SIV-512", "Go", 32, siv_aead.NonceSize} // BackendXChaCha20Poly1305 specifies XChaCha20-Poly1305-Go. // "XChaCha20-Poly1305-Go" in gocryptfs -speed. -var BackendXChaCha20Poly1305 = AEADTypeEnum{"XChaCha20-Poly1305", "Go", chacha20poly1305.NonceSizeX} +var BackendXChaCha20Poly1305 = AEADTypeEnum{"XChaCha20-Poly1305", "Go", 32, chacha20poly1305.NonceSizeX} // BackendXChaCha20Poly1305OpenSSL specifies XChaCha20-Poly1305-OpenSSL. -var BackendXChaCha20Poly1305OpenSSL = AEADTypeEnum{"XChaCha20-Poly1305", "OpenSSL", chacha20poly1305.NonceSizeX} +var BackendXChaCha20Poly1305OpenSSL = AEADTypeEnum{"XChaCha20-Poly1305", "OpenSSL", 32, chacha20poly1305.NonceSizeX} + +var BackendAegis = AEADTypeEnum{"Aegis128X2", "Go", 16, aegis128x2.NonceSize} // CryptoCore is the low level crypto implementation. type CryptoCore struct { @@ -85,9 +91,14 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool) *CryptoC tlog.Debug.Printf("cryptocore.New: key=%d bytes, aeadType=%v, IVBitLen=%d, useHKDF=%v", len(key), aeadType, IVBitLen, useHKDF) - if len(key) != KeyLen { + keyLen := aeadType.KeyLen + if keyLen < MinKeyLen || keyLen > MaxKeyLen { + log.Panicf("Unsupported key length of %d bytes", keyLen) + } + if len(key) < keyLen { log.Panicf("Unsupported key length of %d bytes", len(key)) } + key = key[:keyLen] // keys can safely be truncated if IVBitLen != 96 && IVBitLen != 128 && IVBitLen != chacha20poly1305.NonceSizeX*8 { log.Panicf("Unsupported IV length of %d bits", IVBitLen) } @@ -98,7 +109,7 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool) *CryptoC { var emeBlockCipher cipher.Block if useHKDF { - emeKey := hkdfDerive(key, hkdfInfoEMENames, KeyLen) + emeKey := hkdfDerive(key, hkdfInfoEMENames, keyLen) emeBlockCipher, err = aes.NewCipher(emeKey) for i := range emeKey { emeKey[i] = 0 @@ -117,7 +128,7 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool) *CryptoC if aeadType == BackendOpenSSL || aeadType == BackendGoGCM { var gcmKey []byte if useHKDF { - gcmKey = hkdfDerive(key, hkdfInfoGCMContent, KeyLen) + gcmKey = hkdfDerive(key, hkdfInfoGCMContent, keyLen) } else { // Filesystems created by gocryptfs v0.7 through v1.2 don't use HKDF. // Example: tests/example_filesystems/v0.9 @@ -183,6 +194,23 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool) *CryptoC if err != nil { log.Panic(err) } + } else if aeadType == BackendAegis { + if stupidgcm.BuiltWithoutAegis { + log.Panic("AEGIS is not available") + } + if IVBitLen != 128 { + log.Panicf("AEGIS must use 128-bit IVs, you wanted %d", IVBitLen) + } + var aegisKey []byte + if useHKDF { + aegisKey = hkdfDerive(key, hkdfInfoGCMContent, keyLen) + } else { + aegisKey = append([]byte{}, key...) + } + aeadCipher = stupidgcm.NewAegis(aegisKey) + for i := range aegisKey { + aegisKey[i] = 0 + } } else { log.Panicf("unknown cipher backend %q", aeadType) } diff --git a/internal/exitcodes/exitcodes.go b/internal/exitcodes/exitcodes.go index 508ba38..6bf7672 100644 --- a/internal/exitcodes/exitcodes.go +++ b/internal/exitcodes/exitcodes.go @@ -72,6 +72,8 @@ const ( DevNull = 30 // FIDO2Error - an error was encountered while interacting with a FIDO2 token FIDO2Error = 31 + // Aegis means you tried to enable Aegis, but we were compiled without it. + Aegis = 32 ) // Err wraps an error with an associated numeric exit code diff --git a/internal/fusefrontend/xattr_unit_test.go b/internal/fusefrontend/xattr_unit_test.go index 86c87a7..5f69e00 100644 --- a/internal/fusefrontend/xattr_unit_test.go +++ b/internal/fusefrontend/xattr_unit_test.go @@ -16,7 +16,8 @@ import ( func newTestFS(args Args) *RootNode { // Init crypto backend - key := make([]byte, cryptocore.KeyLen) + keyLen := cryptocore.BackendGoGCM.KeyLen + key := make([]byte, keyLen) cCore := cryptocore.New(key, cryptocore.BackendGoGCM, contentenc.DefaultIVBits, true) cEnc := contentenc.New(cCore, contentenc.DefaultBS) n := nametransform.New(cCore.EMECipher, true, 0, true, nil, false) diff --git a/internal/nametransform/longnames_test.go b/internal/nametransform/longnames_test.go index 7a4e915..be18f92 100644 --- a/internal/nametransform/longnames_test.go +++ b/internal/nametransform/longnames_test.go @@ -34,7 +34,8 @@ func TestRemoveLongNameSuffix(t *testing.T) { } func newLognamesTestInstance(longNameMax uint8) *NameTransform { - key := make([]byte, cryptocore.KeyLen) + keyLen := cryptocore.BackendGoGCM.KeyLen + key := make([]byte, keyLen) cCore := cryptocore.New(key, cryptocore.BackendGoGCM, contentenc.DefaultIVBits, true) return New(cCore.EMECipher, true, longNameMax, true, nil, false) } diff --git a/internal/speed/speed.go b/internal/speed/speed.go index d6fa12e..e60e37d 100644 --- a/internal/speed/speed.go +++ b/internal/speed/speed.go @@ -47,13 +47,14 @@ func Run() { {name: cryptocore.BackendAESSIV.String(), f: bAESSIV, preferred: false}, {name: cryptocore.BackendXChaCha20Poly1305OpenSSL.String(), f: bStupidXchacha, preferred: stupidgcm.PreferOpenSSLXchacha20poly1305()}, {name: cryptocore.BackendXChaCha20Poly1305.String(), f: bXchacha20poly1305, preferred: !stupidgcm.PreferOpenSSLXchacha20poly1305()}, + {name: cryptocore.BackendAegis.String(), f: bAegis, preferred: false}, } testing.Init() for _, b := range bTable { fmt.Printf("%-26s\t", b.name) mbs := mbPerSec(testing.Benchmark(b.f)) if mbs > 0 { - fmt.Printf("%7.2f MB/s", mbs) + fmt.Printf("%8.2f MB/s", mbs) } else { fmt.Printf(" N/A") } @@ -168,3 +169,9 @@ func bStupidXchacha(b *testing.B) { } bEncrypt(b, stupidgcm.NewXchacha20poly1305(randBytes(32))) } + +// bAegis benchmarks Aegis from github.com/aegis-aead/go-libaegis +func bAegis(b *testing.B) { + c := stupidgcm.NewAegis(randBytes(16)) + bEncrypt(b, c) +} diff --git a/internal/stupidgcm/Makefile b/internal/stupidgcm/Makefile index 143819d..d8f7d2e 100644 --- a/internal/stupidgcm/Makefile +++ b/internal/stupidgcm/Makefile @@ -3,11 +3,15 @@ test: gcc # All three ways of building this must work go build go build -tags without_openssl - CGO_ENABLED=0 go build -tags without_openssl + go build -tags without_aegis + go build -tags without_openssl,without_aegis + CGO_ENABLED=0 go build -tags without_openssl,without_aegis # Likewise, all three ways of testing this must work go test -v go test -v -tags without_openssl - CGO_ENABLED=0 go test -v -tags without_openssl + go test -v -tags without_aegis + go test -v -tags without_openssl,without_aegis + CGO_ENABLED=0 go test -v -tags without_openssl,without_aegis .PHONY: gcc gcc: diff --git a/internal/stupidgcm/aegis.go b/internal/stupidgcm/aegis.go new file mode 100644 index 0000000..8975055 --- /dev/null +++ b/internal/stupidgcm/aegis.go @@ -0,0 +1,57 @@ +//go:build !without_aegis && cgo +// +build !without_aegis,cgo + +package stupidgcm + +import ( + "crypto/cipher" + "log" + + "github.com/aegis-aead/go-libaegis/aegis128x2" + "github.com/aegis-aead/go-libaegis/common" +) + +const ( + // BuiltWithoutAegis indicates if aegis been disabled at compile-time + BuiltWithoutAegis = !common.Available + + // Aegis supports 16 and 32 bit tags + AegisTagLen = 16 +) + +type stupidAegis struct { + aead cipher.AEAD +} + +// Verify that we satisfy the cipher.AEAD interface +var _ cipher.AEAD = &stupidAegis{} + +func (*stupidAegis) NonceSize() int { + return aegis128x2.NonceSize +} + +func (*stupidAegis) Overhead() int { + return AegisTagLen +} + +func NewAegis(key []byte) cipher.AEAD { + aead, err := aegis128x2.New(key, AegisTagLen) + if err != nil { + log.Panic(err) + } + return &stupidAegis{ + aead: aead, + } +} + +func (x *stupidAegis) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + return x.aead.Seal(dst, nonce, plaintext, additionalData) +} + +func (x *stupidAegis) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + return x.aead.Open(dst, nonce, ciphertext, additionalData) +} + +func (x *stupidAegis) Wipe() { + x.aead.(*aegis128x2.Aegis128X2).Wipe() +} diff --git a/internal/stupidgcm/aegis_test.go b/internal/stupidgcm/aegis_test.go new file mode 100644 index 0000000..36ef763 --- /dev/null +++ b/internal/stupidgcm/aegis_test.go @@ -0,0 +1,16 @@ +//go:build !without_aegis && cgo +// +build !without_aegis,cgo + +package stupidgcm + +import "testing" + +func TestStupidAegis(t *testing.T) { + if BuiltWithoutAegis { + t.Skip("Aegis support has been disabled at compile-time") + } + key := randBytes(16) + c := NewAegis(key) + + testCiphers(t, c, c) +} diff --git a/internal/stupidgcm/chacha.go b/internal/stupidgcm/chacha.go index de0c2e8..dcdcb3a 100644 --- a/internal/stupidgcm/chacha.go +++ b/internal/stupidgcm/chacha.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm diff --git a/internal/stupidgcm/chacha_test.go b/internal/stupidgcm/chacha_test.go index 542ff15..4fa038b 100644 --- a/internal/stupidgcm/chacha_test.go +++ b/internal/stupidgcm/chacha_test.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm diff --git a/internal/stupidgcm/common.go b/internal/stupidgcm/common.go index d88dc62..c5dd338 100644 --- a/internal/stupidgcm/common.go +++ b/internal/stupidgcm/common.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm diff --git a/internal/stupidgcm/common_test.go b/internal/stupidgcm/common_test.go index 7f38e90..47fee7c 100644 --- a/internal/stupidgcm/common_test.go +++ b/internal/stupidgcm/common_test.go @@ -246,6 +246,8 @@ func testWipe(t *testing.T, c cipher.AEAD) { t.Fatal("c2.key is not zeroed") } } + case *stupidAegis: + c2.Wipe() // AEGIS has its own Wipe method default: t.Fatalf("BUG: unhandled type %T", c2) } diff --git a/internal/stupidgcm/doc.go b/internal/stupidgcm/doc.go index dce82ae..f5d4177 100644 --- a/internal/stupidgcm/doc.go +++ b/internal/stupidgcm/doc.go @@ -1,5 +1,5 @@ -// Package stupidgcm wraps OpenSSL to provide a cipher.AEAD interface for -// authenticated encryption algorithms. +// Package stupidgcm wraps OpenSSL and libaegis to provide a cipher.AEAD +// interface for authenticated encryption algorithms. // // The supported algorithms are: // @@ -9,6 +9,8 @@ // // (3) XChaCha20-Poly1305 (OpenSSL EVP_chacha20_poly1305 + Go HChaCha20) // +// (4) AEGIS (go-libaegis) +// // The golang.org/x/crypto libraries provides implementations for all algorithms, // and the test suite verifies that the implementation in this package gives // the exact same results. diff --git a/internal/stupidgcm/gcm.go b/internal/stupidgcm/gcm.go index 2e5aac4..738021e 100644 --- a/internal/stupidgcm/gcm.go +++ b/internal/stupidgcm/gcm.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm diff --git a/internal/stupidgcm/gcm_test.go b/internal/stupidgcm/gcm_test.go index c730a87..6c15287 100644 --- a/internal/stupidgcm/gcm_test.go +++ b/internal/stupidgcm/gcm_test.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo // We compare against Go's built-in GCM implementation. Since stupidgcm only // supports 128-bit IVs and Go only supports that from 1.5 onward, we cannot diff --git a/internal/stupidgcm/locking.go b/internal/stupidgcm/locking.go index 04cf232..29f8332 100644 --- a/internal/stupidgcm/locking.go +++ b/internal/stupidgcm/locking.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm diff --git a/internal/stupidgcm/openssl.go b/internal/stupidgcm/openssl.go index 8c950f8..0360629 100644 --- a/internal/stupidgcm/openssl.go +++ b/internal/stupidgcm/openssl.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm diff --git a/internal/stupidgcm/without_aegis.go b/internal/stupidgcm/without_aegis.go new file mode 100644 index 0000000..efd665c --- /dev/null +++ b/internal/stupidgcm/without_aegis.go @@ -0,0 +1,28 @@ +//go:build without_aegis || !cgo +// +build without_aegis !cgo + +package stupidgcm + +import ( + "fmt" + "os" + + "crypto/cipher" + + "github.com/rfjakob/gocryptfs/v2/internal/exitcodes" +) + +const ( + // BuiltWithoutAegis indicates if openssl been disabled at compile-time + BuiltWithoutAegis = true +) + +type stupidAegis struct { + aead cipher.AEAD +} + +func NewAegis(_ []byte) cipher.AEAD { + fmt.Fprintln(os.Stderr, "I have been compiled without aegis support but you are still trying to use aegis") + os.Exit(exitcodes.Aegis) + return nil +} diff --git a/internal/stupidgcm/without_openssl.go b/internal/stupidgcm/without_openssl.go index fcef793..1901c78 100644 --- a/internal/stupidgcm/without_openssl.go +++ b/internal/stupidgcm/without_openssl.go @@ -1,5 +1,5 @@ -//go:build without_openssl -// +build without_openssl +//go:build without_openssl || !cgo +// +build without_openssl !cgo package stupidgcm diff --git a/internal/stupidgcm/xchacha.go b/internal/stupidgcm/xchacha.go index 3c121ba..0187da8 100644 --- a/internal/stupidgcm/xchacha.go +++ b/internal/stupidgcm/xchacha.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo // Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/internal/stupidgcm/xchacha_test.go b/internal/stupidgcm/xchacha_test.go index 676a023..bd62c04 100644 --- a/internal/stupidgcm/xchacha_test.go +++ b/internal/stupidgcm/xchacha_test.go @@ -1,5 +1,5 @@ -//go:build !without_openssl -// +build !without_openssl +//go:build !without_openssl && cgo +// +build !without_openssl,cgo package stupidgcm |