mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
chore: sync vless encryption code
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.25, macos-13) (push) Waiting to run
Test / test (1.25, macos-latest) (push) Waiting to run
Test / test (1.25, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.25, ubuntu-latest) (push) Waiting to run
Test / test (1.25, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.25, macos-13) (push) Waiting to run
Test / test (1.25, macos-latest) (push) Waiting to run
Test / test (1.25, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.25, ubuntu-latest) (push) Waiting to run
Test / test (1.25, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
This commit is contained in:
parent
ce760fcf19
commit
4e20ed65f2
@ -116,6 +116,11 @@ func TestInboundVless_Encryption(t *testing.T) {
|
|||||||
Encryption: "8min-xored-mlkem768client-" + clientBase64,
|
Encryption: "8min-xored-mlkem768client-" + clientBase64,
|
||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
|
t.Run("xtls-rprx-vision", func(t *testing.T) {
|
||||||
|
outboundOptions := outboundOptions
|
||||||
|
outboundOptions.Flow = "xtls-rprx-vision"
|
||||||
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -15,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/utls/mlkem"
|
"github.com/metacubex/utls/mlkem"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
"golang.org/x/sys/cpu"
|
"golang.org/x/sys/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,10 +69,10 @@ func (i *ClientInstance) Init(nfsEKeyBytes []byte, xor uint32, minutes time.Dura
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hash256 := sha256.Sum256(nfsEKeyBytes)
|
hash256 := sha3.Sum256(nfsEKeyBytes)
|
||||||
copy(i.hash11[:], hash256[:])
|
copy(i.hash11[:], hash256[:])
|
||||||
if xor > 0 {
|
if xor > 0 {
|
||||||
xorKey := sha256.Sum256(nfsEKeyBytes)
|
xorKey := sha3.Sum256(nfsEKeyBytes)
|
||||||
i.xorKey = xorKey[:]
|
i.xorKey = xorKey[:]
|
||||||
}
|
}
|
||||||
i.minutes = minutes
|
i.minutes = minutes
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -13,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
"golang.org/x/crypto/hkdf"
|
"golang.org/x/crypto/hkdf"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var MaxNonce = bytes.Repeat([]byte{255}, 12)
|
var MaxNonce = bytes.Repeat([]byte{255}, 12)
|
||||||
@ -75,7 +75,7 @@ func ReadAndDiscardPaddings(conn net.Conn) (h []byte, t byte, l int, err error)
|
|||||||
|
|
||||||
func NewAead(c byte, secret, salt, info []byte) (aead cipher.AEAD) {
|
func NewAead(c byte, secret, salt, info []byte) (aead cipher.AEAD) {
|
||||||
key := make([]byte, 32)
|
key := make([]byte, 32)
|
||||||
hkdf.New(sha256.New, secret, salt, info).Read(key)
|
hkdf.New(sha3.New256, secret, salt, info).Read(key)
|
||||||
if c&1 == 1 {
|
if c&1 == 1 {
|
||||||
block, _ := aes.NewCipher(key)
|
block, _ := aes.NewCipher(key)
|
||||||
aead, _ = cipher.NewGCM(block)
|
aead, _ = cipher.NewGCM(block)
|
||||||
|
|||||||
@ -12,4 +12,5 @@
|
|||||||
// https://github.com/XTLS/Xray-core/commit/2807ee432a1fbeb301815647189eacd650b12a8b
|
// https://github.com/XTLS/Xray-core/commit/2807ee432a1fbeb301815647189eacd650b12a8b
|
||||||
// https://github.com/XTLS/Xray-core/commit/bfe4820f2f086daf639b1957eb23dc13c843cad1
|
// https://github.com/XTLS/Xray-core/commit/bfe4820f2f086daf639b1957eb23dc13c843cad1
|
||||||
// https://github.com/XTLS/Xray-core/commit/d1fb48521271251a8c74bd64fcc2fc8700717a3b
|
// https://github.com/XTLS/Xray-core/commit/d1fb48521271251a8c74bd64fcc2fc8700717a3b
|
||||||
|
// https://github.com/XTLS/Xray-core/commit/49580705f6029648399304b816a2737f991582a8
|
||||||
package encryption
|
package encryption
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -13,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/utls/mlkem"
|
"github.com/metacubex/utls/mlkem"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerSession struct {
|
type ServerSession struct {
|
||||||
@ -54,10 +54,10 @@ func (i *ServerInstance) Init(nfsDKeySeed []byte, xor uint32, minutes time.Durat
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hash256 := sha256.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
hash256 := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
||||||
copy(i.hash11[:], hash256[:])
|
copy(i.hash11[:], hash256[:])
|
||||||
if xor > 0 {
|
if xor > 0 {
|
||||||
xorKey := sha256.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
xorKey := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
||||||
i.xorKey = xorKey[:]
|
i.xorKey = xorKey[:]
|
||||||
}
|
}
|
||||||
if minutes > 0 {
|
if minutes > 0 {
|
||||||
@ -279,9 +279,9 @@ func (c *ServerConn) Write(b []byte) (int, error) {
|
|||||||
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])
|
||||||
|
EncodeHeader(data[5+32:], 23, len(b)+16)
|
||||||
c.aead = NewAead(c.cipher, c.baseKey, data[5:5+32], c.peerRandom)
|
c.aead = NewAead(c.cipher, c.baseKey, data[5:5+32], c.peerRandom)
|
||||||
c.nonce = make([]byte, 12)
|
c.nonce = make([]byte, 12)
|
||||||
EncodeHeader(data[5+32:], 23, len(b)+16)
|
|
||||||
c.aead.Seal(data[:5+32+5], c.nonce, b, data[5+32:5+32+5])
|
c.aead.Seal(data[:5+32+5], c.nonce, b, data[5+32:5+32+5])
|
||||||
} else {
|
} else {
|
||||||
data = make([]byte, 5+len(b)+16)
|
data = make([]byte, 5+len(b)+16)
|
||||||
|
|||||||
@ -15,6 +15,14 @@ type XorConn struct {
|
|||||||
peerCtr cipher.Stream
|
peerCtr cipher.Stream
|
||||||
isHeader bool
|
isHeader bool
|
||||||
skipNext bool
|
skipNext bool
|
||||||
|
|
||||||
|
out_after0 bool
|
||||||
|
out_header []byte
|
||||||
|
out_skip int
|
||||||
|
|
||||||
|
in_after0 bool
|
||||||
|
in_header []byte
|
||||||
|
in_skip int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewXorConn(conn net.Conn, key []byte) *XorConn {
|
func NewXorConn(conn net.Conn, key []byte) *XorConn {
|
||||||
@ -26,6 +34,7 @@ func (c *XorConn) Write(b []byte) (int, error) { // whole one/two records
|
|||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
if !c.out_after0 {
|
||||||
var iv []byte
|
var iv []byte
|
||||||
if c.ctr == nil {
|
if c.ctr == nil {
|
||||||
block, _ := aes.NewCipher(c.key)
|
block, _ := aes.NewCipher(c.key)
|
||||||
@ -38,6 +47,9 @@ func (c *XorConn) Write(b []byte) (int, error) { // whole one/two records
|
|||||||
l = 5
|
l = 5
|
||||||
} else { // 1/0 + 23, or noises only
|
} else { // 1/0 + 23, or noises only
|
||||||
l += 10
|
l += 10
|
||||||
|
if t == 0 {
|
||||||
|
c.out_after0 = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.ctr.XORKeyStream(b[:l], b[:l]) // caller MUST discard b
|
c.ctr.XORKeyStream(b[:l], b[:l]) // caller MUST discard b
|
||||||
if iv != nil {
|
if iv != nil {
|
||||||
@ -51,11 +63,35 @@ func (c *XorConn) Write(b []byte) (int, error) { // whole one/two records
|
|||||||
}
|
}
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
for p := b; ; { // for XTLS
|
||||||
|
if len(p) <= c.out_skip {
|
||||||
|
c.out_skip -= len(p)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p = p[c.out_skip:]
|
||||||
|
c.out_skip = 0
|
||||||
|
need := 5 - len(c.out_header)
|
||||||
|
if len(p) < need {
|
||||||
|
c.out_header = append(c.out_header, p...)
|
||||||
|
c.ctr.XORKeyStream(p, p)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_, c.out_skip, _ = DecodeHeader(append(c.out_header, p[:need]...))
|
||||||
|
c.out_header = make([]byte, 0, 5) // DO NOT CHANGE
|
||||||
|
c.ctr.XORKeyStream(p[:need], p[:need])
|
||||||
|
p = p[need:]
|
||||||
|
}
|
||||||
|
if _, err := c.Conn.Write(b); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *XorConn) Read(b []byte) (int, error) { // 5-bytes, data, 5-bytes...
|
func (c *XorConn) Read(b []byte) (int, error) { // 5-bytes, data, 5-bytes...
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
if !c.in_after0 || !c.isHeader {
|
||||||
if c.peerCtr == nil {
|
if c.peerCtr == nil {
|
||||||
peerIv := make([]byte, 16)
|
peerIv := make([]byte, 16)
|
||||||
if _, err := io.ReadFull(c.Conn, peerIv); err != nil {
|
if _, err := io.ReadFull(c.Conn, peerIv); err != nil {
|
||||||
@ -78,9 +114,33 @@ func (c *XorConn) Read(b []byte) (int, error) { // 5-bytes, data, 5-bytes...
|
|||||||
c.skipNext = true
|
c.skipNext = true
|
||||||
} else {
|
} else {
|
||||||
c.isHeader = false
|
c.isHeader = false
|
||||||
|
if t == 0 {
|
||||||
|
c.in_after0 = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.isHeader = true
|
c.isHeader = true
|
||||||
}
|
}
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
n, err := c.Conn.Read(b)
|
||||||
|
for p := b[:n]; ; { // for XTLS
|
||||||
|
if len(p) <= c.in_skip {
|
||||||
|
c.in_skip -= len(p)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p = p[c.in_skip:]
|
||||||
|
c.in_skip = 0
|
||||||
|
need := 5 - len(c.in_header)
|
||||||
|
if len(p) < need {
|
||||||
|
c.peerCtr.XORKeyStream(p, p)
|
||||||
|
c.in_header = append(c.in_header, p...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c.peerCtr.XORKeyStream(p[:need], p[:need])
|
||||||
|
_, c.in_skip, _ = DecodeHeader(append(c.in_header, p[:need]...))
|
||||||
|
c.in_header = make([]byte, 0, 5) // DO NOT CHANGE
|
||||||
|
p = p[need:]
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user