chachapoly.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package noiseutil
  2. import (
  3. "crypto/cipher"
  4. "encoding/binary"
  5. "errors"
  6. "github.com/flynn/noise"
  7. )
  8. // CipherStateChaChaPoly is the data-plane wrapper for the ChaCha20-Poly1305 AEAD cipher.
  9. // ChaCha20-Poly1305 uses little-endian nonce encoding per the Noise spec.
  10. type CipherStateChaChaPoly struct {
  11. c cipher.AEAD
  12. }
  13. // NewCipherStateChaChaPoly extracts the underlying AEAD from the post-handshake noise.CipherState.
  14. // The caller is responsible for ensuring the noise cipher is actually ChaCha20-Poly1305.
  15. func NewCipherStateChaChaPoly(s *noise.CipherState) *CipherStateChaChaPoly {
  16. return &CipherStateChaChaPoly{c: s.Cipher().(cipher.AEAD)}
  17. }
  18. func (s *CipherStateChaChaPoly) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
  19. if s == nil {
  20. return nil, errors.New("no cipher state available to encrypt")
  21. }
  22. nb[0] = 0
  23. nb[1] = 0
  24. nb[2] = 0
  25. nb[3] = 0
  26. binary.LittleEndian.PutUint64(nb[4:], n)
  27. return s.c.Seal(out, nb, plaintext, ad), nil
  28. }
  29. func (s *CipherStateChaChaPoly) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
  30. if s == nil {
  31. return []byte{}, nil
  32. }
  33. nb[0] = 0
  34. nb[1] = 0
  35. nb[2] = 0
  36. nb[3] = 0
  37. binary.LittleEndian.PutUint64(nb[4:], n)
  38. return s.c.Open(out, nb, ciphertext, ad)
  39. }
  40. func (s *CipherStateChaChaPoly) Overhead() int {
  41. if s == nil {
  42. return 0
  43. }
  44. return s.c.Overhead()
  45. }