crypt.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package kcp
  2. import (
  3. "hash/fnv"
  4. "github.com/v2ray/v2ray-core/common/alloc"
  5. "github.com/v2ray/v2ray-core/common/serial"
  6. )
  7. type Authenticator interface {
  8. HeaderSize() int
  9. // Encrypt encrypts the whole block in src into dst.
  10. // Dst and src may point at the same memory.
  11. Seal(buffer *alloc.Buffer)
  12. // Decrypt decrypts the whole block in src into dst.
  13. // Dst and src may point at the same memory.
  14. Open(buffer *alloc.Buffer) bool
  15. }
  16. type SimpleAuthenticator struct{}
  17. func NewSimpleAuthenticator() Authenticator {
  18. return &SimpleAuthenticator{}
  19. }
  20. func (this *SimpleAuthenticator) HeaderSize() int {
  21. return 6
  22. }
  23. func (this *SimpleAuthenticator) Seal(buffer *alloc.Buffer) {
  24. buffer.PrependUint16(uint16(buffer.Len()))
  25. fnvHash := fnv.New32a()
  26. fnvHash.Write(buffer.Value)
  27. buffer.PrependHash(fnvHash)
  28. len := buffer.Len()
  29. xtra := 4 - len%4
  30. if xtra != 0 {
  31. buffer.Slice(0, len+xtra)
  32. }
  33. xorfwd(buffer.Value)
  34. if xtra != 0 {
  35. buffer.Slice(0, len)
  36. }
  37. }
  38. func (this *SimpleAuthenticator) Open(buffer *alloc.Buffer) bool {
  39. len := buffer.Len()
  40. xtra := 4 - len%4
  41. if xtra != 0 {
  42. buffer.Slice(0, len+xtra)
  43. }
  44. xorbkd(buffer.Value)
  45. if xtra != 0 {
  46. buffer.Slice(0, len)
  47. }
  48. fnvHash := fnv.New32a()
  49. fnvHash.Write(buffer.Value[4:])
  50. if serial.BytesToUint32(buffer.Value[:4]) != fnvHash.Sum32() {
  51. return false
  52. }
  53. length := serial.BytesToUint16(buffer.Value[4:6])
  54. if buffer.Len()-6 != int(length) {
  55. return false
  56. }
  57. buffer.SliceFrom(6)
  58. return true
  59. }