crypt.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package kcp
  2. import (
  3. "crypto/cipher"
  4. "errors"
  5. "hash/fnv"
  6. "v2ray.com/core/common/serial"
  7. )
  8. // SimpleAuthenticator is a legacy AEAD used for KCP encryption.
  9. type SimpleAuthenticator struct{}
  10. // NewSimpleAuthenticator creates a new SimpleAuthenticator
  11. func NewSimpleAuthenticator() cipher.AEAD {
  12. return &SimpleAuthenticator{}
  13. }
  14. // NonceSize implements cipher.AEAD.NonceSize().
  15. func (v *SimpleAuthenticator) NonceSize() int {
  16. return 0
  17. }
  18. // Overhead implements cipher.AEAD.NonceSize().
  19. func (v *SimpleAuthenticator) Overhead() int {
  20. return 6
  21. }
  22. // Seal implements cipher.AEAD.Seal().
  23. func (v *SimpleAuthenticator) Seal(dst, nonce, plain, extra []byte) []byte {
  24. dst = append(dst, 0, 0, 0, 0)
  25. dst = serial.Uint16ToBytes(uint16(len(plain)), dst)
  26. dst = append(dst, plain...)
  27. fnvHash := fnv.New32a()
  28. fnvHash.Write(dst[4:])
  29. fnvHash.Sum(dst[:0])
  30. len := len(dst)
  31. xtra := 4 - len%4
  32. if xtra != 4 {
  33. dst = append(dst, make([]byte, xtra)...)
  34. }
  35. xorfwd(dst)
  36. if xtra != 4 {
  37. dst = dst[:len]
  38. }
  39. return dst
  40. }
  41. // Open implements cipher.AEAD.Open().
  42. func (v *SimpleAuthenticator) Open(dst, nonce, cipherText, extra []byte) ([]byte, error) {
  43. dst = append(dst, cipherText...)
  44. dstLen := len(dst)
  45. xtra := 4 - dstLen%4
  46. if xtra != 4 {
  47. dst = append(dst, make([]byte, xtra)...)
  48. }
  49. xorbkd(dst)
  50. if xtra != 4 {
  51. dst = dst[:dstLen]
  52. }
  53. fnvHash := fnv.New32a()
  54. fnvHash.Write(dst[4:])
  55. if serial.BytesToUint32(dst[:4]) != fnvHash.Sum32() {
  56. return nil, errors.New("KCP:SimpleAuthenticator: Invalid auth.")
  57. }
  58. length := serial.BytesToUint16(dst[4:6])
  59. if len(dst)-6 != int(length) {
  60. return nil, errors.New("KCP:SimpleAuthenticator: Invalid auth.")
  61. }
  62. return dst[6:], nil
  63. }