auth.go 1.7 KB

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