auth.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package encoding
  2. import (
  3. "crypto/md5"
  4. "hash/fnv"
  5. "v2ray.com/core/common/errors"
  6. "v2ray.com/core/common/serial"
  7. )
  8. // Authenticate authenticates a byte array using Fnv hash.
  9. func Authenticate(b []byte) uint32 {
  10. fnv1hash := fnv.New32a()
  11. fnv1hash.Write(b)
  12. return fnv1hash.Sum32()
  13. }
  14. type NoOpAuthenticator struct{}
  15. func (NoOpAuthenticator) NonceSize() int {
  16. return 0
  17. }
  18. func (NoOpAuthenticator) Overhead() int {
  19. return 0
  20. }
  21. // Seal implements AEAD.Seal().
  22. func (NoOpAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
  23. return append(dst[:0], plaintext...)
  24. }
  25. // Open implements AEAD.Open().
  26. func (NoOpAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
  27. return append(dst[:0], ciphertext...), nil
  28. }
  29. // FnvAuthenticator is an AEAD based on Fnv hash.
  30. type FnvAuthenticator struct {
  31. }
  32. // NonceSize implements AEAD.NonceSize().
  33. func (v *FnvAuthenticator) NonceSize() int {
  34. return 0
  35. }
  36. // Overhead impelements AEAD.Overhead().
  37. func (v *FnvAuthenticator) Overhead() int {
  38. return 4
  39. }
  40. // Seal implements AEAD.Seal().
  41. func (v *FnvAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
  42. dst = serial.Uint32ToBytes(Authenticate(plaintext), dst)
  43. return append(dst, plaintext...)
  44. }
  45. // Open implements AEAD.Open().
  46. func (v *FnvAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
  47. if serial.BytesToUint32(ciphertext[:4]) != Authenticate(ciphertext[4:]) {
  48. return dst, errors.New("invalid authentication").Path("Proxy", "VMess", "Encoding", "FnvAuthenticator")
  49. }
  50. return append(dst, ciphertext[4:]...), nil
  51. }
  52. // GenerateChacha20Poly1305Key generates a 32-byte key from a given 16-byte array.
  53. func GenerateChacha20Poly1305Key(b []byte) []byte {
  54. key := make([]byte, 32)
  55. t := md5.Sum(b)
  56. copy(key, t[:])
  57. t = md5.Sum(key[:16])
  58. copy(key[16:], t[:])
  59. return key
  60. }