github.com/xxf098/lite-proxy@v0.15.1-0.20230422081941-12c69f323218/transport/ssr/protocol/auth_aes128_sha1.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "math" 7 "math/rand" 8 "net" 9 "strconv" 10 "strings" 11 12 "github.com/xxf098/lite-proxy/common/pool" 13 "github.com/xxf098/lite-proxy/log" 14 "github.com/xxf098/lite-proxy/transport/ssr/tools" 15 ) 16 17 type ( 18 hmacMethod func(key, data []byte) []byte 19 hashDigestMethod func([]byte) []byte 20 ) 21 22 func init() { 23 register("auth_aes128_sha1", newAuthAES128SHA1, 9) 24 } 25 26 type authAES128Function struct { 27 salt string 28 hmac hmacMethod 29 hashDigest hashDigestMethod 30 } 31 32 type authAES128 struct { 33 *Base 34 *authData 35 *authAES128Function 36 *userData 37 iv []byte 38 hasSentHeader bool 39 rawTrans bool 40 packID uint32 41 recvID uint32 42 } 43 44 func newAuthAES128SHA1(b *Base) Protocol { 45 a := &authAES128{ 46 Base: b, 47 authData: &authData{}, 48 authAES128Function: &authAES128Function{salt: "auth_aes128_sha1", hmac: tools.HmacSHA1, hashDigest: tools.SHA1Sum}, 49 userData: &userData{}, 50 } 51 a.initUserData() 52 return a 53 } 54 55 func (a *authAES128) initUserData() { 56 params := strings.Split(a.Param, ":") 57 if len(params) > 1 { 58 if userID, err := strconv.ParseUint(params[0], 10, 32); err == nil { 59 binary.LittleEndian.PutUint32(a.userID[:], uint32(userID)) 60 a.userKey = a.hashDigest([]byte(params[1])) 61 } else { 62 log.Warnln("Wrong protocol-param for %s, only digits are expected before ':'", a.salt) 63 } 64 } 65 if len(a.userKey) == 0 { 66 a.userKey = a.Key 67 rand.Read(a.userID[:]) 68 } 69 } 70 71 func (a *authAES128) StreamConn(c net.Conn, iv []byte) net.Conn { 72 p := &authAES128{ 73 Base: a.Base, 74 authData: a.next(), 75 authAES128Function: a.authAES128Function, 76 userData: a.userData, 77 packID: 1, 78 recvID: 1, 79 } 80 p.iv = iv 81 return &Conn{Conn: c, Protocol: p} 82 } 83 84 func (a *authAES128) PacketConn(c net.PacketConn) net.PacketConn { 85 p := &authAES128{ 86 Base: a.Base, 87 authAES128Function: a.authAES128Function, 88 userData: a.userData, 89 } 90 return &PacketConn{PacketConn: c, Protocol: p} 91 } 92 93 func (a *authAES128) Decode(dst, src *bytes.Buffer) error { 94 if a.rawTrans { 95 dst.ReadFrom(src) 96 return nil 97 } 98 for src.Len() > 4 { 99 macKey := pool.Get(len(a.userKey) + 4) 100 defer pool.Put(macKey) 101 copy(macKey, a.userKey) 102 binary.LittleEndian.PutUint32(macKey[len(a.userKey):], a.recvID) 103 if !bytes.Equal(a.hmac(macKey, src.Bytes()[:2])[:2], src.Bytes()[2:4]) { 104 src.Reset() 105 return errAuthAES128MACError 106 } 107 108 length := int(binary.LittleEndian.Uint16(src.Bytes()[:2])) 109 if length >= 8192 || length < 7 { 110 a.rawTrans = true 111 src.Reset() 112 return errAuthAES128LengthError 113 } 114 if length > src.Len() { 115 break 116 } 117 118 if !bytes.Equal(a.hmac(macKey, src.Bytes()[:length-4])[:4], src.Bytes()[length-4:length]) { 119 a.rawTrans = true 120 src.Reset() 121 return errAuthAES128ChksumError 122 } 123 124 a.recvID++ 125 126 pos := int(src.Bytes()[4]) 127 if pos < 255 { 128 pos += 4 129 } else { 130 pos = int(binary.LittleEndian.Uint16(src.Bytes()[5:7])) + 4 131 } 132 dst.Write(src.Bytes()[pos : length-4]) 133 src.Next(length) 134 } 135 return nil 136 } 137 138 func (a *authAES128) Encode(buf *bytes.Buffer, b []byte) error { 139 fullDataLength := len(b) 140 if !a.hasSentHeader { 141 dataLength := getDataLength(b) 142 a.packAuthData(buf, b[:dataLength]) 143 b = b[dataLength:] 144 a.hasSentHeader = true 145 } 146 for len(b) > 8100 { 147 a.packData(buf, b[:8100], fullDataLength) 148 b = b[8100:] 149 } 150 if len(b) > 0 { 151 a.packData(buf, b, fullDataLength) 152 } 153 return nil 154 } 155 156 func (a *authAES128) DecodePacket(b []byte) ([]byte, error) { 157 if len(b) < 4 { 158 return nil, errAuthAES128LengthError 159 } 160 if !bytes.Equal(a.hmac(a.Key, b[:len(b)-4])[:4], b[len(b)-4:]) { 161 return nil, errAuthAES128ChksumError 162 } 163 return b[:len(b)-4], nil 164 } 165 166 func (a *authAES128) EncodePacket(buf *bytes.Buffer, b []byte) error { 167 buf.Write(b) 168 buf.Write(a.userID[:]) 169 buf.Write(a.hmac(a.userKey, buf.Bytes())[:4]) 170 return nil 171 } 172 173 func (a *authAES128) packData(poolBuf *bytes.Buffer, data []byte, fullDataLength int) { 174 dataLength := len(data) 175 randDataLength := a.getRandDataLengthForPackData(dataLength, fullDataLength) 176 /* 177 2: uint16 LittleEndian packedDataLength 178 2: hmac of packedDataLength 179 3: maxRandDataLengthPrefix (min:1) 180 4: hmac of packedData except the last 4 bytes 181 */ 182 packedDataLength := 2 + 2 + 3 + randDataLength + dataLength + 4 183 if randDataLength < 128 { 184 packedDataLength -= 2 185 } 186 187 macKey := pool.Get(len(a.userKey) + 4) 188 defer pool.Put(macKey) 189 copy(macKey, a.userKey) 190 binary.LittleEndian.PutUint32(macKey[len(a.userKey):], a.packID) 191 a.packID++ 192 193 binary.Write(poolBuf, binary.LittleEndian, uint16(packedDataLength)) 194 poolBuf.Write(a.hmac(macKey, poolBuf.Bytes()[poolBuf.Len()-2:])[:2]) 195 a.packRandData(poolBuf, randDataLength) 196 poolBuf.Write(data) 197 poolBuf.Write(a.hmac(macKey, poolBuf.Bytes()[poolBuf.Len()-packedDataLength+4:])[:4]) 198 } 199 200 func trapezoidRandom(max int, d float64) int { 201 base := rand.Float64() 202 if d-0 > 1e-6 { 203 a := 1 - d 204 base = (math.Sqrt(a*a+4*d*base) - a) / (2 * d) 205 } 206 return int(base * float64(max)) 207 } 208 209 func (a *authAES128) getRandDataLengthForPackData(dataLength, fullDataLength int) int { 210 if fullDataLength >= 32*1024-a.Overhead { 211 return 0 212 } 213 // 1460: tcp_mss 214 revLength := 1460 - dataLength - 9 215 if revLength == 0 { 216 return 0 217 } 218 if revLength < 0 { 219 if revLength > -1460 { 220 return trapezoidRandom(revLength+1460, -0.3) 221 } 222 return rand.Intn(32) 223 } 224 if dataLength > 900 { 225 return rand.Intn(revLength) 226 } 227 return trapezoidRandom(revLength, -0.3) 228 } 229 230 func (a *authAES128) packAuthData(poolBuf *bytes.Buffer, data []byte) { 231 if len(data) == 0 { 232 return 233 } 234 dataLength := len(data) 235 randDataLength := a.getRandDataLengthForPackAuthData(dataLength) 236 /* 237 7: checkHead(1) and hmac of checkHead(6) 238 4: userID 239 16: encrypted data of authdata(12), uint16 BigEndian packedDataLength(2) and uint16 BigEndian randDataLength(2) 240 4: hmac of userID and encrypted data 241 4: hmac of packedAuthData except the last 4 bytes 242 */ 243 packedAuthDataLength := 7 + 4 + 16 + 4 + randDataLength + dataLength + 4 244 245 macKey := pool.Get(len(a.iv) + len(a.Key)) 246 defer pool.Put(macKey) 247 copy(macKey, a.iv) 248 copy(macKey[len(a.iv):], a.Key) 249 250 poolBuf.WriteByte(byte(rand.Intn(256))) 251 poolBuf.Write(a.hmac(macKey, poolBuf.Bytes())[:6]) 252 poolBuf.Write(a.userID[:]) 253 err := a.authData.putEncryptedData(poolBuf, a.userKey, [2]int{packedAuthDataLength, randDataLength}, a.salt) 254 if err != nil { 255 poolBuf.Reset() 256 return 257 } 258 poolBuf.Write(a.hmac(macKey, poolBuf.Bytes()[7:])[:4]) 259 tools.AppendRandBytes(poolBuf, randDataLength) 260 poolBuf.Write(data) 261 poolBuf.Write(a.hmac(a.userKey, poolBuf.Bytes())[:4]) 262 } 263 264 func (a *authAES128) getRandDataLengthForPackAuthData(size int) int { 265 if size > 400 { 266 return rand.Intn(512) 267 } 268 return rand.Intn(1024) 269 } 270 271 func (a *authAES128) packRandData(poolBuf *bytes.Buffer, size int) { 272 if size < 128 { 273 poolBuf.WriteByte(byte(size + 1)) 274 tools.AppendRandBytes(poolBuf, size) 275 return 276 } 277 poolBuf.WriteByte(255) 278 binary.Write(poolBuf, binary.LittleEndian, uint16(size+3)) 279 tools.AppendRandBytes(poolBuf, size) 280 }