github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/proxy/shadowsocks2022/eih_aes.go (about) 1 package shadowsocks2022 2 3 import ( 4 "crypto/subtle" 5 "io" 6 7 "github.com/lunixbochs/struc" 8 9 "github.com/v2fly/v2ray-core/v5/common/buf" 10 11 "lukechampine.com/blake3" 12 ) 13 14 func newAESEIH(size int) *aesEIH { 15 return &aesEIH{length: size} 16 } 17 18 func newAESEIHWithData(size int, eih [][aesEIHSize]byte) *aesEIH { 19 return &aesEIH{length: size, eih: eih} 20 } 21 22 const aesEIHSize = 16 23 24 type aesEIH struct { 25 eih [][aesEIHSize]byte 26 length int 27 } 28 29 func (a *aesEIH) Pack(p []byte, opt *struc.Options) (int, error) { 30 var totalCopy int 31 for i := 0; i < a.length; i++ { 32 n := copy(p[aesEIHSize*i:aesEIHSize*(i+1)], a.eih[i][:]) 33 if n != 16 { 34 return 0, newError("failed to pack aesEIH") 35 } 36 totalCopy += n 37 } 38 return totalCopy, nil 39 } 40 41 func (a *aesEIH) Unpack(r io.Reader, length int, opt *struc.Options) error { 42 a.eih = make([][aesEIHSize]byte, a.length) 43 for i := 0; i < a.length; i++ { 44 n, err := r.Read(a.eih[i][:]) 45 if err != nil { 46 return newError("failed to unpack aesEIH").Base(err) 47 } 48 if n != aesEIHSize { 49 return newError("failed to unpack aesEIH") 50 } 51 } 52 return nil 53 } 54 55 func (a *aesEIH) Size(opt *struc.Options) int { 56 return a.length * aesEIHSize 57 } 58 59 func (a *aesEIH) String() string { 60 return "" 61 } 62 63 const aesEIHPskHashSize = 16 64 65 type aesEIHGenerator struct { 66 ipsk [][]byte 67 ipskHash [][aesEIHPskHashSize]byte 68 psk []byte 69 pskHash [aesEIHPskHashSize]byte 70 length int 71 } 72 73 func newAESEIHGeneratorContainer(size int, effectivePsk []byte, ipsk [][]byte) *aesEIHGenerator { 74 var ipskHash [][aesEIHPskHashSize]byte 75 for _, v := range ipsk { 76 hash := blake3.Sum512(v) 77 ipskHash = append(ipskHash, [aesEIHPskHashSize]byte(hash[:16])) 78 } 79 pskHashFull := blake3.Sum512(effectivePsk) 80 pskHash := [aesEIHPskHashSize]byte(pskHashFull[:16]) 81 return &aesEIHGenerator{length: size, ipsk: ipsk, ipskHash: ipskHash, psk: effectivePsk, pskHash: pskHash} 82 } 83 84 func (a *aesEIHGenerator) GenerateEIH(derivation KeyDerivation, method Method, salt []byte) (ExtensibleIdentityHeaders, error) { 85 return a.generateEIHWithMask(derivation, method, salt, nil) 86 } 87 88 func (a *aesEIHGenerator) GenerateEIHUDP(derivation KeyDerivation, method Method, mask []byte) (ExtensibleIdentityHeaders, error) { 89 return a.generateEIHWithMask(derivation, method, nil, mask) 90 } 91 92 func (a *aesEIHGenerator) generateEIHWithMask(derivation KeyDerivation, method Method, salt, mask []byte) (ExtensibleIdentityHeaders, error) { 93 eih := make([][16]byte, a.length) 94 current := a.length - 1 95 currentPskHash := a.pskHash 96 for { 97 identityKeyBuf := buf.New() 98 identityKey := identityKeyBuf.Extend(int32(method.GetSessionSubKeyAndSaltLength())) 99 if mask == nil { 100 err := derivation.GetIdentitySubKey(a.ipsk[current], salt, identityKey) 101 if err != nil { 102 return nil, newError("failed to get identity sub key").Base(err) 103 } 104 } else { 105 copy(identityKey, a.ipsk[current]) 106 } 107 eih[current] = [16]byte{} 108 if mask != nil { 109 subtle.XORBytes(currentPskHash[:], mask, currentPskHash[:]) 110 } 111 err := method.GenerateEIH(identityKey, currentPskHash[:], eih[current][:]) 112 if err != nil { 113 return nil, newError("failed to generate EIH").Base(err) 114 } 115 current-- 116 if current < 0 { 117 break 118 } 119 currentPskHash = a.ipskHash[current] 120 identityKeyBuf.Release() 121 } 122 return newAESEIHWithData(a.length, eih), nil 123 }