Skip to content

Commit 24318fd

Browse files
committed
crypto/tls: add cipher suites TLS_ECDHE_PSK
1 parent 160414c commit 24318fd

File tree

7 files changed

+318
-25
lines changed

7 files changed

+318
-25
lines changed

src/crypto/tls/cipher_suites.go

+45-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"crypto/rc4"
1515
"crypto/sha1"
1616
"crypto/sha256"
17+
"crypto/sha512"
1718
"fmt"
1819
"hash"
1920
"internal/cpu"
@@ -69,8 +70,12 @@ func CipherSuites() []*CipherSuite {
6970
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
7071
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
7172
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
73+
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", supportedOnlyTLS12, false},
74+
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", supportedOnlyTLS12, false},
75+
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", supportedOnlyTLS12, false},
7276
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
7377
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
78+
{TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
7479
}
7580
}
7681

@@ -91,6 +96,7 @@ func InsecureCipherSuites() []*CipherSuite {
9196
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
9297
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
9398
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
99+
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
94100
}
95101
}
96102

@@ -128,6 +134,9 @@ const (
128134
// suiteSHA384 indicates that the cipher suite uses SHA384 as the
129135
// handshake hash.
130136
suiteSHA384
137+
// suiteNoCerts indicates that the cipher suite doesn't use certificate exchange
138+
// (anonymous ciphersuites or pre-shared-secret)
139+
suiteNoCerts
131140
)
132141

133142
// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange
@@ -169,6 +178,12 @@ var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order
169178
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
170179
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
171180
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil},
181+
182+
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suiteTLS12 | suiteNoCerts, cipherAES, macSHA1, nil},
183+
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdhePSKKA, suiteECDHE | suiteTLS12 | suiteNoCerts, cipherAES, macSHA256, nil},
184+
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suiteTLS12 | suiteNoCerts, cipherAES, macSHA1, nil},
185+
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdhePSKKA, suiteECDHE | suiteTLS12 | suiteSHA384 | suiteNoCerts, cipherAES, macSHA384, nil},
186+
{TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdhePSKKA, suiteECDHE | suiteTLS12 | suiteNoCerts, nil, nil, aeadChaCha20Poly1305},
172187
}
173188

174189
// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which
@@ -272,11 +287,12 @@ var cipherSuitesPreferenceOrder = []uint16{
272287
// AEADs w/ ECDHE
273288
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
274289
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
275-
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
290+
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
276291

277292
// CBC w/ ECDHE
278-
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
279-
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
293+
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
294+
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
295+
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
280296

281297
// AEADs w/o ECDHE
282298
TLS_RSA_WITH_AES_128_GCM_SHA256,
@@ -292,6 +308,7 @@ var cipherSuitesPreferenceOrder = []uint16{
292308

293309
// CBC_SHA256
294310
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
311+
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
295312
TLS_RSA_WITH_AES_128_CBC_SHA256,
296313

297314
// RC4
@@ -301,22 +318,27 @@ var cipherSuitesPreferenceOrder = []uint16{
301318

302319
var cipherSuitesPreferenceOrderNoAES = []uint16{
303320
// ChaCha20Poly1305
304-
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
321+
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
305322

306323
// AES-GCM w/ ECDHE
307324
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
308325
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
309326

310327
// The rest of cipherSuitesPreferenceOrder.
311-
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
312-
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
328+
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
329+
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
330+
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
331+
313332
TLS_RSA_WITH_AES_128_GCM_SHA256,
314333
TLS_RSA_WITH_AES_256_GCM_SHA384,
315334
TLS_RSA_WITH_AES_128_CBC_SHA,
316335
TLS_RSA_WITH_AES_256_CBC_SHA,
336+
317337
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
318338
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
339+
319340
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
341+
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
320342
TLS_RSA_WITH_AES_128_CBC_SHA256,
321343
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
322344
TLS_RSA_WITH_RC4_128_SHA,
@@ -327,6 +349,7 @@ var cipherSuitesPreferenceOrderNoAES = []uint16{
327349
var disabledCipherSuites = []uint16{
328350
// CBC_SHA256
329351
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
352+
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
330353
TLS_RSA_WITH_AES_128_CBC_SHA256,
331354

332355
// RC4
@@ -437,6 +460,11 @@ func macSHA256(key []byte) hash.Hash {
437460
return hmac.New(sha256.New, key)
438461
}
439462

463+
// macSHA384 returns a SHA-384 based MAC.
464+
func macSHA384(key []byte) hash.Hash {
465+
return hmac.New(sha512.New384, key)
466+
}
467+
440468
type aead interface {
441469
cipher.AEAD
442470

@@ -619,6 +647,12 @@ func ecdheRSAKA(version uint16) keyAgreement {
619647
}
620648
}
621649

650+
func ecdhePSKKA(version uint16) keyAgreement {
651+
return &ecdhePskKeyAgreement{
652+
version: version,
653+
}
654+
}
655+
622656
// mutualCipherSuite returns a cipherSuite given a list of supported
623657
// ciphersuites and the id requested by the peer.
624658
func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
@@ -683,8 +717,13 @@ const (
683717
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
684718
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
685719
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
720+
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xc035
721+
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xc036
722+
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xc037
723+
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xc038
686724
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8
687725
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
726+
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xccac
688727

689728
// TLS 1.3 cipher suites.
690729
TLS_AES_128_GCM_SHA256 uint16 = 0x1301

src/crypto/tls/common.go

+3
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,9 @@ type Config struct {
723723
// used for debugging.
724724
KeyLogWriter io.Writer
725725

726+
// Extra is used to hold extra configuration for external cipher-suites
727+
Extra interface{}
728+
726729
// mutex protects sessionTicketKeys and autoSessionTicketKeys.
727730
mutex sync.RWMutex
728731
// sessionTicketKeys contains zero or more ticket keys. If set, it means the

src/crypto/tls/handshake_server.go

+20-16
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,14 @@ func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
370370
if !hs.ecdheOk {
371371
return false
372372
}
373-
if c.flags&suiteECSign != 0 {
374-
if !hs.ecSignOk {
373+
if c.flags&suiteNoCerts == 0 {
374+
if c.flags&suiteECSign != 0 {
375+
if !hs.ecSignOk {
376+
return false
377+
}
378+
} else if !hs.rsaSignOk {
375379
return false
376380
}
377-
} else if !hs.rsaSignOk {
378-
return false
379381
}
380382
} else if !hs.rsaDecryptOk {
381383
return false
@@ -502,20 +504,22 @@ func (hs *serverHandshakeState) doFullHandshake() error {
502504
return err
503505
}
504506

505-
certMsg := new(certificateMsg)
506-
certMsg.certificates = hs.cert.Certificate
507-
hs.finishedHash.Write(certMsg.marshal())
508-
if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
509-
return err
510-
}
511-
512-
if hs.hello.ocspStapling {
513-
certStatus := new(certificateStatusMsg)
514-
certStatus.response = hs.cert.OCSPStaple
515-
hs.finishedHash.Write(certStatus.marshal())
516-
if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
507+
if hs.suite.flags&suiteNoCerts == 0 { // this suite requires certificate handshake
508+
certMsg := new(certificateMsg)
509+
certMsg.certificates = hs.cert.Certificate
510+
hs.finishedHash.Write(certMsg.marshal())
511+
if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
517512
return err
518513
}
514+
515+
if hs.hello.ocspStapling {
516+
certStatus := new(certificateStatusMsg)
517+
certStatus.response = hs.cert.OCSPStaple
518+
hs.finishedHash.Write(certStatus.marshal())
519+
if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
520+
return err
521+
}
522+
}
519523
}
520524

521525
keyAgreement := hs.suite.ka(c.vers)

src/crypto/tls/handshake_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,9 @@ func (zeroSource) Read(b []byte) (n int, err error) {
320320
func allCipherSuites() []uint16 {
321321
ids := make([]uint16, len(cipherSuites))
322322
for i, suite := range cipherSuites {
323-
ids[i] = suite.id
323+
if suite.flags&suiteNoCerts == 0 {
324+
ids[i] = suite.id
325+
}
324326
}
325327

326328
return ids

0 commit comments

Comments
 (0)