diff --git a/internal/stupidgcm/chacha.go b/internal/stupidgcm/chacha.go index 2e6e6e6..c90d721 100644 --- a/internal/stupidgcm/chacha.go +++ b/internal/stupidgcm/chacha.go @@ -21,6 +21,20 @@ type stupidChacha20poly1305 struct { // Verify that we satisfy the cipher.AEAD interface var _ cipher.AEAD = &stupidChacha20poly1305{} +// _EVP_chacha20_poly1305 caches C.EVP_chacha20_poly1305() to avoid the Cgo call +// overhead for each instantiation of NewChacha20poly1305. +var _EVP_chacha20_poly1305 *C.EVP_CIPHER + +func init() { + _EVP_chacha20_poly1305 = C.EVP_chacha20_poly1305() +} + +// NewChacha20poly1305 returns a new instance of the OpenSSL ChaCha20-Poly1305 AEAD +// cipher ( https://www.openssl.org/docs/man1.1.1/man3/EVP_chacha20_poly1305.html ). +// +// gocryptfs only uses ChaCha20-Poly1305 as a building block for OpenSSL +// XChaCha20-Poly1305. This function is hot because it gets called once for each +// block by XChaCha20-Poly1305. func NewChacha20poly1305(key []byte) *stupidChacha20poly1305 { if len(key) != chacha20poly1305.KeySize { log.Panicf("Only %d-byte keys are supported, you passed %d bytes", chacha20poly1305.KeySize, len(key)) @@ -28,7 +42,7 @@ func NewChacha20poly1305(key []byte) *stupidChacha20poly1305 { return &stupidChacha20poly1305{ stupidAEADCommon{ key: append([]byte{}, key...), // private copy - openSSLEVPCipher: C.EVP_chacha20_poly1305(), + openSSLEVPCipher: _EVP_chacha20_poly1305, nonceSize: chacha20poly1305.NonceSize, }, }