Skip to content

Commit d319820

Browse files
committed
refactor: use stdlib ech functions for grease ech
1 parent 80dbaa4 commit d319820

2 files changed

Lines changed: 25 additions & 49 deletions

File tree

u_ech.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"math/big"
99
"sync"
1010

11-
"github.com/cloudflare/circl/hpke"
1211
"github.com/refraction-networking/utls/dicttls"
12+
"github.com/refraction-networking/utls/internal/hpke"
1313
"golang.org/x/crypto/cryptobyte"
1414
)
1515

@@ -96,8 +96,7 @@ func (g *GREASEEncryptedClientHelloExtension) init() error {
9696
// but MAY be held constant for successive connections to the same server
9797
// in the same session.
9898
if len(g.CandidateCipherSuites) == 0 {
99-
_, kdf, aead := defaultHPKESuite.Params()
100-
g.cipherSuite = HPKESymmetricCipherSuite{uint16(kdf), uint16(aead)}
99+
g.cipherSuite = HPKESymmetricCipherSuite{uint16(defaultHpkeKdf), uint16(defaultHpkeAead)}
101100
} else {
102101
// randomly pick one from the list
103102
rndIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(g.CandidateCipherSuites))))
@@ -113,21 +112,18 @@ func (g *GREASEEncryptedClientHelloExtension) init() error {
113112
}
114113

115114
if len(g.EncapsulatedKey) == 0 {
116-
// use default random key from cloudflare/go
117-
kem := hpke.KEM_X25519_HKDF_SHA256
115+
kem := uint16(defaultHpkeKem)
118116

119-
pk, err := kem.Scheme().UnmarshalBinaryPublicKey(dummyX25519PublicKey)
117+
echPK, err := hpke.ParseHPKEPublicKey(uint16(kem), dummyX25519PublicKey)
120118
if err != nil {
121119
initErr = fmt.Errorf("tls: grease ech: failed to parse dummy public key: %w", err)
122120
return
123121
}
124-
sender, err := defaultHPKESuite.NewSender(pk, nil)
125-
if err != nil {
126-
initErr = fmt.Errorf("tls: grease ech: failed to create sender: %w", err)
127-
return
122+
suite := echCipher{
123+
KDFID: defaultHpkeKdf,
124+
AEADID: defaultHpkeAead,
128125
}
129-
130-
g.EncapsulatedKey, _, err = sender.Setup(rand.Reader)
126+
g.EncapsulatedKey, _, err = hpke.SetupSender(kem, suite.KDFID, suite.AEADID, echPK, []byte{})
131127
if err != nil {
132128
initErr = fmt.Errorf("tls: grease ech: failed to setup encapsulated key: %w", err)
133129
return
@@ -158,8 +154,7 @@ func (g *GREASEEncryptedClientHelloExtension) randomizePayload(encodedHelloInner
158154
return errors.New("tls: grease ech: regenerating payload is forbidden")
159155
}
160156

161-
aead := hpke.AEAD(g.cipherSuite.AeadId)
162-
g.payload = make([]byte, int(aead.CipherLen(uint(encodedHelloInnerLen))))
157+
g.payload = make([]byte, cipherLen(g.cipherSuite.AeadId, int(encodedHelloInnerLen)))
163158
_, err := rand.Read(g.payload)
164159
if err != nil {
165160
return fmt.Errorf("tls: generating grease ech payload: %w", err)
@@ -269,8 +264,7 @@ func (g *GREASEEncryptedClientHelloExtension) Write(b []byte) (int, error) {
269264
if !extData.ReadUint16LengthPrefixed(&ignored) {
270265
return fullLen, errors.New("bad payload")
271266
}
272-
aead := hpke.AEAD(g.cipherSuite.AeadId)
273-
g.CandidatePayloadLens = []uint16{uint16(len(ignored) - int(aead.CipherLen(0)))}
267+
g.CandidatePayloadLens = []uint16{uint16(len(ignored) - cipherLen(g.cipherSuite.AeadId, 0))}
274268

275269
return fullLen, nil
276270
}

u_hpke.go

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package tls
22

33
import (
4-
"errors"
5-
"fmt"
6-
7-
"github.com/cloudflare/circl/hpke"
84
"github.com/cloudflare/circl/kem"
5+
"github.com/refraction-networking/utls/internal/hpke"
96
)
107

118
type HPKERawPublicKey = []byte
@@ -26,37 +23,22 @@ type HPKEKeyConfig struct {
2623
CipherSuites []HPKESymmetricCipherSuite
2724
}
2825

29-
var defaultHPKESuite hpke.Suite
30-
31-
func init() {
32-
var err error
33-
defaultHPKESuite, err = hpkeAssembleSuite(
34-
uint16(hpke.KEM_X25519_HKDF_SHA256),
35-
uint16(hpke.KDF_HKDF_SHA256),
36-
uint16(hpke.AEAD_AES128GCM),
37-
)
38-
if err != nil {
39-
panic(fmt.Sprintf("hpke: mandatory-to-implement cipher suite not supported: %s", err))
40-
}
41-
}
42-
43-
func hpkeAssembleSuite(kemId, kdfId, aeadId uint16) (hpke.Suite, error) {
44-
kem := hpke.KEM(kemId)
45-
if !kem.IsValid() {
46-
return hpke.Suite{}, errors.New("KEM is not supported")
47-
}
48-
kdf := hpke.KDF(kdfId)
49-
if !kdf.IsValid() {
50-
return hpke.Suite{}, errors.New("KDF is not supported")
51-
}
52-
aead := hpke.AEAD(aeadId)
53-
if !aead.IsValid() {
54-
return hpke.Suite{}, errors.New("AEAD is not supported")
55-
}
56-
return hpke.NewSuite(kem, kdf, aead), nil
57-
}
26+
const defaultHpkeKdf = hpke.KDF_HKDF_SHA256
27+
const defaultHpkeKem = hpke.DHKEM_X25519_HKDF_SHA256
28+
const defaultHpkeAead = hpke.AEAD_AES_128_GCM
5829

5930
var dummyX25519PublicKey = []byte{
6031
143, 38, 37, 36, 12, 6, 229, 30, 140, 27, 167, 73, 26, 100, 203, 107, 216,
6132
81, 163, 222, 52, 211, 54, 210, 46, 37, 78, 216, 157, 97, 241, 244,
6233
}
34+
35+
// cipherLen returns the length of a ciphertext corresponding to a message of
36+
// length mLen.
37+
func cipherLen(a uint16, mLen int) int {
38+
switch a {
39+
case hpke.AEAD_AES_128_GCM, hpke.AEAD_AES_256_GCM, hpke.AEAD_ChaCha20Poly1305:
40+
return mLen + 16
41+
default:
42+
panic("hpke: invalid AEAD identifier")
43+
}
44+
}

0 commit comments

Comments
 (0)