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  }