github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/transport/internet/kcp/crypt.go (about) 1 package kcp 2 3 import ( 4 "crypto/cipher" 5 "encoding/binary" 6 "hash/fnv" 7 8 "github.com/v2fly/v2ray-core/v5/common" 9 ) 10 11 // SimpleAuthenticator is a legacy AEAD used for KCP encryption. 12 type SimpleAuthenticator struct{} 13 14 // NewSimpleAuthenticator creates a new SimpleAuthenticator 15 func NewSimpleAuthenticator() cipher.AEAD { 16 return &SimpleAuthenticator{} 17 } 18 19 // NonceSize implements cipher.AEAD.NonceSize(). 20 func (*SimpleAuthenticator) NonceSize() int { 21 return 0 22 } 23 24 // Overhead implements cipher.AEAD.NonceSize(). 25 func (*SimpleAuthenticator) Overhead() int { 26 return 6 27 } 28 29 // Seal implements cipher.AEAD.Seal(). 30 func (a *SimpleAuthenticator) Seal(dst, nonce, plain, extra []byte) []byte { 31 dst = append(dst, 0, 0, 0, 0, 0, 0) // 4 bytes for hash, and then 2 bytes for length 32 binary.BigEndian.PutUint16(dst[4:], uint16(len(plain))) 33 dst = append(dst, plain...) 34 35 fnvHash := fnv.New32a() 36 common.Must2(fnvHash.Write(dst[4:])) 37 fnvHash.Sum(dst[:0]) 38 39 dstLen := len(dst) 40 xtra := 4 - dstLen%4 41 if xtra != 4 { 42 dst = append(dst, make([]byte, xtra)...) 43 } 44 xorfwd(dst) 45 if xtra != 4 { 46 dst = dst[:dstLen] 47 } 48 return dst 49 } 50 51 // Open implements cipher.AEAD.Open(). 52 func (a *SimpleAuthenticator) Open(dst, nonce, cipherText, extra []byte) ([]byte, error) { 53 dst = append(dst, cipherText...) 54 dstLen := len(dst) 55 xtra := 4 - dstLen%4 56 if xtra != 4 { 57 dst = append(dst, make([]byte, xtra)...) 58 } 59 xorbkd(dst) 60 if xtra != 4 { 61 dst = dst[:dstLen] 62 } 63 64 fnvHash := fnv.New32a() 65 common.Must2(fnvHash.Write(dst[4:])) 66 if binary.BigEndian.Uint32(dst[:4]) != fnvHash.Sum32() { 67 return nil, newError("invalid auth") 68 } 69 70 length := binary.BigEndian.Uint16(dst[4:6]) 71 if len(dst)-6 != int(length) { 72 return nil, newError("invalid auth") 73 } 74 75 return dst[6:], nil 76 }