1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- //go:build boringcrypto
- // +build boringcrypto
- package noiseutil
- import (
- "crypto/aes"
- "crypto/cipher"
- "encoding/binary"
- // unsafe needed for go:linkname
- _ "unsafe"
- "github.com/flynn/noise"
- )
- // EncryptLockNeeded indicates if calls to Encrypt need a lock
- // This is true for boringcrypto because the Seal function verifies that the
- // nonce is strictly increasing.
- const EncryptLockNeeded = true
- // NewGCMTLS is no longer exposed in go1.19+, so we need to link it in
- // See: https://github.com/golang/go/issues/56326
- //
- // NewGCMTLS is the internal method used with boringcrypto that provices a
- // validated mode of AES-GCM which enforces the nonce is strictly
- // monotonically increasing. This is the TLS 1.2 specification for nonce
- // generation (which also matches the method used by the Noise Protocol)
- //
- // - https://github.com/golang/go/blob/go1.19/src/crypto/tls/cipher_suites.go#L520-L522
- // - https://github.com/golang/go/blob/go1.19/src/crypto/internal/boring/aes.go#L235-L237
- // - https://github.com/golang/go/blob/go1.19/src/crypto/internal/boring/aes.go#L250
- // - https://github.com/google/boringssl/blob/ae223d6138807a13006342edfeef32e813246b39/include/openssl/aead.h#L379-L381
- // - https://github.com/google/boringssl/blob/ae223d6138807a13006342edfeef32e813246b39/crypto/fipsmodule/cipher/e_aes.c#L1082-L1093
- //
- //go:linkname newGCMTLS crypto/internal/boring.NewGCMTLS
- func newGCMTLS(c cipher.Block) (cipher.AEAD, error)
- type cipherFn struct {
- fn func([32]byte) noise.Cipher
- name string
- }
- func (c cipherFn) Cipher(k [32]byte) noise.Cipher { return c.fn(k) }
- func (c cipherFn) CipherName() string { return c.name }
- // CipherAESGCM is the AES256-GCM AEAD cipher (using NewGCMTLS when GoBoring is present)
- var CipherAESGCM noise.CipherFunc = cipherFn{cipherAESGCMBoring, "AESGCM"}
- func cipherAESGCMBoring(k [32]byte) noise.Cipher {
- c, err := aes.NewCipher(k[:])
- if err != nil {
- panic(err)
- }
- gcm, err := newGCMTLS(c)
- if err != nil {
- panic(err)
- }
- return aeadCipher{
- gcm,
- func(n uint64) []byte {
- var nonce [12]byte
- binary.BigEndian.PutUint64(nonce[4:], n)
- return nonce[:]
- },
- }
- }
- type aeadCipher struct {
- cipher.AEAD
- nonce func(uint64) []byte
- }
- func (c aeadCipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte {
- return c.Seal(out, c.nonce(n), plaintext, ad)
- }
- func (c aeadCipher) Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) {
- return c.Open(out, c.nonce(n), ciphertext, ad)
- }
|