mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
chore: sync vless encryption code
Some checks failed
Test / test (1.20, macos-13) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-13) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-13) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-13) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-13) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-13) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled
Some checks failed
Test / test (1.20, macos-13) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-13) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-13) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-13) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-13) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-13) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled
This commit is contained in:
parent
cdf5e0c73e
commit
2a8831b0d0
@ -70,13 +70,13 @@ func (i *ClientInstance) Init(nfsEKeyBytes, xorPKeyBytes []byte, xorMode, minute
|
|||||||
if i.nfsEKey, err = mlkem.NewEncapsulationKey768(nfsEKeyBytes); err != nil {
|
if i.nfsEKey, err = mlkem.NewEncapsulationKey768(nfsEKeyBytes); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hash32 := sha3.Sum256(nfsEKeyBytes)
|
|
||||||
copy(i.hash11[:], hash32[:])
|
|
||||||
if xorMode > 0 {
|
if xorMode > 0 {
|
||||||
i.xorMode = xorMode
|
i.xorMode = xorMode
|
||||||
if i.xorPKey, err = ecdh.X25519().NewPublicKey(xorPKeyBytes); err != nil {
|
if i.xorPKey, err = ecdh.X25519().NewPublicKey(xorPKeyBytes); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
hash32 := sha3.Sum256(nfsEKeyBytes)
|
||||||
|
copy(i.hash11[:], hash32[:])
|
||||||
}
|
}
|
||||||
i.minutes = time.Duration(minutes) * time.Minute
|
i.minutes = time.Duration(minutes) * time.Minute
|
||||||
return
|
return
|
||||||
@ -126,7 +126,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*ClientConn, error) {
|
|||||||
}
|
}
|
||||||
// client can send more NFS AEAD paddings / messages if needed
|
// client can send more NFS AEAD paddings / messages if needed
|
||||||
|
|
||||||
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before server hello
|
_, t, l, err := ReadAndDiscardPaddings(c.Conn, nil, nil) // allow paddings before server hello
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -209,9 +209,9 @@ func (c *ClientConn) Read(b []byte) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
if c.peerAEAD == nil {
|
if c.peerAEAD == nil {
|
||||||
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before random hello
|
_, t, l, err := ReadAndDiscardPaddings(c.Conn, nil, nil) // allow paddings before random hello
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if c.instance != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // 0-RTT's 0-RTT
|
if c.instance != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // 0-RTT
|
||||||
c.instance.Lock()
|
c.instance.Lock()
|
||||||
if bytes.Equal(c.ticket, c.instance.ticket) {
|
if bytes.Equal(c.ticket, c.instance.ticket) {
|
||||||
c.instance.expire = time.Now() // expired
|
c.instance.expire = time.Now() // expired
|
||||||
|
|||||||
@ -62,14 +62,21 @@ func ReadAndDecodeHeader(conn net.Conn) (h []byte, t byte, l int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadAndDiscardPaddings(conn net.Conn) (h []byte, t byte, l int, err error) {
|
func ReadAndDiscardPaddings(conn net.Conn, aead cipher.AEAD, nonce []byte) (h []byte, t byte, l int, err error) {
|
||||||
for {
|
for {
|
||||||
if h, t, l, err = ReadAndDecodeHeader(conn); err != nil || t != 23 {
|
if h, t, l, err = ReadAndDecodeHeader(conn); err != nil || t != 23 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, err = io.ReadFull(conn, make([]byte, l)); err != nil {
|
padding := make([]byte, l)
|
||||||
|
if _, err = io.ReadFull(conn, padding); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if aead != nil {
|
||||||
|
if _, err := aead.Open(nil, nonce, padding, h); err != nil {
|
||||||
|
return h, t, l, err
|
||||||
|
}
|
||||||
|
IncreaseNonce(nonce)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,4 +16,5 @@
|
|||||||
// https://github.com/XTLS/Xray-core/commit/84835bec7d0d8555d0dd30953ed26a272de814c4
|
// https://github.com/XTLS/Xray-core/commit/84835bec7d0d8555d0dd30953ed26a272de814c4
|
||||||
// https://github.com/XTLS/Xray-core/commit/373558ed7abdbac3de41745cf30ec04c9adde604
|
// https://github.com/XTLS/Xray-core/commit/373558ed7abdbac3de41745cf30ec04c9adde604
|
||||||
// https://github.com/XTLS/Xray-core/commit/38cc306c955c362f044e074049a5e67b6b9fb389
|
// https://github.com/XTLS/Xray-core/commit/38cc306c955c362f044e074049a5e67b6b9fb389
|
||||||
|
// https://github.com/XTLS/Xray-core/commit/b33555cc0a52d0af3c23d2af8fca42f8a685d9af
|
||||||
package encryption
|
package encryption
|
||||||
|
|||||||
@ -55,13 +55,13 @@ func (i *ServerInstance) Init(nfsDKeySeed, xorSKeyBytes []byte, xorMode, minutes
|
|||||||
if i.nfsDKey, err = mlkem.NewDecapsulationKey768(nfsDKeySeed); err != nil {
|
if i.nfsDKey, err = mlkem.NewDecapsulationKey768(nfsDKeySeed); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hash32 := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
|
||||||
copy(i.hash11[:], hash32[:])
|
|
||||||
if xorMode > 0 {
|
if xorMode > 0 {
|
||||||
i.xorMode = xorMode
|
i.xorMode = xorMode
|
||||||
if i.xorSKey, err = ecdh.X25519().NewPrivateKey(xorSKeyBytes); err != nil {
|
if i.xorSKey, err = ecdh.X25519().NewPrivateKey(xorSKeyBytes); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
hash32 := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
||||||
|
copy(i.hash11[:], hash32[:])
|
||||||
}
|
}
|
||||||
if minutes > 0 {
|
if minutes > 0 {
|
||||||
i.minutes = time.Duration(minutes) * time.Minute
|
i.minutes = time.Duration(minutes) * time.Minute
|
||||||
@ -106,7 +106,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*ServerConn, error) {
|
|||||||
}
|
}
|
||||||
c := &ServerConn{Conn: conn}
|
c := &ServerConn{Conn: conn}
|
||||||
|
|
||||||
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before client/ticket hello
|
_, t, l, err := ReadAndDiscardPaddings(c.Conn, nil, nil) // allow paddings before client/ticket hello
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -170,11 +170,14 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*ServerConn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
nfsAEAD := NewAEAD(c.cipher, nfsKey, pfsEKeyBytes, encapsulatedNfsKey)
|
||||||
|
nfsNonce := append([]byte{}, peerClientHello[:11+1]...)
|
||||||
pfsKey, encapsulatedPfsKey := pfsEKey.Encapsulate()
|
pfsKey, encapsulatedPfsKey := pfsEKey.Encapsulate()
|
||||||
c.baseKey = append(pfsKey, nfsKey...)
|
c.baseKey = append(pfsKey, nfsKey...)
|
||||||
pfsAEAD := NewAEAD(c.cipher, c.baseKey, encapsulatedPfsKey, encapsulatedNfsKey)
|
pfsAEAD := NewAEAD(c.cipher, c.baseKey, encapsulatedPfsKey, encapsulatedNfsKey)
|
||||||
c.ticket = append(i.hash11[:], pfsAEAD.Seal(nil, peerClientHello[:11+1], []byte("VLESS"), pfsEKeyBytes)...)
|
pfsNonce := append([]byte{}, peerClientHello[:11+1]...)
|
||||||
IncreaseNonce(peerClientHello[:11+1])
|
c.ticket = append(i.hash11[:], pfsAEAD.Seal(nil, pfsNonce, []byte("VLESS"), pfsEKeyBytes)...)
|
||||||
|
IncreaseNonce(pfsNonce)
|
||||||
|
|
||||||
serverHello := make([]byte, 5+1088+21+randBetween(100, 1000))
|
serverHello := make([]byte, 5+1088+21+randBetween(100, 1000))
|
||||||
EncodeHeader(serverHello, 1, 1088+21)
|
EncodeHeader(serverHello, 1, 1088+21)
|
||||||
@ -183,20 +186,41 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*ServerConn, error) {
|
|||||||
padding := serverHello[5+1088+21:]
|
padding := serverHello[5+1088+21:]
|
||||||
rand.Read(padding) // important
|
rand.Read(padding) // important
|
||||||
EncodeHeader(padding, 23, len(padding)-5)
|
EncodeHeader(padding, 23, len(padding)-5)
|
||||||
pfsAEAD.Seal(padding[:5], peerClientHello[:11+1], padding[5:len(padding)-16], padding[:5])
|
pfsAEAD.Seal(padding[:5], pfsNonce, padding[5:len(padding)-16], padding[:5])
|
||||||
|
|
||||||
if _, err := c.Conn.Write(serverHello); err != nil {
|
if _, err := c.Conn.Write(serverHello); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// server can send more PFS AEAD paddings / messages if needed
|
// server can send more PFS AEAD paddings / messages if needed
|
||||||
|
|
||||||
|
_, t, l, err = ReadAndDiscardPaddings(c.Conn, nfsAEAD, nfsNonce) // allow paddings before ticket hello
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if t != 0 {
|
||||||
|
return nil, fmt.Errorf("unexpected type %v, expect ticket hello", t)
|
||||||
|
}
|
||||||
|
peerTicketHello := make([]byte, 32+32)
|
||||||
|
if l != len(peerTicketHello) {
|
||||||
|
return nil, fmt.Errorf("unexpected length %v for ticket hello", l)
|
||||||
|
}
|
||||||
|
if _, err := io.ReadFull(c.Conn, peerTicketHello); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !bytes.Equal(peerTicketHello[:32], c.ticket) {
|
||||||
|
return nil, errors.New("naughty boy")
|
||||||
|
}
|
||||||
|
c.peerRandom = peerTicketHello[32:]
|
||||||
|
|
||||||
if i.minutes > 0 {
|
if i.minutes > 0 {
|
||||||
i.Lock()
|
i.Lock()
|
||||||
i.sessions[[32]byte(c.ticket)] = &ServerSession{
|
s := &ServerSession{
|
||||||
expire: time.Now().Add(i.minutes),
|
expire: time.Now().Add(i.minutes),
|
||||||
cipher: c.cipher,
|
cipher: c.cipher,
|
||||||
baseKey: c.baseKey,
|
baseKey: c.baseKey,
|
||||||
}
|
}
|
||||||
|
s.randoms.Store([32]byte(c.peerRandom), true)
|
||||||
|
i.sessions[[32]byte(c.ticket)] = s
|
||||||
i.Unlock()
|
i.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,26 +232,6 @@ func (c *ServerConn) Read(b []byte) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
if c.peerAEAD == nil {
|
if c.peerAEAD == nil {
|
||||||
if c.peerRandom == nil { // 1-RTT's 0-RTT
|
|
||||||
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before ticket hello
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if t != 0 {
|
|
||||||
return 0, fmt.Errorf("unexpected type %v, expect ticket hello", t)
|
|
||||||
}
|
|
||||||
peerTicketHello := make([]byte, 32+32)
|
|
||||||
if l != len(peerTicketHello) {
|
|
||||||
return 0, fmt.Errorf("unexpected length %v for ticket hello", l)
|
|
||||||
}
|
|
||||||
if _, err := io.ReadFull(c.Conn, peerTicketHello); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if !bytes.Equal(peerTicketHello[:32], c.ticket) {
|
|
||||||
return 0, errors.New("naughty boy")
|
|
||||||
}
|
|
||||||
c.peerRandom = peerTicketHello[32:]
|
|
||||||
}
|
|
||||||
c.peerAEAD = NewAEAD(c.cipher, c.baseKey, c.peerRandom, c.ticket)
|
c.peerAEAD = NewAEAD(c.cipher, c.baseKey, c.peerRandom, c.ticket)
|
||||||
c.peerNonce = make([]byte, 12)
|
c.peerNonce = make([]byte, 12)
|
||||||
}
|
}
|
||||||
@ -280,9 +284,6 @@ func (c *ServerConn) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
n += len(b)
|
n += len(b)
|
||||||
if c.aead == nil {
|
if c.aead == nil {
|
||||||
if c.peerRandom == nil {
|
|
||||||
return 0, errors.New("empty c.peerRandom")
|
|
||||||
}
|
|
||||||
data = make([]byte, 5+32+5+len(b)+16)
|
data = make([]byte, 5+32+5+len(b)+16)
|
||||||
EncodeHeader(data, 0, 32)
|
EncodeHeader(data, 0, 32)
|
||||||
rand.Read(data[5 : 5+32])
|
rand.Read(data[5 : 5+32])
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user