Skip to content

Commit 854c6a1

Browse files
committed
chore: sync vless encryption code
1 parent b4c3bbf commit 854c6a1

File tree

4 files changed

+59
-51
lines changed

4 files changed

+59
-51
lines changed

transport/vless/encryption/client.go

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"crypto/cipher"
66
"crypto/rand"
7-
"crypto/sha256"
87
"errors"
98
"io"
109
"net"
@@ -13,7 +12,6 @@ import (
1312
"time"
1413

1514
"github.com/metacubex/utls/mlkem"
16-
"golang.org/x/crypto/hkdf"
1715
"golang.org/x/sys/cpu"
1816
)
1917

@@ -101,7 +99,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
10199
clientHello[0] = ClientCipher
102100
copy(clientHello[1:], pfsEKeyBytes)
103101
copy(clientHello[1185:], encapsulatedNfsKey)
104-
encodeHeader(clientHello[2273:], int(paddingLen))
102+
EncodeHeader(clientHello[2273:], int(paddingLen))
105103
rand.Read(clientHello[2278:])
106104

107105
if _, err := c.Conn.Write(clientHello); err != nil {
@@ -122,11 +120,9 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
122120
}
123121
c.baseKey = append(pfsKey, nfsKey...)
124122

125-
authKey := make([]byte, 32)
126-
hkdf.New(sha256.New, c.baseKey, encapsulatedPfsKey, encapsulatedNfsKey).Read(authKey)
127123
nonce := [12]byte{ClientCipher}
128-
VLESS, _ := newAead(ClientCipher, authKey).Open(nil, nonce[:], c.ticket, pfsEKeyBytes)
129-
if !bytes.Equal(VLESS, []byte("VLESS")) { // TODO: more message
124+
VLESS, _ := NewAead(ClientCipher, c.baseKey, encapsulatedPfsKey, encapsulatedNfsKey).Open(nil, nonce[:], c.ticket, pfsEKeyBytes)
125+
if !bytes.Equal(VLESS, []byte("VLESS")) { // TODO: more messages
130126
return nil, errors.New("invalid server")
131127
}
132128

@@ -145,32 +141,32 @@ func (c *ClientConn) Write(b []byte) (int, error) {
145141
if len(b) == 0 {
146142
return 0, nil
147143
}
144+
var data []byte
148145
for n := 0; n < len(b); {
149146
b := b[n:]
150147
if len(b) > 8192 {
151148
b = b[:8192] // for avoiding another copy() in server's Read()
152149
}
153150
n += len(b)
154-
var data []byte
155151
if c.aead == nil {
156152
c.random = make([]byte, 32)
157153
rand.Read(c.random)
158-
key := make([]byte, 32)
159-
hkdf.New(sha256.New, c.baseKey, c.random, c.ticket).Read(key)
160-
c.aead = newAead(ClientCipher, key)
154+
c.aead = NewAead(ClientCipher, c.baseKey, c.random, c.ticket)
161155
c.nonce = make([]byte, 12)
162-
163156
data = make([]byte, 21+32+5+len(b)+16)
164157
copy(data, c.ticket)
165158
copy(data[21:], c.random)
166-
encodeHeader(data[53:], len(b)+16)
159+
EncodeHeader(data[53:], len(b)+16)
167160
c.aead.Seal(data[:58], c.nonce, b, data[53:58])
168161
} else {
169162
data = make([]byte, 5+len(b)+16)
170-
encodeHeader(data, len(b)+16)
163+
EncodeHeader(data, len(b)+16)
171164
c.aead.Seal(data[:5], c.nonce, b, data[:5])
165+
if bytes.Equal(c.nonce, MaxNonce) {
166+
c.aead = NewAead(ClientCipher, c.baseKey, data[5:], data[:5])
167+
}
172168
}
173-
increaseNonce(c.nonce)
169+
IncreaseNonce(c.nonce)
174170
if _, err := c.Conn.Write(data); err != nil {
175171
return 0, err
176172
}
@@ -189,7 +185,7 @@ func (c *ClientConn) Read(b []byte) (int, error) {
189185
if _, err := io.ReadFull(c.Conn, peerHeader); err != nil {
190186
return 0, err
191187
}
192-
peerPaddingLen, _ := decodeHeader(peerHeader)
188+
peerPaddingLen, _ := DecodeHeader(peerHeader)
193189
if peerPaddingLen == 0 {
194190
break
195191
}
@@ -210,9 +206,7 @@ func (c *ClientConn) Read(b []byte) (int, error) {
210206
if c.random == nil {
211207
return 0, errors.New("empty c.random")
212208
}
213-
peerKey := make([]byte, 32)
214-
hkdf.New(sha256.New, c.baseKey, peerRandom, c.random).Read(peerKey)
215-
c.peerAead = newAead(ClientCipher, peerKey)
209+
c.peerAead = NewAead(ClientCipher, c.baseKey, peerRandom, c.random)
216210
c.peerNonce = make([]byte, 12)
217211
}
218212
if len(c.peerCache) != 0 {
@@ -223,7 +217,7 @@ func (c *ClientConn) Read(b []byte) (int, error) {
223217
if _, err := io.ReadFull(c.Conn, peerHeader); err != nil {
224218
return 0, err
225219
}
226-
peerLength, err := decodeHeader(peerHeader) // 17~17000
220+
peerLength, err := DecodeHeader(peerHeader) // 17~17000
227221
if err != nil {
228222
if c.instance != nil {
229223
c.instance.Lock()
@@ -242,8 +236,15 @@ func (c *ClientConn) Read(b []byte) (int, error) {
242236
if len(dst) <= len(b) {
243237
dst = b[:len(dst)] // avoids another copy()
244238
}
239+
var peerAead cipher.AEAD
240+
if bytes.Equal(c.peerNonce, MaxNonce) {
241+
peerAead = NewAead(ClientCipher, c.baseKey, peerData, peerHeader)
242+
}
245243
_, err = c.peerAead.Open(dst[:0], c.peerNonce, peerData, peerHeader)
246-
increaseNonce(c.peerNonce)
244+
if peerAead != nil {
245+
c.peerAead = peerAead
246+
}
247+
IncreaseNonce(c.peerNonce)
247248
if err != nil {
248249
return 0, err
249250
}

transport/vless/encryption/common.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,58 @@
11
package encryption
22

33
import (
4+
"bytes"
45
"crypto/aes"
56
"crypto/cipher"
67
"crypto/rand"
8+
"crypto/sha256"
79
"errors"
810
"math/big"
911
"strconv"
1012

1113
"golang.org/x/crypto/chacha20poly1305"
14+
"golang.org/x/crypto/hkdf"
1215
)
1316

14-
func encodeHeader(b []byte, l int) {
17+
var MaxNonce = bytes.Repeat([]byte{255}, 12)
18+
19+
func EncodeHeader(b []byte, l int) {
1520
b[0] = 23
1621
b[1] = 3
1722
b[2] = 3
1823
b[3] = byte(l >> 8)
1924
b[4] = byte(l)
2025
}
2126

22-
func decodeHeader(b []byte) (int, error) {
27+
func DecodeHeader(b []byte) (int, error) {
2328
if b[0] == 23 && b[1] == 3 && b[2] == 3 {
2429
l := int(b[3])<<8 | int(b[4])
25-
if l < 17 || l > 17000 { // TODO
30+
if l < 17 || l > 17000 { // TODO: TLSv1.3 max length
2631
return 0, errors.New("invalid length in record's header: " + strconv.Itoa(l))
2732
}
2833
return l, nil
2934
}
3035
return 0, errors.New("invalid record's header")
3136
}
3237

33-
func newAead(c byte, k []byte) (aead cipher.AEAD) {
38+
func NewAead(c byte, secret, salt, info []byte) (aead cipher.AEAD) {
39+
key := make([]byte, 32)
40+
hkdf.New(sha256.New, secret, salt, info).Read(key)
3441
if c&1 == 1 {
35-
block, _ := aes.NewCipher(k)
42+
block, _ := aes.NewCipher(key)
3643
aead, _ = cipher.NewGCM(block)
3744
} else {
38-
aead, _ = chacha20poly1305.New(k)
45+
aead, _ = chacha20poly1305.New(key)
3946
}
4047
return
4148
}
4249

43-
func increaseNonce(nonce []byte) {
50+
func IncreaseNonce(nonce []byte) {
4451
for i := 0; i < 12; i++ {
4552
nonce[11-i]++
4653
if nonce[11-i] != 0 {
4754
break
4855
}
49-
if i == 11 {
50-
// TODO
51-
}
5256
}
5357
}
5458

transport/vless/encryption/doc.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
// https://github.com/XTLS/Xray-core/commit/3e19bf9233bdd9bafc073a71c65b737cc1ffba5e
44
// https://github.com/XTLS/Xray-core/commit/7ffb555fc8ec51bd1e3e60f26f1d6957984dba80
55
// https://github.com/XTLS/Xray-core/commit/ec1cc35188c1a5f38a2ff75e88b5d043ffdc59da
6+
// https://github.com/XTLS/Xray-core/commit/5c611420487a92f931faefc01d4bf03869f477f6
67
package encryption

transport/vless/encryption/server.go

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ import (
44
"bytes"
55
"crypto/cipher"
66
"crypto/rand"
7-
"crypto/sha256"
87
"errors"
98
"io"
109
"net"
1110
"sync"
1211
"time"
1312

1413
"github.com/metacubex/utls/mlkem"
15-
"golang.org/x/crypto/hkdf"
1614
)
1715

1816
type ServerSession struct {
@@ -113,7 +111,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
113111
if _, err := io.ReadFull(c.Conn, peerHeader); err != nil {
114112
return nil, err
115113
}
116-
if l, _ := decodeHeader(peerHeader); l != 0 {
114+
if l, _ := DecodeHeader(peerHeader); l != 0 {
117115
noise := make([]byte, randBetween(100, 1000))
118116
rand.Read(noise)
119117
c.Conn.Write(noise) // make client do new handshake
@@ -141,17 +139,15 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
141139
pfsKey, encapsulatedPfsKey := pfsEKey.Encapsulate()
142140
c.baseKey = append(pfsKey, nfsKey...)
143141

144-
authKey := make([]byte, 32)
145-
hkdf.New(sha256.New, c.baseKey, encapsulatedPfsKey, encapsulatedNfsKey).Read(authKey)
146142
nonce := [12]byte{c.cipher}
147-
c.ticket = newAead(c.cipher, authKey).Seal(nil, nonce[:], []byte("VLESS"), pfsEKeyBytes)
143+
c.ticket = NewAead(c.cipher, c.baseKey, encapsulatedPfsKey, encapsulatedNfsKey).Seal(nil, nonce[:], []byte("VLESS"), pfsEKeyBytes)
148144

149145
paddingLen := randBetween(100, 1000)
150146

151147
serverHello := make([]byte, 1088+21+5+paddingLen)
152148
copy(serverHello, encapsulatedPfsKey)
153149
copy(serverHello[1088:], c.ticket)
154-
encodeHeader(serverHello[1109:], int(paddingLen))
150+
EncodeHeader(serverHello[1109:], int(paddingLen))
155151
rand.Read(serverHello[1114:])
156152

157153
if _, err := c.Conn.Write(serverHello); err != nil {
@@ -183,7 +179,7 @@ func (c *ServerConn) Read(b []byte) (int, error) {
183179
if _, err := io.ReadFull(c.Conn, peerHeader); err != nil {
184180
return 0, err
185181
}
186-
peerPaddingLen, _ := decodeHeader(peerHeader)
182+
peerPaddingLen, _ := DecodeHeader(peerHeader)
187183
if peerPaddingLen == 0 {
188184
break
189185
}
@@ -204,9 +200,7 @@ func (c *ServerConn) Read(b []byte) (int, error) {
204200
return 0, err
205201
}
206202
}
207-
peerKey := make([]byte, 32)
208-
hkdf.New(sha256.New, c.baseKey, c.peerRandom, c.ticket).Read(peerKey)
209-
c.peerAead = newAead(c.cipher, peerKey)
203+
c.peerAead = NewAead(c.cipher, c.baseKey, c.peerRandom, c.ticket)
210204
c.peerNonce = make([]byte, 12)
211205
}
212206
if len(c.peerCache) != 0 {
@@ -217,7 +211,7 @@ func (c *ServerConn) Read(b []byte) (int, error) {
217211
if _, err := io.ReadFull(c.Conn, peerHeader); err != nil {
218212
return 0, err
219213
}
220-
peerLength, err := decodeHeader(peerHeader) // 17~17000
214+
peerLength, err := DecodeHeader(peerHeader) // 17~17000
221215
if err != nil {
222216
return 0, err
223217
}
@@ -229,8 +223,15 @@ func (c *ServerConn) Read(b []byte) (int, error) {
229223
if len(dst) <= len(b) {
230224
dst = b[:len(dst)] // avoids another copy()
231225
}
226+
var peerAead cipher.AEAD
227+
if bytes.Equal(c.peerNonce, MaxNonce) {
228+
peerAead = NewAead(ClientCipher, c.baseKey, peerData, peerHeader)
229+
}
232230
_, err = c.peerAead.Open(dst[:0], c.peerNonce, peerData, peerHeader)
233-
increaseNonce(c.peerNonce)
231+
if peerAead != nil {
232+
c.peerAead = peerAead
233+
}
234+
IncreaseNonce(c.peerNonce)
234235
if err != nil {
235236
return 0, errors.New("error")
236237
}
@@ -245,31 +246,32 @@ func (c *ServerConn) Write(b []byte) (int, error) {
245246
if len(b) == 0 {
246247
return 0, nil
247248
}
249+
var data []byte
248250
for n := 0; n < len(b); {
249251
b := b[n:]
250252
if len(b) > 8192 {
251253
b = b[:8192] // for avoiding another copy() in client's Read()
252254
}
253255
n += len(b)
254-
var data []byte
255256
if c.aead == nil {
256257
if c.peerRandom == nil {
257258
return 0, errors.New("empty c.peerRandom")
258259
}
259260
data = make([]byte, 32+5+len(b)+16)
260261
rand.Read(data[:32])
261-
key := make([]byte, 32)
262-
hkdf.New(sha256.New, c.baseKey, data[:32], c.peerRandom).Read(key)
263-
c.aead = newAead(c.cipher, key)
262+
c.aead = NewAead(c.cipher, c.baseKey, data[:32], c.peerRandom)
264263
c.nonce = make([]byte, 12)
265-
encodeHeader(data[32:], len(b)+16)
264+
EncodeHeader(data[32:], len(b)+16)
266265
c.aead.Seal(data[:37], c.nonce, b, data[32:37])
267266
} else {
268267
data = make([]byte, 5+len(b)+16)
269-
encodeHeader(data, len(b)+16)
268+
EncodeHeader(data, len(b)+16)
270269
c.aead.Seal(data[:5], c.nonce, b, data[:5])
270+
if bytes.Equal(c.nonce, MaxNonce) {
271+
c.aead = NewAead(ClientCipher, c.baseKey, data[5:], data[:5])
272+
}
271273
}
272-
increaseNonce(c.nonce)
274+
IncreaseNonce(c.nonce)
273275
if _, err := c.Conn.Write(data); err != nil {
274276
return 0, err
275277
}

0 commit comments

Comments
 (0)